RequestTest.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901
  1. <?php
  2. /**
  3. * Unit tests for request class
  4. *
  5. * @group kohana
  6. * @group kohana.core
  7. * @group kohana.core.request
  8. *
  9. * @package Kohana
  10. * @category Tests
  11. * @author Kohana Team
  12. * @author BRMatt <matthew@sigswitch.com>
  13. * @copyright (c) Kohana Team
  14. * @license https://koseven.ga/LICENSE.md
  15. */
  16. class Kohana_RequestTest extends Unittest_TestCase
  17. {
  18. protected $_inital_request;
  19. // @codingStandardsIgnoreStart
  20. public function setUp()
  21. // @codingStandardsIgnoreEnd
  22. {
  23. parent::setUp();
  24. Kohana::$config->load('url')->set('trusted_hosts', ['localhost']);
  25. $this->_initial_request = Request::$initial;
  26. Request::$initial = new Request('/');
  27. }
  28. // @codingStandardsIgnoreStart
  29. public function tearDown()
  30. // @codingStandardsIgnoreEnd
  31. {
  32. Request::$initial = $this->_initial_request;
  33. parent::tearDown();
  34. }
  35. public function test_initial()
  36. {
  37. $this->setEnvironment([
  38. 'Request::$initial' => NULL,
  39. 'Request::$client_ip' => NULL,
  40. 'Request::$user_agent' => NULL,
  41. '_SERVER' => [
  42. 'HTTPS' => NULL,
  43. 'PATH_INFO' => '/',
  44. 'HTTP_REFERER' => 'http://example.com/',
  45. 'HTTP_USER_AGENT' => 'whatever (Mozilla 5.0/compatible)',
  46. 'REMOTE_ADDR' => '127.0.0.1',
  47. 'REQUEST_METHOD' => 'GET',
  48. 'HTTP_X_REQUESTED_WITH' => 'ajax-or-something',
  49. ],
  50. '_GET' => [],
  51. '_POST' => [],
  52. ]);
  53. $request = Request::factory();
  54. $this->assertEquals(Request::$initial, $request);
  55. $this->assertEquals(Request::$client_ip, '127.0.0.1');
  56. $this->assertEquals(Request::$user_agent, 'whatever (Mozilla 5.0/compatible)');
  57. $this->assertEquals($request->protocol(), 'HTTP/1.1');
  58. $this->assertEquals($request->referrer(), 'http://example.com/');
  59. $this->assertEquals($request->requested_with(), 'ajax-or-something');
  60. $this->assertEquals($request->query(), []);
  61. $this->assertEquals($request->post(), []);
  62. }
  63. /**
  64. * Tests client IP detection
  65. *
  66. * @return null
  67. */
  68. public function test_client_ips()
  69. {
  70. // testing X-Forwarded-For
  71. $server = [
  72. 'HTTPS' => NULL,
  73. 'PATH_INFO' => '/',
  74. 'REMOTE_ADDR' => '255.255.255.1',
  75. 'HTTP_X_FORWARDED_FOR' => '127.0.0.2, 255.255.255.1, 255.255.255.2',
  76. ];
  77. $this->setEnvironment([
  78. 'Request::$initial' => NULL,
  79. 'Request::$client_ip' => NULL,
  80. 'Request::$trusted_proxies' => ['255.255.255.1'],
  81. '_SERVER' => $server,
  82. ]);
  83. $request = Request::factory();
  84. $this->assertEquals(Request::$client_ip, '127.0.0.2', 'Header "HTTP_X_FORWARDED_FOR" handled incorrectly');
  85. // testing Client-IP
  86. $server['HTTP_CLIENT_IP'] = '127.0.0.3';
  87. unset($server['HTTP_X_FORWARDED_FOR']);
  88. $this->setEnvironment([
  89. 'Request::$initial' => NULL,
  90. 'Request::$client_ip' => NULL,
  91. '_SERVER' => $server,
  92. ]);
  93. $request = Request::factory();
  94. $this->assertEquals(Request::$client_ip, '127.0.0.3', 'Header "HTTP_CLIENT_IP" handled incorrectly');
  95. // testing Cloudflare
  96. $server['HTTP_CF_CONNECTING_IP'] = '127.0.0.4';
  97. $this->setEnvironment([
  98. 'Request::$initial' => NULL,
  99. 'Request::$client_ip' => NULL,
  100. '_SERVER' => $server,
  101. ]);
  102. $request = Request::factory();
  103. $this->assertEquals(Request::$client_ip, '127.0.0.4', 'Cloudflare header "HTTP_CF_CONNECTING_IP" handled incorrectly');
  104. }
  105. /**
  106. * Tests that the allow_external flag prevents an external request.
  107. *
  108. * @return null
  109. */
  110. public function test_disable_external_tests()
  111. {
  112. $this->setEnvironment(
  113. [
  114. 'Request::$initial' => NULL,
  115. ]
  116. );
  117. $request = new Request('http://www.google.com/', [], FALSE);
  118. $this->assertEquals(FALSE, $request->is_external());
  119. }
  120. /**
  121. * Provides the data for test_create()
  122. * @return array
  123. */
  124. public function provider_create()
  125. {
  126. return [
  127. ['foo/bar', 'Request_Client_Internal'],
  128. ['http://google.com', 'Request_Client_External'],
  129. ];
  130. }
  131. /**
  132. * Ensures the create class is created with the correct client
  133. *
  134. * @test
  135. * @dataProvider provider_create
  136. */
  137. public function test_create($uri, $client_class)
  138. {
  139. $request = Request::factory($uri);
  140. $this->assertInstanceOf($client_class, $request->client());
  141. }
  142. /**
  143. * Ensure that parameters can be read
  144. *
  145. * @test
  146. */
  147. public function test_param()
  148. {
  149. $route = new Route('(<controller>(/<action>(/<id>)))');
  150. $uri = 'kohana_requesttest_dummy/foobar/some_id';
  151. $request = Request::factory($uri, NULL, TRUE, [$route]);
  152. // We need to execute the request before it has matched a route
  153. $response = $request->execute();
  154. $controller = new Controller_Kohana_RequestTest_Dummy($request, $response);
  155. $this->assertSame(200, $response->status());
  156. $this->assertSame($controller->get_expected_response(), $response->body());
  157. $this->assertArrayHasKey('id', $request->param());
  158. $this->assertArrayNotHasKey('foo', $request->param());
  159. $this->assertEquals($request->uri(), $uri);
  160. // Ensure the params do not contain contamination from controller, action, route, uri etc etc
  161. $params = $request->param();
  162. // Test for illegal components
  163. $this->assertArrayNotHasKey('controller', $params);
  164. $this->assertArrayNotHasKey('action', $params);
  165. $this->assertArrayNotHasKey('directory', $params);
  166. $this->assertArrayNotHasKey('uri', $params);
  167. $this->assertArrayNotHasKey('route', $params);
  168. $route = new Route('(<uri>)', ['uri' => '.+']);
  169. $route->defaults(['controller' => 'kohana_requesttest_dummy', 'action' => 'foobar']);
  170. $request = Request::factory('kohana_requesttest_dummy', NULL, TRUE, [$route]);
  171. // We need to execute the request before it has matched a route
  172. $response = $request->execute();
  173. $controller = new Controller_Kohana_RequestTest_Dummy($request, $response);
  174. $this->assertSame(200, $response->status());
  175. $this->assertSame($controller->get_expected_response(), $response->body());
  176. $this->assertSame('kohana_requesttest_dummy', $request->param('uri'));
  177. }
  178. /**
  179. * Tests Request::method()
  180. *
  181. * @test
  182. */
  183. public function test_method()
  184. {
  185. $request = Request::factory('foo/bar');
  186. $this->assertEquals($request->method(), 'GET');
  187. $this->assertEquals(($request->method('post') === $request), TRUE);
  188. $this->assertEquals(($request->method() === 'POST'), TRUE);
  189. }
  190. /**
  191. * Tests Request::route()
  192. *
  193. * @test
  194. */
  195. public function test_route()
  196. {
  197. $request = Request::factory(''); // This should always match something, no matter what changes people make
  198. // We need to execute the request before it has matched a route
  199. try
  200. {
  201. $request->execute();
  202. }
  203. catch (Exception $e) {}
  204. $this->assertInstanceOf('Route', $request->route());
  205. }
  206. /**
  207. * Tests Request::route()
  208. *
  209. * @test
  210. */
  211. public function test_route_is_not_set_before_execute()
  212. {
  213. $request = Request::factory(''); // This should always match something, no matter what changes people make
  214. // The route should be NULL since the request has not been executed yet
  215. $this->assertEquals($request->route(), NULL);
  216. }
  217. /**
  218. * Tests Request::accept_type()
  219. *
  220. * @test
  221. * @covers Request::accept_type
  222. */
  223. public function test_accept_type()
  224. {
  225. $this->assertEquals(['*/*' => 1], Request::accept_type());
  226. }
  227. /**
  228. * Provides test data for Request::accept_lang()
  229. * @return array
  230. */
  231. public function provider_accept_lang()
  232. {
  233. return [
  234. ['en-us', 1, ['_SERVER' => ['HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5']]],
  235. ['en-us', 1, ['_SERVER' => ['HTTP_ACCEPT_LANGUAGE' => 'en-gb']]],
  236. ['en-us', 1, ['_SERVER' => ['HTTP_ACCEPT_LANGUAGE' => 'sp-sp;q=0.5']]]
  237. ];
  238. }
  239. /**
  240. * Tests Request::accept_lang()
  241. *
  242. * @test
  243. * @covers Request::accept_lang
  244. * @dataProvider provider_accept_lang
  245. * @param array $params Query string
  246. * @param string $expected Expected result
  247. * @param array $enviroment Set environment
  248. */
  249. public function test_accept_lang($params, $expected, $enviroment)
  250. {
  251. $this->setEnvironment($enviroment);
  252. $this->assertEquals(
  253. $expected,
  254. Request::accept_lang($params)
  255. );
  256. }
  257. /**
  258. * Provides test data for Request::url()
  259. * @return array
  260. */
  261. public function provider_url()
  262. {
  263. return [
  264. [
  265. 'foo/bar',
  266. 'http',
  267. 'http://localhost/kohana/foo/bar'
  268. ],
  269. [
  270. 'foo',
  271. 'http',
  272. 'http://localhost/kohana/foo'
  273. ],
  274. [
  275. 'http://www.google.com',
  276. 'http',
  277. 'http://www.google.com'
  278. ],
  279. [
  280. '0',
  281. 'http',
  282. 'http://localhost/kohana/0'
  283. ]
  284. ];
  285. }
  286. /**
  287. * Tests Request::url()
  288. *
  289. * @test
  290. * @dataProvider provider_url
  291. * @covers Request::url
  292. * @param string $uri the uri to use
  293. * @param string $protocol the protocol to use
  294. * @param array $expected The string we expect
  295. */
  296. public function test_url($uri, $protocol, $expected)
  297. {
  298. if ( ! isset($_SERVER['argc']))
  299. {
  300. $_SERVER['argc'] = 1;
  301. }
  302. $this->setEnvironment([
  303. 'Kohana::$base_url' => '/kohana/',
  304. '_SERVER' => ['HTTP_HOST' => 'localhost', 'argc' => $_SERVER['argc']],
  305. 'Kohana::$index_file' => FALSE,
  306. ]);
  307. // issue #3967: inject the route so that we don't conflict with the application's default route
  308. $route = new Route('(<controller>(/<action>))');
  309. $route->defaults([
  310. 'controller' => 'welcome',
  311. 'action' => 'index',
  312. ]);
  313. $this->assertEquals(Request::factory($uri, [], TRUE, [$route])->url($protocol), $expected);
  314. }
  315. /**
  316. * Data provider for test_set_protocol() test
  317. *
  318. * @return array
  319. */
  320. public function provider_set_protocol()
  321. {
  322. return [
  323. [
  324. 'http/1.1',
  325. 'HTTP/1.1',
  326. ],
  327. [
  328. 'ftp',
  329. 'FTP',
  330. ],
  331. [
  332. 'hTTp/1.0',
  333. 'HTTP/1.0',
  334. ],
  335. ];
  336. }
  337. /**
  338. * Tests the protocol() method
  339. *
  340. * @dataProvider provider_set_protocol
  341. *
  342. * @return null
  343. */
  344. public function test_set_protocol($protocol, $expected)
  345. {
  346. $request = Request::factory();
  347. // Set the supplied protocol
  348. $result = $request->protocol($protocol);
  349. // Test the set value
  350. $this->assertSame($expected, $request->protocol());
  351. // Test the return value
  352. $this->assertTrue($request instanceof $result);
  353. }
  354. /**
  355. * Provides data for test_post_max_size_exceeded()
  356. *
  357. * @return array
  358. */
  359. public function provider_post_max_size_exceeded()
  360. {
  361. // Get the post max size
  362. $post_max_size = Num::bytes(ini_get('post_max_size'));
  363. return [
  364. [
  365. $post_max_size+200000,
  366. TRUE
  367. ],
  368. [
  369. $post_max_size-20,
  370. FALSE
  371. ],
  372. [
  373. $post_max_size,
  374. FALSE
  375. ]
  376. ];
  377. }
  378. /**
  379. * Tests the post_max_size_exceeded() method
  380. *
  381. * @dataProvider provider_post_max_size_exceeded
  382. *
  383. * @param int content_length
  384. * @param bool expected
  385. * @return void
  386. */
  387. public function test_post_max_size_exceeded($content_length, $expected)
  388. {
  389. // Ensure the request method is set to POST
  390. Request::$initial->method(HTTP_Request::POST);
  391. // Set the content length
  392. $_SERVER['CONTENT_LENGTH'] = $content_length;
  393. // Test the post_max_size_exceeded() method
  394. $this->assertSame(Request::post_max_size_exceeded(), $expected);
  395. }
  396. /**
  397. * Provides data for test_uri_only_trimed_on_internal()
  398. *
  399. * @return array
  400. */
  401. public function provider_uri_only_trimed_on_internal()
  402. {
  403. // issue #3967: inject the route so that we don't conflict with the application's default route
  404. $route = new Route('(<controller>(/<action>))');
  405. $route->defaults([
  406. 'controller' => 'welcome',
  407. 'action' => 'index',
  408. ]);
  409. $old_request = Request::$initial;
  410. Request::$initial = new Request(TRUE, [], TRUE, [$route]);
  411. $result = [
  412. [
  413. new Request('http://www.google.com'),
  414. 'http://www.google.com'
  415. ],
  416. [
  417. new Request('http://www.google.com/'),
  418. 'http://www.google.com/'
  419. ],
  420. [
  421. new Request('foo/bar/'),
  422. 'foo/bar'
  423. ],
  424. [
  425. new Request('foo/bar'),
  426. 'foo/bar'
  427. ],
  428. [
  429. new Request('/0'),
  430. '0'
  431. ],
  432. [
  433. new Request('0'),
  434. '0'
  435. ],
  436. [
  437. new Request('/'),
  438. '/'
  439. ],
  440. [
  441. new Request(''),
  442. '/'
  443. ]
  444. ];
  445. Request::$initial = $old_request;
  446. return $result;
  447. }
  448. /**
  449. * Tests that the uri supplied to Request is only trimed
  450. * for internal requests.
  451. *
  452. * @dataProvider provider_uri_only_trimed_on_internal
  453. *
  454. * @return void
  455. */
  456. public function test_uri_only_trimed_on_internal(Request $request, $expected)
  457. {
  458. $this->assertSame($request->uri(), $expected);
  459. }
  460. /**
  461. * Data provider for test_options_set_to_external_client()
  462. *
  463. * @return array
  464. */
  465. public function provider_options_set_to_external_client()
  466. {
  467. $provider = [
  468. [
  469. [
  470. CURLOPT_PROXYPORT => 8080,
  471. CURLOPT_PROXYTYPE => CURLPROXY_HTTP,
  472. CURLOPT_VERBOSE => TRUE
  473. ],
  474. [
  475. CURLOPT_PROXYPORT => 8080,
  476. CURLOPT_PROXYTYPE => CURLPROXY_HTTP,
  477. CURLOPT_VERBOSE => TRUE
  478. ]
  479. ]
  480. ];
  481. return $provider;
  482. }
  483. /**
  484. * Test for Request_Client_External::options() to ensure options
  485. * can be set to the external client (for cURL and PECL_HTTP)
  486. *
  487. * @dataProvider provider_options_set_to_external_client
  488. *
  489. * @param array settings
  490. * @param array expected
  491. * @return void
  492. */
  493. public function test_options_set_to_external_client($settings, $expected)
  494. {
  495. $request_client = Request_Client_External::factory([], 'Request_Client_Curl');
  496. // Test for empty array
  497. $this->assertSame([], $request_client->options());
  498. // Test that set works as expected
  499. $this->assertSame($request_client->options($settings), $request_client);
  500. // Test that each setting is present and returned
  501. foreach ($expected as $key => $value)
  502. {
  503. $this->assertSame($request_client->options($key), $value);
  504. }
  505. }
  506. /**
  507. * Provides data for test_headers_get()
  508. *
  509. * @return array
  510. */
  511. public function provider_headers_get()
  512. {
  513. $x_powered_by = 'Kohana Unit Test';
  514. $content_type = 'application/x-www-form-urlencoded';
  515. $request = new Request('foo/bar', [], TRUE, []);
  516. return [
  517. [
  518. $request->headers([
  519. 'x-powered-by' => $x_powered_by,
  520. 'content-type' => $content_type
  521. ]
  522. ),
  523. [
  524. 'x-powered-by' => $x_powered_by,
  525. 'content-type' => $content_type
  526. ]
  527. ]
  528. ];
  529. }
  530. /**
  531. * Tests getting headers from the Request object
  532. *
  533. * @dataProvider provider_headers_get
  534. *
  535. * @param Request request to test
  536. * @param array headers to test against
  537. * @return void
  538. */
  539. public function test_headers_get($request, $headers)
  540. {
  541. foreach ($headers as $key => $expected_value)
  542. {
  543. $this->assertSame( (string) $request->headers($key), $expected_value);
  544. }
  545. }
  546. /**
  547. * Provides data for test_headers_set
  548. *
  549. * @return array
  550. */
  551. public function provider_headers_set()
  552. {
  553. return [
  554. [
  555. [
  556. 'content-type' => 'application/x-www-form-urlencoded',
  557. 'x-test-header' => 'foo'
  558. ],
  559. "Content-Type: application/x-www-form-urlencoded\r\nX-Test-Header: foo\r\n\r\n"
  560. ],
  561. [
  562. [
  563. 'content-type' => 'application/json',
  564. 'x-powered-by' => 'kohana'
  565. ],
  566. "Content-Type: application/json\r\nX-Powered-By: kohana\r\n\r\n"
  567. ]
  568. ];
  569. }
  570. /**
  571. * Tests the setting of headers to the request object
  572. *
  573. * @dataProvider provider_headers_set
  574. *
  575. * @param array header(s) to set to the request object
  576. * @param string expected http header
  577. * @return void
  578. */
  579. public function test_headers_set($headers, $expected)
  580. {
  581. $request = new Request(TRUE, [], TRUE, []);
  582. $request->headers($headers);
  583. $this->assertSame($expected, (string) $request->headers());
  584. }
  585. /**
  586. * Provides test data for test_query_parameter_parsing()
  587. *
  588. * @return array
  589. */
  590. public function provider_query_parameter_parsing()
  591. {
  592. return [
  593. [
  594. 'foo/bar',
  595. [
  596. 'foo' => 'bar',
  597. 'sna' => 'fu'
  598. ],
  599. [
  600. 'foo' => 'bar',
  601. 'sna' => 'fu'
  602. ],
  603. ],
  604. [
  605. 'foo/bar?john=wayne&peggy=sue',
  606. [
  607. 'foo' => 'bar',
  608. 'sna' => 'fu'
  609. ],
  610. [
  611. 'john' => 'wayne',
  612. 'peggy' => 'sue',
  613. 'foo' => 'bar',
  614. 'sna' => 'fu'
  615. ],
  616. ],
  617. [
  618. 'http://host.tld/foo/bar?john=wayne&peggy=sue',
  619. [
  620. 'foo' => 'bar',
  621. 'sna' => 'fu'
  622. ],
  623. [
  624. 'john' => 'wayne',
  625. 'peggy' => 'sue',
  626. 'foo' => 'bar',
  627. 'sna' => 'fu'
  628. ],
  629. ],
  630. ];
  631. }
  632. /**
  633. * Tests that query parameters are parsed correctly
  634. *
  635. * @dataProvider provider_query_parameter_parsing
  636. *
  637. * @param string url
  638. * @param array query
  639. * @param array expected
  640. * @return void
  641. */
  642. public function test_query_parameter_parsing($url, $query, $expected)
  643. {
  644. Request::$initial = NULL;
  645. $request = new Request($url);
  646. foreach ($query as $key => $value)
  647. {
  648. $request->query($key, $value);
  649. }
  650. $this->assertSame($expected, $request->query());
  651. }
  652. /**
  653. * Tests that query parameters are parsed correctly
  654. *
  655. * @dataProvider provider_query_parameter_parsing
  656. *
  657. * @param string url
  658. * @param array query
  659. * @param array expected
  660. * @return void
  661. */
  662. public function test_query_parameter_parsing_in_subrequest($url, $query, $expected)
  663. {
  664. Request::$initial = new Request(TRUE);
  665. $request = new Request($url);
  666. foreach ($query as $key => $value)
  667. {
  668. $request->query($key, $value);
  669. }
  670. $this->assertSame($expected, $request->query());
  671. }
  672. /**
  673. * Provides data for test_client
  674. *
  675. * @return array
  676. */
  677. public function provider_client()
  678. {
  679. $internal_client = new Request_Client_Internal;
  680. $external_client = new Request_Client_Stream;
  681. return [
  682. [
  683. new Request('http://kohanaframework.org'),
  684. $internal_client,
  685. $internal_client
  686. ],
  687. [
  688. new Request('foo/bar'),
  689. $external_client,
  690. $external_client
  691. ]
  692. ];
  693. }
  694. /**
  695. * Tests the getter/setter for request client
  696. *
  697. * @dataProvider provider_client
  698. *
  699. * @param Request $request
  700. * @param Request_Client $client
  701. * @param Request_Client $expected
  702. * @return void
  703. */
  704. public function test_client(Request $request, Request_Client $client, Request_Client $expected)
  705. {
  706. $request->client($client);
  707. $this->assertSame($expected, $request->client());
  708. }
  709. /**
  710. * Tests that the Request constructor passes client params on to the
  711. * Request_Client once created.
  712. */
  713. public function test_passes_client_params()
  714. {
  715. $request = Request::factory('http://example.com/', [
  716. 'follow' => TRUE,
  717. 'strict_redirect' => FALSE
  718. ]);
  719. $client = $request->client();
  720. $this->assertEquals($client->follow(), TRUE);
  721. $this->assertEquals($client->strict_redirect(), FALSE);
  722. }
  723. /**
  724. * Tests correctness request content-length header after calling render
  725. */
  726. public function test_content_length_after_render()
  727. {
  728. $request = Request::factory('https://example.org/post')
  729. ->client(new Kohana_RequestTest_Header_Spying_Request_Client_External)
  730. ->method(Request::POST)
  731. ->post(['aaa' => 'bbb']);
  732. $request->render();
  733. $request->execute();
  734. $headers = $request->client()->get_received_request_headers();
  735. $this->assertEquals(strlen($request->body()), $headers['content-length']);
  736. }
  737. /**
  738. * Tests correctness request content-length header after calling render
  739. * and changing post
  740. */
  741. public function test_content_length_after_changing_post()
  742. {
  743. $request = Request::factory('https://example.org/post')
  744. ->client(new Kohana_RequestTest_Header_Spying_Request_Client_External)
  745. ->method(Request::POST)
  746. ->post(['aaa' => 'bbb']);
  747. $request->render();
  748. $request->post(['one' => 'one', 'two' => 'two', 'three' => 'three']);
  749. $request->execute();
  750. $headers = $request->client()->get_received_request_headers();
  751. $this->assertEquals(strlen($request->body()), $headers['content-length']);
  752. }
  753. } // End Kohana_RequestTest
  754. /**
  755. * A dummy Request_Client_External implementation, that spies on the headers
  756. * of the request
  757. */
  758. class Kohana_RequestTest_Header_Spying_Request_Client_External extends Request_Client_External
  759. {
  760. private $headers;
  761. protected function _send_message(\Request $request, \Response $response)
  762. {
  763. $this->headers = $request->headers();
  764. return $response;
  765. }
  766. public function get_received_request_headers()
  767. {
  768. return $this->headers;
  769. }
  770. }
  771. class Controller_Kohana_RequestTest_Dummy extends Controller
  772. {
  773. // hard coded dummy response
  774. protected $dummy_response = "this is a dummy response";
  775. public function action_foobar()
  776. {
  777. $this->response->body($this->dummy_response);
  778. }
  779. public function get_expected_response()
  780. {
  781. return $this->dummy_response;
  782. }
  783. } // End Kohana_RequestTest