RequestTest.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Tests\Component\HttpFoundation;
  11. use Symfony\Component\HttpFoundation\Request;
  12. use Symfony\Component\HttpFoundation\File\UploadedFile;
  13. class RequestTest extends \PHPUnit_Framework_TestCase
  14. {
  15. /**
  16. * @covers Symfony\Component\HttpFoundation\Request::__construct
  17. */
  18. public function testConstructor()
  19. {
  20. $this->testInitialize();
  21. }
  22. /**
  23. * @covers Symfony\Component\HttpFoundation\Request::initialize
  24. */
  25. public function testInitialize()
  26. {
  27. $request = new Request();
  28. $request->initialize(array('foo' => 'bar'));
  29. $this->assertEquals('bar', $request->query->get('foo'), '->initialize() takes an array of query parameters as its first argument');
  30. $request->initialize(array(), array('foo' => 'bar'));
  31. $this->assertEquals('bar', $request->request->get('foo'), '->initialize() takes an array of request parameters as its second argument');
  32. $request->initialize(array(), array(), array('foo' => 'bar'));
  33. $this->assertEquals('bar', $request->attributes->get('foo'), '->initialize() takes an array of attributes as its thrid argument');
  34. $request->initialize(array(), array(), array(), array(), array(), array('HTTP_FOO' => 'bar'));
  35. $this->assertEquals('bar', $request->headers->get('FOO'), '->initialize() takes an array of HTTP headers as its fourth argument');
  36. }
  37. /**
  38. * @covers Symfony\Component\HttpFoundation\Request::create
  39. */
  40. public function testCreate()
  41. {
  42. $request = Request::create('http://test.com/foo?bar=baz');
  43. $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
  44. $this->assertEquals('/foo', $request->getPathInfo());
  45. $this->assertEquals('bar=baz', $request->getQueryString());
  46. $this->assertEquals(80, $request->getPort());
  47. $request = Request::create('https://test.com/foo?bar=baz');
  48. $this->assertEquals('https://test.com/foo?bar=baz', $request->getUri());
  49. $this->assertEquals('/foo', $request->getPathInfo());
  50. $this->assertEquals('bar=baz', $request->getQueryString());
  51. $this->assertEquals(443, $request->getPort());
  52. $request = Request::create('test.com:90/foo');
  53. $this->assertEquals('http://test.com:90/foo', $request->getUri());
  54. $this->assertEquals('/foo', $request->getPathInfo());
  55. $this->assertEquals('test.com', $request->getHost());
  56. $this->assertEquals(90, $request->getPort());
  57. $request = Request::create('https://test.com:90/foo');
  58. $this->assertEquals('https://test.com:90/foo', $request->getUri());
  59. $this->assertEquals('/foo', $request->getPathInfo());
  60. $this->assertEquals('test.com', $request->getHost());
  61. $this->assertEquals(90, $request->getPort());
  62. $json = '{"jsonrpc":"2.0","method":"echo","id":7,"params":["Hello World"]}';
  63. $request = Request::create('http://example.com/jsonrpc', 'POST', array(), array(), array(), array(), $json);
  64. $this->assertEquals($json, $request->getContent());
  65. }
  66. /**
  67. * @covers Symfony\Component\HttpFoundation\Request::duplicate
  68. */
  69. public function testDuplicate()
  70. {
  71. $request = new Request(array('foo' => 'bar'), array('foo' => 'bar'), array('foo' => 'bar'), array(), array(), array('HTTP_FOO' => 'bar'));
  72. $dup = $request->duplicate();
  73. $this->assertEquals($request->query->all(), $dup->query->all(), '->duplicate() duplicates a request an copy the current query parameters');
  74. $this->assertEquals($request->request->all(), $dup->request->all(), '->duplicate() duplicates a request an copy the current request parameters');
  75. $this->assertEquals($request->attributes->all(), $dup->attributes->all(), '->duplicate() duplicates a request an copy the current attributes');
  76. $this->assertEquals($request->headers->all(), $dup->headers->all(), '->duplicate() duplicates a request an copy the current HTTP headers');
  77. $dup = $request->duplicate(array('foo' => 'foobar'), array('foo' => 'foobar'), array('foo' => 'foobar'), array(), array(), array('HTTP_FOO' => 'foobar'));
  78. $this->assertEquals(array('foo' => 'foobar'), $dup->query->all(), '->duplicate() overrides the query parameters if provided');
  79. $this->assertEquals(array('foo' => 'foobar'), $dup->request->all(), '->duplicate() overrides the request parameters if provided');
  80. $this->assertEquals(array('foo' => 'foobar'), $dup->attributes->all(), '->duplicate() overrides the attributes if provided');
  81. $this->assertEquals(array('foo' => array('foobar')), $dup->headers->all(), '->duplicate() overrides the HTTP header if provided');
  82. }
  83. /**
  84. * @covers Symfony\Component\HttpFoundation\Request::getFormat
  85. * @dataProvider getFormatToMimeTypeMapProvider
  86. */
  87. public function testGetFormatFromMimeType($format, $mimeTypes)
  88. {
  89. $request = new Request();
  90. foreach ($mimeTypes as $mime) {
  91. $this->assertEquals($format, $request->getFormat($mime));
  92. }
  93. }
  94. /**
  95. * @covers Symfony\Component\HttpFoundation\Request::getMimeType
  96. * @dataProvider getFormatToMimeTypeMapProvider
  97. */
  98. public function testGetMimeTypeFromFormat($format, $mimeTypes)
  99. {
  100. if (!is_null($format)) {
  101. $request = new Request();
  102. $this->assertEquals($mimeTypes[0], $request->getMimeType($format));
  103. }
  104. }
  105. public function getFormatToMimeTypeMapProvider()
  106. {
  107. return array(
  108. array(null, array(null, 'unexistant-mime-type')),
  109. array('txt', array('text/plain')),
  110. array('js', array('application/javascript', 'application/x-javascript', 'text/javascript')),
  111. array('css', array('text/css')),
  112. array('json', array('application/json', 'application/x-json')),
  113. array('xml', array('text/xml', 'application/xml', 'application/x-xml')),
  114. array('rdf', array('application/rdf+xml')),
  115. array('atom',array('application/atom+xml')),
  116. );
  117. }
  118. /**
  119. * @covers Symfony\Component\HttpFoundation\Request::getUri
  120. */
  121. public function testGetUri()
  122. {
  123. $server = array();
  124. // Standard Request on non default PORT
  125. // http://hostname:8080/index.php/path/info?query=string
  126. $server['HTTP_HOST'] = 'hostname:8080';
  127. $server['SERVER_NAME'] = 'hostname';
  128. $server['SERVER_PORT'] = '8080';
  129. $server['QUERY_STRING'] = 'query=string';
  130. $server['REQUEST_URI'] = '/index.php/path/info?query=string';
  131. $server['SCRIPT_NAME'] = '/index.php';
  132. $server['PATH_INFO'] = '/path/info';
  133. $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
  134. $server['PHP_SELF'] = '/index_dev.php/path/info';
  135. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  136. $request = new Request();
  137. $request->initialize(array(), array(), array(), array(), array(), $server);
  138. $this->assertEquals('http://hostname:8080/index.php/path/info?query=string', $request->getUri(), '->getUri() with non default port');
  139. // Use std port number
  140. $server['HTTP_HOST'] = 'hostname';
  141. $server['SERVER_NAME'] = 'hostname';
  142. $server['SERVER_PORT'] = '80';
  143. $request->initialize(array(), array(), array(), array(), array(), $server);
  144. $this->assertEquals('http://hostname/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port');
  145. // Without HOST HEADER
  146. unset($server['HTTP_HOST']);
  147. $server['SERVER_NAME'] = 'hostname';
  148. $server['SERVER_PORT'] = '80';
  149. $request->initialize(array(), array(), array(), array(), array(), $server);
  150. $this->assertEquals('http://hostname/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port without HOST_HEADER');
  151. // Request with URL REWRITING (hide index.php)
  152. // RewriteCond %{REQUEST_FILENAME} !-f
  153. // RewriteRule ^(.*)$ index.php [QSA,L]
  154. // http://hostname:8080/path/info?query=string
  155. $server = array();
  156. $server['HTTP_HOST'] = 'hostname:8080';
  157. $server['SERVER_NAME'] = 'hostname';
  158. $server['SERVER_PORT'] = '8080';
  159. $server['REDIRECT_QUERY_STRING'] = 'query=string';
  160. $server['REDIRECT_URL'] = '/path/info';
  161. $server['SCRIPT_NAME'] = '/index.php';
  162. $server['QUERY_STRING'] = 'query=string';
  163. $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
  164. $server['SCRIPT_NAME'] = '/index.php';
  165. $server['PHP_SELF'] = '/index.php';
  166. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  167. $request->initialize(array(), array(), array(), array(), array(), $server);
  168. $this->assertEquals('http://hostname:8080/path/info?query=string', $request->getUri(), '->getUri() with rewrite');
  169. // Use std port number
  170. // http://hostname/path/info?query=string
  171. $server['HTTP_HOST'] = 'hostname';
  172. $server['SERVER_NAME'] = 'hostname';
  173. $server['SERVER_PORT'] = '80';
  174. $request->initialize(array(), array(), array(), array(), array(), $server);
  175. $this->assertEquals('http://hostname/path/info?query=string', $request->getUri(), '->getUri() with rewrite and default port');
  176. // Without HOST HEADER
  177. unset($server['HTTP_HOST']);
  178. $server['SERVER_NAME'] = 'hostname';
  179. $server['SERVER_PORT'] = '80';
  180. $request->initialize(array(), array(), array(), array(), array(), $server);
  181. $this->assertEquals('http://hostname/path/info?query=string', $request->getUri(), '->getUri() with rewrite, default port without HOST_HEADER');
  182. }
  183. /**
  184. * @covers Symfony\Component\HttpFoundation\Request::getUriForPath
  185. */
  186. public function testGetUriForPath()
  187. {
  188. $request = Request::create('http://test.com/foo?bar=baz');
  189. $this->assertEquals('http://test.com/some/path', $request->getUriForPath('/some/path'));
  190. $request = Request::create('http://test.com:90/foo?bar=baz');
  191. $this->assertEquals('http://test.com:90/some/path', $request->getUriForPath('/some/path'));
  192. $request = Request::create('https://test.com/foo?bar=baz');
  193. $this->assertEquals('https://test.com/some/path', $request->getUriForPath('/some/path'));
  194. $request = Request::create('https://test.com:90/foo?bar=baz');
  195. $this->assertEquals('https://test.com:90/some/path', $request->getUriForPath('/some/path'));
  196. $server = array();
  197. // Standard Request on non default PORT
  198. // http://hostname:8080/index.php/path/info?query=string
  199. $server['HTTP_HOST'] = 'hostname:8080';
  200. $server['SERVER_NAME'] = 'hostname';
  201. $server['SERVER_PORT'] = '8080';
  202. $server['QUERY_STRING'] = 'query=string';
  203. $server['REQUEST_URI'] = '/index.php/path/info?query=string';
  204. $server['SCRIPT_NAME'] = '/index.php';
  205. $server['PATH_INFO'] = '/path/info';
  206. $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
  207. $server['PHP_SELF'] = '/index_dev.php/path/info';
  208. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  209. $request = new Request();
  210. $request->initialize(array(), array(), array(), array(), array(),$server);
  211. $this->assertEquals('http://hostname:8080/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with non default port');
  212. // Use std port number
  213. $server['HTTP_HOST'] = 'hostname';
  214. $server['SERVER_NAME'] = 'hostname';
  215. $server['SERVER_PORT'] = '80';
  216. $request->initialize(array(), array(), array(), array(), array(), $server);
  217. $this->assertEquals('http://hostname/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port');
  218. // Without HOST HEADER
  219. unset($server['HTTP_HOST']);
  220. $server['SERVER_NAME'] = 'hostname';
  221. $server['SERVER_PORT'] = '80';
  222. $request->initialize(array(), array(), array(), array(), array(), $server);
  223. $this->assertEquals('http://hostname/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port without HOST_HEADER');
  224. // Request with URL REWRITING (hide index.php)
  225. // RewriteCond %{REQUEST_FILENAME} !-f
  226. // RewriteRule ^(.*)$ index.php [QSA,L]
  227. // http://hostname:8080/path/info?query=string
  228. $server = array();
  229. $server['HTTP_HOST'] = 'hostname:8080';
  230. $server['SERVER_NAME'] = 'hostname';
  231. $server['SERVER_PORT'] = '8080';
  232. $server['REDIRECT_QUERY_STRING'] = 'query=string';
  233. $server['REDIRECT_URL'] = '/path/info';
  234. $server['SCRIPT_NAME'] = '/index.php';
  235. $server['QUERY_STRING'] = 'query=string';
  236. $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
  237. $server['SCRIPT_NAME'] = '/index.php';
  238. $server['PHP_SELF'] = '/index.php';
  239. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  240. $request->initialize(array(), array(), array(), array(), array(), $server);
  241. $this->assertEquals('http://hostname:8080/some/path', $request->getUriForPath('/some/path'), '->getUri() with rewrite');
  242. // Use std port number
  243. // http://hostname/path/info?query=string
  244. $server['HTTP_HOST'] = 'hostname';
  245. $server['SERVER_NAME'] = 'hostname';
  246. $server['SERVER_PORT'] = '80';
  247. $request->initialize(array(), array(), array(), array(), array(), $server);
  248. $this->assertEquals('http://hostname/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite and default port');
  249. // Without HOST HEADER
  250. unset($server['HTTP_HOST']);
  251. $server['SERVER_NAME'] = 'hostname';
  252. $server['SERVER_PORT'] = '80';
  253. $request->initialize(array(), array(), array(), array(), array(), $server);
  254. $this->assertEquals('http://hostname/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite, default port without HOST_HEADER');
  255. }
  256. /**
  257. * @covers Symfony\Component\HttpFoundation\Request::getQueryString
  258. */
  259. public function testGetQueryString()
  260. {
  261. $request = new Request();
  262. $request->server->set('QUERY_STRING', 'foo');
  263. $this->assertEquals('foo', $request->getQueryString(), '->getQueryString() works with valueless parameters');
  264. $request->server->set('QUERY_STRING', 'foo=');
  265. $this->assertEquals('foo=', $request->getQueryString(), '->getQueryString() includes a dangling equal sign');
  266. $request->server->set('QUERY_STRING', 'bar=&foo=bar');
  267. $this->assertEquals('bar=&foo=bar', $request->getQueryString(), '->getQueryString() works when empty parameters');
  268. $request->server->set('QUERY_STRING', 'foo=bar&bar=');
  269. $this->assertEquals('bar=&foo=bar', $request->getQueryString(), '->getQueryString() sorts keys alphabetically');
  270. $request->server->set('QUERY_STRING', 'him=John%20Doe&her=Jane+Doe');
  271. $this->assertEquals('her=Jane+Doe&him=John+Doe', $request->getQueryString(), '->getQueryString() normalizes encoding');
  272. $request->server->set('QUERY_STRING', 'foo[]=1&foo[]=2');
  273. $this->assertEquals('foo%5B%5D=1&foo%5B%5D=2', $request->getQueryString(), '->getQueryString() allows array notation');
  274. $request->server->set('QUERY_STRING', 'foo=1&foo=2');
  275. $this->assertEquals('foo=1&foo=2', $request->getQueryString(), '->getQueryString() allows repeated parameters');
  276. }
  277. /**
  278. * @covers Symfony\Component\HttpFoundation\Request::getHost
  279. */
  280. public function testGetHost()
  281. {
  282. $request = new Request();
  283. $request->initialize(array('foo' => 'bar'));
  284. $this->assertEquals('', $request->getHost(), '->getHost() return empty string if not initialized');
  285. $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.exemple.com'));
  286. $this->assertEquals('www.exemple.com', $request->getHost(), '->getHost() from Host Header');
  287. // Host header with port number.
  288. $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.exemple.com:8080'));
  289. $this->assertEquals('www.exemple.com', $request->getHost(), '->getHost() from Host Header with port number');
  290. // Server values.
  291. $request->initialize(array(), array(), array(), array(), array(), array('SERVER_NAME' => 'www.exemple.com'));
  292. $this->assertEquals('www.exemple.com', $request->getHost(), '->getHost() from server name');
  293. // X_FORWARDED_HOST.
  294. $request->initialize(array(), array(), array(), array(), array(), array('HTTP_X_FORWARDED_HOST' => 'www.exemple.com'));
  295. $this->assertEquals('www.exemple.com', $request->getHost(), '->getHost() from X_FORWARDED_HOST');
  296. // X_FORWARDED_HOST
  297. $request->initialize(array(), array(), array(), array(), array(), array('HTTP_X_FORWARDED_HOST' => 'www.exemple.com, www.second.com'));
  298. $this->assertEquals('www.second.com', $request->getHost(), '->getHost() value from X_FORWARDED_HOST use last value');
  299. // X_FORWARDED_HOST with port number
  300. $request->initialize(array(), array(), array(), array(), array(), array('HTTP_X_FORWARDED_HOST' => 'www.exemple.com, www.second.com:8080'));
  301. $this->assertEquals('www.second.com', $request->getHost(), '->getHost() value from X_FORWARDED_HOST with port number');
  302. $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.exemple.com', 'HTTP_X_FORWARDED_HOST' => 'www.forward.com'));
  303. $this->assertEquals('www.forward.com', $request->getHost(), '->getHost() value from X_FORWARDED_HOST has priority over Host');
  304. $request->initialize(array(), array(), array(), array(), array(), array('SERVER_NAME' => 'www.exemple.com', 'HTTP_X_FORWARDED_HOST' => 'www.forward.com'));
  305. $this->assertEquals('www.forward.com', $request->getHost(), '->getHost() value from X_FORWARDED_HOST has priority over SERVER_NAME ');
  306. $request->initialize(array(), array(), array(), array(), array(), array('SERVER_NAME' => 'www.exemple.com', 'HTTP_HOST' => 'www.host.com'));
  307. $this->assertEquals('www.host.com', $request->getHost(), '->getHost() value from Host header has priority over SERVER_NAME ');
  308. }
  309. /**
  310. * @covers Symfony\Component\HttpFoundation\Request::setMethod
  311. * @covers Symfony\Component\HttpFoundation\Request::getMethod
  312. */
  313. public function testGetSetMethod()
  314. {
  315. $request = new Request();
  316. $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns GET if no method is defined');
  317. $request->setMethod('get');
  318. $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns an uppercased string');
  319. $request->setMethod('PURGE');
  320. $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method even if it is not a standard one');
  321. $request->setMethod('POST');
  322. $this->assertEquals('POST', $request->getMethod(), '->getMethod() returns the method POST if no _method is defined');
  323. $request->setMethod('POST');
  324. $request->request->set('_method', 'purge');
  325. $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method from _method if defined and POST');
  326. }
  327. public function testGetContentWorksTwiceInDefaultMode()
  328. {
  329. $req = new Request;
  330. $this->assertEquals('', $req->getContent());
  331. $this->assertEquals('', $req->getContent());
  332. }
  333. public function testGetContentReturnsResource()
  334. {
  335. $req = new Request;
  336. $retval = $req->getContent(true);
  337. $this->assertInternalType('resource', $retval);
  338. $this->assertEquals("", fread($retval, 1));
  339. $this->assertTrue(feof($retval));
  340. }
  341. /**
  342. * @expectedException LogicException
  343. * @dataProvider getContentCantBeCalledTwiceWithResourcesProvider
  344. */
  345. public function testGetContentCantBeCalledTwiceWithResources($first, $second)
  346. {
  347. $req = new Request;
  348. $req->getContent($first);
  349. $req->getContent($second);
  350. }
  351. public function getContentCantBeCalledTwiceWithResourcesProvider()
  352. {
  353. return array(
  354. 'Resource then fetch' => array(true, false),
  355. 'Resource then resource' => array(true, true),
  356. 'Fetch then resource' => array(false, true),
  357. );
  358. }
  359. public function testCreateFromGlobals()
  360. {
  361. $_GET['foo1'] = 'bar1';
  362. $_POST['foo2'] = 'bar2';
  363. $_COOKIE['foo3'] = 'bar3';
  364. $_FILES['foo4'] = array('bar4');
  365. $_SERVER['foo5'] = 'bar5';
  366. $request = Request::createFromGlobals();
  367. $this->assertEquals('bar1', $request->query->get('foo1'), '::fromGlobals() uses values from $_GET');
  368. $this->assertEquals('bar2', $request->request->get('foo2'), '::fromGlobals() uses values from $_POST');
  369. $this->assertEquals('bar3', $request->cookies->get('foo3'), '::fromGlobals() uses values from $_COOKIE');
  370. $this->assertEquals(array('bar4'), $request->files->get('foo4'), '::fromGlobals() uses values from $_FILES');
  371. $this->assertEquals('bar5', $request->server->get('foo5'), '::fromGlobals() uses values from $_SERVER');
  372. unset($_GET['foo1'], $_POST['foo2'], $_COOKIE['foo3'], $_FILES['foo4'], $_SERVER['foo5']);
  373. }
  374. }