CurlTest.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * Redistributions of files must retain the above copyright notice.
  8. *
  9. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  10. * @link https://cakephp.org CakePHP(tm) Project
  11. * @since 3.7.0
  12. * @license https://opensource.org/licenses/mit-license.php MIT License
  13. */
  14. namespace Cake\Test\TestCase\Http\Client\Adapter;
  15. use Cake\Http\Client\Adapter\Curl;
  16. use Cake\Http\Client\Request;
  17. use Cake\Http\Client\Response;
  18. use Cake\TestSuite\TestCase;
  19. /**
  20. * HTTP curl adapter test.
  21. */
  22. class CurlTest extends TestCase
  23. {
  24. public function setUp()
  25. {
  26. parent::setUp();
  27. $this->skipIf(!function_exists('curl_init'), 'Skipping as ext/curl is not installed.');
  28. $this->curl = new Curl();
  29. $this->caFile = CORE_PATH . 'config' . DIRECTORY_SEPARATOR . 'cacert.pem';
  30. }
  31. /**
  32. * Test the send method
  33. *
  34. * @return void
  35. */
  36. public function testSendLive()
  37. {
  38. $request = new Request('http://localhost', 'GET', [
  39. 'User-Agent' => 'CakePHP TestSuite',
  40. 'Cookie' => 'testing=value',
  41. ]);
  42. try {
  43. $responses = $this->curl->send($request, []);
  44. } catch (\Cake\Core\Exception\Exception $e) {
  45. $this->markTestSkipped('Could not connect to localhost, skipping');
  46. }
  47. $this->assertCount(1, $responses);
  48. $response = $responses[0];
  49. $this->assertInstanceOf(Response::class, $response);
  50. $this->assertNotEmpty($response->getHeaders());
  51. $this->assertNotEmpty($response->getBody()->getContents());
  52. }
  53. /**
  54. * Test the send method
  55. *
  56. * @return void
  57. */
  58. public function testSendLiveResponseCheck()
  59. {
  60. $request = new Request('https://api.cakephp.org/3.0/', 'GET', [
  61. 'User-Agent' => 'CakePHP TestSuite',
  62. ]);
  63. try {
  64. $responses = $this->curl->send($request, []);
  65. } catch (\Cake\Core\Exception\Exception $e) {
  66. $this->markTestSkipped('Could not connect to book.cakephp.org, skipping');
  67. }
  68. $this->assertCount(1, $responses);
  69. $response = $responses[0];
  70. $this->assertInstanceOf(Response::class, $response);
  71. $this->assertTrue($response->hasHeader('Date'));
  72. $this->assertTrue($response->hasHeader('Content-type'));
  73. $this->assertContains('<html', $response->getBody()->getContents());
  74. }
  75. /**
  76. * Test converting client options into curl ones.
  77. *
  78. * @return void
  79. */
  80. public function testBuildOptionsGet()
  81. {
  82. $options = [
  83. 'timeout' => 5,
  84. ];
  85. $request = new Request(
  86. 'http://localhost/things',
  87. 'GET',
  88. ['Cookie' => 'testing=value']
  89. );
  90. $result = $this->curl->buildOptions($request, $options);
  91. $expected = [
  92. CURLOPT_URL => 'http://localhost/things',
  93. CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  94. CURLOPT_RETURNTRANSFER => true,
  95. CURLOPT_HEADER => true,
  96. CURLOPT_HTTPHEADER => [
  97. 'Cookie: testing=value',
  98. 'Connection: close',
  99. 'User-Agent: CakePHP',
  100. ],
  101. CURLOPT_HTTPGET => true,
  102. CURLOPT_TIMEOUT => 5,
  103. CURLOPT_CAINFO => $this->caFile,
  104. ];
  105. $this->assertSame($expected, $result);
  106. }
  107. /**
  108. * Test converting client options into curl ones.
  109. *
  110. * @return void
  111. */
  112. public function testBuildOptionsPost()
  113. {
  114. $options = [];
  115. $request = new Request(
  116. 'http://localhost/things',
  117. 'POST',
  118. ['Cookie' => 'testing=value'],
  119. ['name' => 'cakephp', 'yes' => 1]
  120. );
  121. $result = $this->curl->buildOptions($request, $options);
  122. $expected = [
  123. CURLOPT_URL => 'http://localhost/things',
  124. CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  125. CURLOPT_RETURNTRANSFER => true,
  126. CURLOPT_HEADER => true,
  127. CURLOPT_HTTPHEADER => [
  128. 'Cookie: testing=value',
  129. 'Connection: close',
  130. 'User-Agent: CakePHP',
  131. 'Content-Type: application/x-www-form-urlencoded',
  132. ],
  133. CURLOPT_POST => true,
  134. CURLOPT_POSTFIELDS => 'name=cakephp&yes=1',
  135. CURLOPT_CAINFO => $this->caFile,
  136. ];
  137. $this->assertSame($expected, $result);
  138. }
  139. /**
  140. * Test converting client options into curl ones.
  141. *
  142. * @return void
  143. */
  144. public function testBuildOptionsPut()
  145. {
  146. $options = [];
  147. $request = new Request(
  148. 'http://localhost/things',
  149. 'PUT',
  150. ['Cookie' => 'testing=value']
  151. );
  152. $result = $this->curl->buildOptions($request, $options);
  153. $expected = [
  154. CURLOPT_URL => 'http://localhost/things',
  155. CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  156. CURLOPT_RETURNTRANSFER => true,
  157. CURLOPT_HEADER => true,
  158. CURLOPT_HTTPHEADER => [
  159. 'Cookie: testing=value',
  160. 'Connection: close',
  161. 'User-Agent: CakePHP',
  162. ],
  163. CURLOPT_POST => true,
  164. CURLOPT_CUSTOMREQUEST => 'PUT',
  165. CURLOPT_CAINFO => $this->caFile,
  166. ];
  167. $this->assertSame($expected, $result);
  168. }
  169. /**
  170. * Test converting client options into curl ones.
  171. *
  172. * @return void
  173. */
  174. public function testBuildOptionsJsonPost()
  175. {
  176. $options = [];
  177. $content = json_encode(['a' => 1, 'b' => 2]);
  178. $request = new Request(
  179. 'http://localhost/things',
  180. 'POST',
  181. ['Content-type' => 'application/json'],
  182. $content
  183. );
  184. $result = $this->curl->buildOptions($request, $options);
  185. $expected = [
  186. CURLOPT_URL => 'http://localhost/things',
  187. CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  188. CURLOPT_RETURNTRANSFER => true,
  189. CURLOPT_HEADER => true,
  190. CURLOPT_HTTPHEADER => [
  191. 'Content-type: application/json',
  192. 'Connection: close',
  193. 'User-Agent: CakePHP',
  194. ],
  195. CURLOPT_POST => true,
  196. CURLOPT_POSTFIELDS => $content,
  197. CURLOPT_CAINFO => $this->caFile,
  198. ];
  199. $this->assertSame($expected, $result);
  200. }
  201. /**
  202. * Test converting client options into curl ones.
  203. *
  204. * @return void
  205. */
  206. public function testBuildOptionsSsl()
  207. {
  208. $options = [
  209. 'ssl_verify_host' => true,
  210. 'ssl_verify_peer' => true,
  211. 'ssl_verify_peer_name' => true,
  212. // These options do nothing in curl.
  213. 'ssl_verify_depth' => 9000,
  214. 'ssl_allow_self_signed' => false,
  215. ];
  216. $request = new Request('http://localhost/things', 'GET');
  217. $result = $this->curl->buildOptions($request, $options);
  218. $expected = [
  219. CURLOPT_URL => 'http://localhost/things',
  220. CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  221. CURLOPT_RETURNTRANSFER => true,
  222. CURLOPT_HEADER => true,
  223. CURLOPT_HTTPHEADER => [
  224. 'Connection: close',
  225. 'User-Agent: CakePHP',
  226. ],
  227. CURLOPT_HTTPGET => true,
  228. CURLOPT_SSL_VERIFYPEER => true,
  229. CURLOPT_SSL_VERIFYHOST => 2,
  230. CURLOPT_CAINFO => $this->caFile,
  231. ];
  232. $this->assertSame($expected, $result);
  233. }
  234. /**
  235. * Test converting client options into curl ones.
  236. *
  237. * @return void
  238. */
  239. public function testBuildOptionsProxy()
  240. {
  241. $options = [
  242. 'proxy' => [
  243. 'proxy' => '127.0.0.1:8080',
  244. 'username' => 'frodo',
  245. 'password' => 'one_ring',
  246. ],
  247. ];
  248. $request = new Request('http://localhost/things', 'GET');
  249. $result = $this->curl->buildOptions($request, $options);
  250. $expected = [
  251. CURLOPT_URL => 'http://localhost/things',
  252. CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  253. CURLOPT_RETURNTRANSFER => true,
  254. CURLOPT_HEADER => true,
  255. CURLOPT_HTTPHEADER => [
  256. 'Connection: close',
  257. 'User-Agent: CakePHP',
  258. ],
  259. CURLOPT_HTTPGET => true,
  260. CURLOPT_CAINFO => $this->caFile,
  261. CURLOPT_PROXY => '127.0.0.1:8080',
  262. CURLOPT_PROXYUSERPWD => 'frodo:one_ring',
  263. ];
  264. $this->assertSame($expected, $result);
  265. }
  266. /**
  267. * Test converting client options into curl ones.
  268. *
  269. * @return void
  270. */
  271. public function testBuildOptionsCurlOptions()
  272. {
  273. $options = [
  274. 'curl' => [
  275. CURLOPT_USERAGENT => 'Super-secret',
  276. ],
  277. ];
  278. $request = new Request('http://localhost/things', 'GET');
  279. $request = $request->withProtocolVersion('1.0');
  280. $result = $this->curl->buildOptions($request, $options);
  281. $expected = [
  282. CURLOPT_URL => 'http://localhost/things',
  283. CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_0,
  284. CURLOPT_RETURNTRANSFER => true,
  285. CURLOPT_HEADER => true,
  286. CURLOPT_HTTPHEADER => [
  287. 'Connection: close',
  288. 'User-Agent: CakePHP',
  289. ],
  290. CURLOPT_HTTPGET => true,
  291. CURLOPT_CAINFO => $this->caFile,
  292. CURLOPT_USERAGENT => 'Super-secret',
  293. ];
  294. $this->assertSame($expected, $result);
  295. }
  296. /**
  297. * Test converting client options into curl ones.
  298. *
  299. * @return void
  300. */
  301. public function testBuildOptionsProtocolVersion()
  302. {
  303. $this->skipIf(!defined('CURL_HTTP_VERSION_2TLS'), 'Requires libcurl 7.42');
  304. $options = [];
  305. $request = new Request('http://localhost/things', 'GET');
  306. $request = $request->withProtocolVersion('2');
  307. $result = $this->curl->buildOptions($request, $options);
  308. $this->assertSame(CURL_HTTP_VERSION_2TLS, $result[CURLOPT_HTTP_VERSION]);
  309. }
  310. }