RequestTest.php 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.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\Component\HttpFoundation\Tests;
  11. use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
  12. use Symfony\Component\HttpFoundation\Session\Session;
  13. use Symfony\Component\HttpFoundation\Request;
  14. class RequestTest extends \PHPUnit_Framework_TestCase
  15. {
  16. /**
  17. * @covers Symfony\Component\HttpFoundation\Request::__construct
  18. */
  19. public function testConstructor()
  20. {
  21. $this->testInitialize();
  22. }
  23. /**
  24. * @covers Symfony\Component\HttpFoundation\Request::initialize
  25. */
  26. public function testInitialize()
  27. {
  28. $request = new Request();
  29. $request->initialize(array('foo' => 'bar'));
  30. $this->assertEquals('bar', $request->query->get('foo'), '->initialize() takes an array of query parameters as its first argument');
  31. $request->initialize(array(), array('foo' => 'bar'));
  32. $this->assertEquals('bar', $request->request->get('foo'), '->initialize() takes an array of request parameters as its second argument');
  33. $request->initialize(array(), array(), array('foo' => 'bar'));
  34. $this->assertEquals('bar', $request->attributes->get('foo'), '->initialize() takes an array of attributes as its third argument');
  35. $request->initialize(array(), array(), array(), array(), array(), array('HTTP_FOO' => 'bar'));
  36. $this->assertEquals('bar', $request->headers->get('FOO'), '->initialize() takes an array of HTTP headers as its fourth argument');
  37. }
  38. public function testGetLocale()
  39. {
  40. $request = new Request();
  41. $request->setLocale('pl');
  42. $locale = $request->getLocale();
  43. $this->assertEquals('pl', $locale);
  44. }
  45. public function testGetUser()
  46. {
  47. $request = Request::create('http://user_test:password_test@test.com/');
  48. $user = $request->getUser();
  49. $this->assertEquals('user_test', $user);
  50. }
  51. public function testGetPassword()
  52. {
  53. $request = Request::create('http://user_test:password_test@test.com/');
  54. $password = $request->getPassword();
  55. $this->assertEquals('password_test', $password);
  56. }
  57. public function testIsNoCache()
  58. {
  59. $request = new Request();
  60. $isNoCache = $request->isNoCache();
  61. $this->assertFalse($isNoCache);
  62. }
  63. public function testGetContentType()
  64. {
  65. $request = new Request();
  66. $contentType = $request->getContentType();
  67. $this->assertNull($contentType);
  68. }
  69. public function testSetDefaultLocale()
  70. {
  71. $request = new Request();
  72. $request->setDefaultLocale('pl');
  73. $locale = $request->getLocale();
  74. $this->assertEquals('pl', $locale);
  75. }
  76. /**
  77. * @covers Symfony\Component\HttpFoundation\Request::create
  78. */
  79. public function testCreate()
  80. {
  81. $request = Request::create('http://test.com/foo?bar=baz');
  82. $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
  83. $this->assertEquals('/foo', $request->getPathInfo());
  84. $this->assertEquals('bar=baz', $request->getQueryString());
  85. $this->assertEquals(80, $request->getPort());
  86. $this->assertEquals('test.com', $request->getHttpHost());
  87. $this->assertFalse($request->isSecure());
  88. $request = Request::create('http://test.com/foo', 'GET', array('bar' => 'baz'));
  89. $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
  90. $this->assertEquals('/foo', $request->getPathInfo());
  91. $this->assertEquals('bar=baz', $request->getQueryString());
  92. $this->assertEquals(80, $request->getPort());
  93. $this->assertEquals('test.com', $request->getHttpHost());
  94. $this->assertFalse($request->isSecure());
  95. $request = Request::create('http://test.com/foo?bar=foo', 'GET', array('bar' => 'baz'));
  96. $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
  97. $this->assertEquals('/foo', $request->getPathInfo());
  98. $this->assertEquals('bar=baz', $request->getQueryString());
  99. $this->assertEquals(80, $request->getPort());
  100. $this->assertEquals('test.com', $request->getHttpHost());
  101. $this->assertFalse($request->isSecure());
  102. $request = Request::create('https://test.com/foo?bar=baz');
  103. $this->assertEquals('https://test.com/foo?bar=baz', $request->getUri());
  104. $this->assertEquals('/foo', $request->getPathInfo());
  105. $this->assertEquals('bar=baz', $request->getQueryString());
  106. $this->assertEquals(443, $request->getPort());
  107. $this->assertEquals('test.com', $request->getHttpHost());
  108. $this->assertTrue($request->isSecure());
  109. $request = Request::create('test.com:90/foo');
  110. $this->assertEquals('http://test.com:90/foo', $request->getUri());
  111. $this->assertEquals('/foo', $request->getPathInfo());
  112. $this->assertEquals('test.com', $request->getHost());
  113. $this->assertEquals('test.com:90', $request->getHttpHost());
  114. $this->assertEquals(90, $request->getPort());
  115. $this->assertFalse($request->isSecure());
  116. $request = Request::create('https://test.com:90/foo');
  117. $this->assertEquals('https://test.com:90/foo', $request->getUri());
  118. $this->assertEquals('/foo', $request->getPathInfo());
  119. $this->assertEquals('test.com', $request->getHost());
  120. $this->assertEquals('test.com:90', $request->getHttpHost());
  121. $this->assertEquals(90, $request->getPort());
  122. $this->assertTrue($request->isSecure());
  123. $request = Request::create('https://127.0.0.1:90/foo');
  124. $this->assertEquals('https://127.0.0.1:90/foo', $request->getUri());
  125. $this->assertEquals('/foo', $request->getPathInfo());
  126. $this->assertEquals('127.0.0.1', $request->getHost());
  127. $this->assertEquals('127.0.0.1:90', $request->getHttpHost());
  128. $this->assertEquals(90, $request->getPort());
  129. $this->assertTrue($request->isSecure());
  130. $request = Request::create('https://[::1]:90/foo');
  131. $this->assertEquals('https://[::1]:90/foo', $request->getUri());
  132. $this->assertEquals('/foo', $request->getPathInfo());
  133. $this->assertEquals('[::1]', $request->getHost());
  134. $this->assertEquals('[::1]:90', $request->getHttpHost());
  135. $this->assertEquals(90, $request->getPort());
  136. $this->assertTrue($request->isSecure());
  137. $json = '{"jsonrpc":"2.0","method":"echo","id":7,"params":["Hello World"]}';
  138. $request = Request::create('http://example.com/jsonrpc', 'POST', array(), array(), array(), array(), $json);
  139. $this->assertEquals($json, $request->getContent());
  140. $this->assertFalse($request->isSecure());
  141. $request = Request::create('http://test.com');
  142. $this->assertEquals('http://test.com/', $request->getUri());
  143. $this->assertEquals('/', $request->getPathInfo());
  144. $this->assertEquals('', $request->getQueryString());
  145. $this->assertEquals(80, $request->getPort());
  146. $this->assertEquals('test.com', $request->getHttpHost());
  147. $this->assertFalse($request->isSecure());
  148. $request = Request::create('http://test.com?test=1');
  149. $this->assertEquals('http://test.com/?test=1', $request->getUri());
  150. $this->assertEquals('/', $request->getPathInfo());
  151. $this->assertEquals('test=1', $request->getQueryString());
  152. $this->assertEquals(80, $request->getPort());
  153. $this->assertEquals('test.com', $request->getHttpHost());
  154. $this->assertFalse($request->isSecure());
  155. $request = Request::create('http://test.com:90/?test=1');
  156. $this->assertEquals('http://test.com:90/?test=1', $request->getUri());
  157. $this->assertEquals('/', $request->getPathInfo());
  158. $this->assertEquals('test=1', $request->getQueryString());
  159. $this->assertEquals(90, $request->getPort());
  160. $this->assertEquals('test.com:90', $request->getHttpHost());
  161. $this->assertFalse($request->isSecure());
  162. $request = Request::create('http://test:test@test.com');
  163. $this->assertEquals('http://test.com/', $request->getUri());
  164. $this->assertEquals('/', $request->getPathInfo());
  165. $this->assertEquals('', $request->getQueryString());
  166. $this->assertEquals(80, $request->getPort());
  167. $this->assertEquals('test.com', $request->getHttpHost());
  168. $this->assertEquals('test', $request->getUser());
  169. $this->assertEquals('test', $request->getPassword());
  170. $this->assertFalse($request->isSecure());
  171. $request = Request::create('http://testnopass@test.com');
  172. $this->assertEquals('http://test.com/', $request->getUri());
  173. $this->assertEquals('/', $request->getPathInfo());
  174. $this->assertEquals('', $request->getQueryString());
  175. $this->assertEquals(80, $request->getPort());
  176. $this->assertEquals('test.com', $request->getHttpHost());
  177. $this->assertEquals('testnopass', $request->getUser());
  178. $this->assertNull($request->getPassword());
  179. $this->assertFalse($request->isSecure());
  180. }
  181. /**
  182. * @covers Symfony\Component\HttpFoundation\Request::create
  183. */
  184. public function testCreateCheckPrecedence()
  185. {
  186. // server is used by default
  187. $request = Request::create('/', 'DELETE', array(), array(), array(), array(
  188. 'HTTP_HOST' => 'example.com',
  189. 'HTTPS' => 'on',
  190. 'SERVER_PORT' => 443,
  191. 'PHP_AUTH_USER' => 'fabien',
  192. 'PHP_AUTH_PW' => 'pa$$',
  193. 'QUERY_STRING' => 'foo=bar',
  194. 'CONTENT_TYPE' => 'application/json',
  195. ));
  196. $this->assertEquals('example.com', $request->getHost());
  197. $this->assertEquals(443, $request->getPort());
  198. $this->assertTrue($request->isSecure());
  199. $this->assertEquals('fabien', $request->getUser());
  200. $this->assertEquals('pa$$', $request->getPassword());
  201. $this->assertEquals('', $request->getQueryString());
  202. $this->assertEquals('application/json', $request->headers->get('CONTENT_TYPE'));
  203. // URI has precedence over server
  204. $request = Request::create('http://thomas:pokemon@example.net:8080/?foo=bar', 'GET', array(), array(), array(), array(
  205. 'HTTP_HOST' => 'example.com',
  206. 'HTTPS' => 'on',
  207. 'SERVER_PORT' => 443,
  208. ));
  209. $this->assertEquals('example.net', $request->getHost());
  210. $this->assertEquals(8080, $request->getPort());
  211. $this->assertFalse($request->isSecure());
  212. $this->assertEquals('thomas', $request->getUser());
  213. $this->assertEquals('pokemon', $request->getPassword());
  214. $this->assertEquals('foo=bar', $request->getQueryString());
  215. }
  216. /**
  217. * @covers Symfony\Component\HttpFoundation\Request::duplicate
  218. */
  219. public function testDuplicate()
  220. {
  221. $request = new Request(array('foo' => 'bar'), array('foo' => 'bar'), array('foo' => 'bar'), array(), array(), array('HTTP_FOO' => 'bar'));
  222. $dup = $request->duplicate();
  223. $this->assertEquals($request->query->all(), $dup->query->all(), '->duplicate() duplicates a request an copy the current query parameters');
  224. $this->assertEquals($request->request->all(), $dup->request->all(), '->duplicate() duplicates a request an copy the current request parameters');
  225. $this->assertEquals($request->attributes->all(), $dup->attributes->all(), '->duplicate() duplicates a request an copy the current attributes');
  226. $this->assertEquals($request->headers->all(), $dup->headers->all(), '->duplicate() duplicates a request an copy the current HTTP headers');
  227. $dup = $request->duplicate(array('foo' => 'foobar'), array('foo' => 'foobar'), array('foo' => 'foobar'), array(), array(), array('HTTP_FOO' => 'foobar'));
  228. $this->assertEquals(array('foo' => 'foobar'), $dup->query->all(), '->duplicate() overrides the query parameters if provided');
  229. $this->assertEquals(array('foo' => 'foobar'), $dup->request->all(), '->duplicate() overrides the request parameters if provided');
  230. $this->assertEquals(array('foo' => 'foobar'), $dup->attributes->all(), '->duplicate() overrides the attributes if provided');
  231. $this->assertEquals(array('foo' => array('foobar')), $dup->headers->all(), '->duplicate() overrides the HTTP header if provided');
  232. }
  233. /**
  234. * @covers Symfony\Component\HttpFoundation\Request::getFormat
  235. * @covers Symfony\Component\HttpFoundation\Request::setFormat
  236. * @dataProvider getFormatToMimeTypeMapProvider
  237. */
  238. public function testGetFormatFromMimeType($format, $mimeTypes)
  239. {
  240. $request = new Request();
  241. foreach ($mimeTypes as $mime) {
  242. $this->assertEquals($format, $request->getFormat($mime));
  243. }
  244. $request->setFormat($format, $mimeTypes);
  245. foreach ($mimeTypes as $mime) {
  246. $this->assertEquals($format, $request->getFormat($mime));
  247. }
  248. }
  249. /**
  250. * @covers Symfony\Component\HttpFoundation\Request::getFormat
  251. */
  252. public function testGetFormatFromMimeTypeWithParameters()
  253. {
  254. $request = new Request();
  255. $this->assertEquals('json', $request->getFormat('application/json; charset=utf-8'));
  256. }
  257. /**
  258. * @covers Symfony\Component\HttpFoundation\Request::getMimeType
  259. * @dataProvider getFormatToMimeTypeMapProvider
  260. */
  261. public function testGetMimeTypeFromFormat($format, $mimeTypes)
  262. {
  263. if (null !== $format) {
  264. $request = new Request();
  265. $this->assertEquals($mimeTypes[0], $request->getMimeType($format));
  266. }
  267. }
  268. public function getFormatToMimeTypeMapProvider()
  269. {
  270. return array(
  271. array(null, array(null, 'unexistent-mime-type')),
  272. array('txt', array('text/plain')),
  273. array('js', array('application/javascript', 'application/x-javascript', 'text/javascript')),
  274. array('css', array('text/css')),
  275. array('json', array('application/json', 'application/x-json')),
  276. array('xml', array('text/xml', 'application/xml', 'application/x-xml')),
  277. array('rdf', array('application/rdf+xml')),
  278. array('atom',array('application/atom+xml')),
  279. );
  280. }
  281. /**
  282. * @covers Symfony\Component\HttpFoundation\Request::getUri
  283. */
  284. public function testGetUri()
  285. {
  286. $server = array();
  287. // Standard Request on non default PORT
  288. // http://host:8080/index.php/path/info?query=string
  289. $server['HTTP_HOST'] = 'host:8080';
  290. $server['SERVER_NAME'] = 'servername';
  291. $server['SERVER_PORT'] = '8080';
  292. $server['QUERY_STRING'] = 'query=string';
  293. $server['REQUEST_URI'] = '/index.php/path/info?query=string';
  294. $server['SCRIPT_NAME'] = '/index.php';
  295. $server['PATH_INFO'] = '/path/info';
  296. $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
  297. $server['PHP_SELF'] = '/index_dev.php/path/info';
  298. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  299. $request = new Request();
  300. $request->initialize(array(), array(), array(), array(), array(), $server);
  301. $this->assertEquals('http://host:8080/index.php/path/info?query=string', $request->getUri(), '->getUri() with non default port');
  302. // Use std port number
  303. $server['HTTP_HOST'] = 'host';
  304. $server['SERVER_NAME'] = 'servername';
  305. $server['SERVER_PORT'] = '80';
  306. $request->initialize(array(), array(), array(), array(), array(), $server);
  307. $this->assertEquals('http://host/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port');
  308. // Without HOST HEADER
  309. unset($server['HTTP_HOST']);
  310. $server['SERVER_NAME'] = 'servername';
  311. $server['SERVER_PORT'] = '80';
  312. $request->initialize(array(), array(), array(), array(), array(), $server);
  313. $this->assertEquals('http://servername/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port without HOST_HEADER');
  314. // Request with URL REWRITING (hide index.php)
  315. // RewriteCond %{REQUEST_FILENAME} !-f
  316. // RewriteRule ^(.*)$ index.php [QSA,L]
  317. // http://host:8080/path/info?query=string
  318. $server = array();
  319. $server['HTTP_HOST'] = 'host:8080';
  320. $server['SERVER_NAME'] = 'servername';
  321. $server['SERVER_PORT'] = '8080';
  322. $server['REDIRECT_QUERY_STRING'] = 'query=string';
  323. $server['REDIRECT_URL'] = '/path/info';
  324. $server['SCRIPT_NAME'] = '/index.php';
  325. $server['QUERY_STRING'] = 'query=string';
  326. $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
  327. $server['SCRIPT_NAME'] = '/index.php';
  328. $server['PHP_SELF'] = '/index.php';
  329. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  330. $request->initialize(array(), array(), array(), array(), array(), $server);
  331. $this->assertEquals('http://host:8080/path/info?query=string', $request->getUri(), '->getUri() with rewrite');
  332. // Use std port number
  333. // http://host/path/info?query=string
  334. $server['HTTP_HOST'] = 'host';
  335. $server['SERVER_NAME'] = 'servername';
  336. $server['SERVER_PORT'] = '80';
  337. $request->initialize(array(), array(), array(), array(), array(), $server);
  338. $this->assertEquals('http://host/path/info?query=string', $request->getUri(), '->getUri() with rewrite and default port');
  339. // Without HOST HEADER
  340. unset($server['HTTP_HOST']);
  341. $server['SERVER_NAME'] = 'servername';
  342. $server['SERVER_PORT'] = '80';
  343. $request->initialize(array(), array(), array(), array(), array(), $server);
  344. $this->assertEquals('http://servername/path/info?query=string', $request->getUri(), '->getUri() with rewrite, default port without HOST_HEADER');
  345. // With encoded characters
  346. $server = array(
  347. 'HTTP_HOST' => 'host:8080',
  348. 'SERVER_NAME' => 'servername',
  349. 'SERVER_PORT' => '8080',
  350. 'QUERY_STRING' => 'query=string',
  351. 'REQUEST_URI' => '/ba%20se/index_dev.php/foo%20bar/in+fo?query=string',
  352. 'SCRIPT_NAME' => '/ba se/index_dev.php',
  353. 'PATH_TRANSLATED' => 'redirect:/index.php/foo bar/in+fo',
  354. 'PHP_SELF' => '/ba se/index_dev.php/path/info',
  355. 'SCRIPT_FILENAME' => '/some/where/ba se/index_dev.php',
  356. );
  357. $request->initialize(array(), array(), array(), array(), array(), $server);
  358. $this->assertEquals(
  359. 'http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string',
  360. $request->getUri()
  361. );
  362. // with user info
  363. $server['PHP_AUTH_USER'] = 'fabien';
  364. $request->initialize(array(), array(), array(), array(), array(), $server);
  365. $this->assertEquals('http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri());
  366. $server['PHP_AUTH_PW'] = 'symfony';
  367. $request->initialize(array(), array(), array(), array(), array(), $server);
  368. $this->assertEquals('http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri());
  369. }
  370. /**
  371. * @covers Symfony\Component\HttpFoundation\Request::getUriForPath
  372. */
  373. public function testGetUriForPath()
  374. {
  375. $request = Request::create('http://test.com/foo?bar=baz');
  376. $this->assertEquals('http://test.com/some/path', $request->getUriForPath('/some/path'));
  377. $request = Request::create('http://test.com:90/foo?bar=baz');
  378. $this->assertEquals('http://test.com:90/some/path', $request->getUriForPath('/some/path'));
  379. $request = Request::create('https://test.com/foo?bar=baz');
  380. $this->assertEquals('https://test.com/some/path', $request->getUriForPath('/some/path'));
  381. $request = Request::create('https://test.com:90/foo?bar=baz');
  382. $this->assertEquals('https://test.com:90/some/path', $request->getUriForPath('/some/path'));
  383. $server = array();
  384. // Standard Request on non default PORT
  385. // http://host:8080/index.php/path/info?query=string
  386. $server['HTTP_HOST'] = 'host:8080';
  387. $server['SERVER_NAME'] = 'servername';
  388. $server['SERVER_PORT'] = '8080';
  389. $server['QUERY_STRING'] = 'query=string';
  390. $server['REQUEST_URI'] = '/index.php/path/info?query=string';
  391. $server['SCRIPT_NAME'] = '/index.php';
  392. $server['PATH_INFO'] = '/path/info';
  393. $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
  394. $server['PHP_SELF'] = '/index_dev.php/path/info';
  395. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  396. $request = new Request();
  397. $request->initialize(array(), array(), array(), array(), array(),$server);
  398. $this->assertEquals('http://host:8080/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with non default port');
  399. // Use std port number
  400. $server['HTTP_HOST'] = 'host';
  401. $server['SERVER_NAME'] = 'servername';
  402. $server['SERVER_PORT'] = '80';
  403. $request->initialize(array(), array(), array(), array(), array(), $server);
  404. $this->assertEquals('http://host/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port');
  405. // Without HOST HEADER
  406. unset($server['HTTP_HOST']);
  407. $server['SERVER_NAME'] = 'servername';
  408. $server['SERVER_PORT'] = '80';
  409. $request->initialize(array(), array(), array(), array(), array(), $server);
  410. $this->assertEquals('http://servername/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port without HOST_HEADER');
  411. // Request with URL REWRITING (hide index.php)
  412. // RewriteCond %{REQUEST_FILENAME} !-f
  413. // RewriteRule ^(.*)$ index.php [QSA,L]
  414. // http://host:8080/path/info?query=string
  415. $server = array();
  416. $server['HTTP_HOST'] = 'host:8080';
  417. $server['SERVER_NAME'] = 'servername';
  418. $server['SERVER_PORT'] = '8080';
  419. $server['REDIRECT_QUERY_STRING'] = 'query=string';
  420. $server['REDIRECT_URL'] = '/path/info';
  421. $server['SCRIPT_NAME'] = '/index.php';
  422. $server['QUERY_STRING'] = 'query=string';
  423. $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
  424. $server['SCRIPT_NAME'] = '/index.php';
  425. $server['PHP_SELF'] = '/index.php';
  426. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  427. $request->initialize(array(), array(), array(), array(), array(), $server);
  428. $this->assertEquals('http://host:8080/some/path', $request->getUriForPath('/some/path'), '->getUri() with rewrite');
  429. // Use std port number
  430. // http://host/path/info?query=string
  431. $server['HTTP_HOST'] = 'host';
  432. $server['SERVER_NAME'] = 'servername';
  433. $server['SERVER_PORT'] = '80';
  434. $request->initialize(array(), array(), array(), array(), array(), $server);
  435. $this->assertEquals('http://host/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite and default port');
  436. // Without HOST HEADER
  437. unset($server['HTTP_HOST']);
  438. $server['SERVER_NAME'] = 'servername';
  439. $server['SERVER_PORT'] = '80';
  440. $request->initialize(array(), array(), array(), array(), array(), $server);
  441. $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite, default port without HOST_HEADER');
  442. $this->assertEquals('servername', $request->getHttpHost());
  443. // with user info
  444. $server['PHP_AUTH_USER'] = 'fabien';
  445. $request->initialize(array(), array(), array(), array(), array(), $server);
  446. $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'));
  447. $server['PHP_AUTH_PW'] = 'symfony';
  448. $request->initialize(array(), array(), array(), array(), array(), $server);
  449. $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'));
  450. }
  451. /**
  452. * @covers Symfony\Component\HttpFoundation\Request::getUserInfo
  453. */
  454. public function testGetUserInfo()
  455. {
  456. $request = new Request();
  457. $server['PHP_AUTH_USER'] = 'fabien';
  458. $request->initialize(array(), array(), array(), array(), array(), $server);
  459. $this->assertEquals('fabien', $request->getUserInfo());
  460. $server['PHP_AUTH_USER'] = '0';
  461. $request->initialize(array(), array(), array(), array(), array(), $server);
  462. $this->assertEquals('0', $request->getUserInfo());
  463. $server['PHP_AUTH_PW'] = '0';
  464. $request->initialize(array(), array(), array(), array(), array(), $server);
  465. $this->assertEquals('0:0', $request->getUserInfo());
  466. }
  467. /**
  468. * @covers Symfony\Component\HttpFoundation\Request::getSchemeAndHttpHost
  469. */
  470. public function testGetSchemeAndHttpHost()
  471. {
  472. $request = new Request();
  473. $server['SERVER_NAME'] = 'servername';
  474. $server['SERVER_PORT'] = '90';
  475. $request->initialize(array(), array(), array(), array(), array(), $server);
  476. $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
  477. $server['PHP_AUTH_USER'] = 'fabien';
  478. $request->initialize(array(), array(), array(), array(), array(), $server);
  479. $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
  480. $server['PHP_AUTH_USER'] = '0';
  481. $request->initialize(array(), array(), array(), array(), array(), $server);
  482. $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
  483. $server['PHP_AUTH_PW'] = '0';
  484. $request->initialize(array(), array(), array(), array(), array(), $server);
  485. $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
  486. }
  487. /**
  488. * @covers Symfony\Component\HttpFoundation\Request::getQueryString
  489. * @covers Symfony\Component\HttpFoundation\Request::normalizeQueryString
  490. * @dataProvider getQueryStringNormalizationData
  491. */
  492. public function testGetQueryString($query, $expectedQuery, $msg)
  493. {
  494. $request = new Request();
  495. $request->server->set('QUERY_STRING', $query);
  496. $this->assertSame($expectedQuery, $request->getQueryString(), $msg);
  497. }
  498. public function getQueryStringNormalizationData()
  499. {
  500. return array(
  501. array('foo', 'foo', 'works with valueless parameters'),
  502. array('foo=', 'foo=', 'includes a dangling equal sign'),
  503. array('bar=&foo=bar', 'bar=&foo=bar', '->works with empty parameters'),
  504. array('foo=bar&bar=', 'bar=&foo=bar', 'sorts keys alphabetically'),
  505. // GET parameters, that are submitted from a HTML form, encode spaces as "+" by default (as defined in enctype application/x-www-form-urlencoded).
  506. // PHP also converts "+" to spaces when filling the global _GET or when using the function parse_str.
  507. array('him=John%20Doe&her=Jane+Doe', 'her=Jane%20Doe&him=John%20Doe', 'normalizes spaces in both encodings "%20" and "+"'),
  508. array('foo[]=1&foo[]=2', 'foo%5B%5D=1&foo%5B%5D=2', 'allows array notation'),
  509. array('foo=1&foo=2', 'foo=1&foo=2', 'allows repeated parameters'),
  510. array('pa%3Dram=foo%26bar%3Dbaz&test=test', 'pa%3Dram=foo%26bar%3Dbaz&test=test', 'works with encoded delimiters'),
  511. array('0', '0', 'allows "0"'),
  512. array('Jane Doe&John%20Doe', 'Jane%20Doe&John%20Doe', 'normalizes encoding in keys'),
  513. array('her=Jane Doe&him=John%20Doe', 'her=Jane%20Doe&him=John%20Doe', 'normalizes encoding in values'),
  514. array('foo=bar&&&test&&', 'foo=bar&test', 'removes unneeded delimiters'),
  515. array('formula=e=m*c^2', 'formula=e%3Dm%2Ac%5E2', 'correctly treats only the first "=" as delimiter and the next as value'),
  516. // Ignore pairs with empty key, even if there was a value, e.g. "=value", as such nameless values cannot be retrieved anyway.
  517. // PHP also does not include them when building _GET.
  518. array('foo=bar&=a=b&=x=y', 'foo=bar', 'removes params with empty key'),
  519. );
  520. }
  521. public function testGetQueryStringReturnsNull()
  522. {
  523. $request = new Request();
  524. $this->assertNull($request->getQueryString(), '->getQueryString() returns null for non-existent query string');
  525. $request->server->set('QUERY_STRING', '');
  526. $this->assertNull($request->getQueryString(), '->getQueryString() returns null for empty query string');
  527. }
  528. public function testGetHost()
  529. {
  530. $request = new Request();
  531. $request->initialize(array('foo' => 'bar'));
  532. $this->assertEquals('', $request->getHost(), '->getHost() return empty string if not initialized');
  533. $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.exemple.com'));
  534. $this->assertEquals('www.exemple.com', $request->getHost(), '->getHost() from Host Header');
  535. // Host header with port number
  536. $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.exemple.com:8080'));
  537. $this->assertEquals('www.exemple.com', $request->getHost(), '->getHost() from Host Header with port number');
  538. // Server values
  539. $request->initialize(array(), array(), array(), array(), array(), array('SERVER_NAME' => 'www.exemple.com'));
  540. $this->assertEquals('www.exemple.com', $request->getHost(), '->getHost() from server name');
  541. $request->initialize(array(), array(), array(), array(), array(), array('SERVER_NAME' => 'www.exemple.com', 'HTTP_HOST' => 'www.host.com'));
  542. $this->assertEquals('www.host.com', $request->getHost(), '->getHost() value from Host header has priority over SERVER_NAME ');
  543. }
  544. public function testGetPort()
  545. {
  546. $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
  547. 'HTTP_X_FORWARDED_PROTO' => 'https',
  548. 'HTTP_X_FORWARDED_PORT' => '443'
  549. ));
  550. $port = $request->getPort();
  551. $this->assertEquals(80, $port, 'Without trusted proxies FORWARDED_PROTO and FORWARDED_PORT are ignored.');
  552. Request::setTrustedProxies(array('1.1.1.1'));
  553. $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
  554. 'HTTP_X_FORWARDED_PROTO' => 'https',
  555. 'HTTP_X_FORWARDED_PORT' => '8443'
  556. ));
  557. $port = $request->getPort();
  558. $this->assertEquals(8443, $port, 'With PROTO and PORT set PORT takes precedence.');
  559. $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
  560. 'HTTP_X_FORWARDED_PROTO' => 'https'
  561. ));
  562. $port = $request->getPort();
  563. $this->assertEquals(443, $port, 'With only PROTO set getPort() defaults to 443.');
  564. $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
  565. 'HTTP_X_FORWARDED_PROTO' => 'http'
  566. ));
  567. $port = $request->getPort();
  568. $this->assertEquals(80, $port, 'If X_FORWARDED_PROTO is set to http return 80.');
  569. Request::setTrustedProxies(array());
  570. }
  571. /**
  572. * @expectedException RuntimeException
  573. */
  574. public function testGetHostWithFakeHttpHostValue()
  575. {
  576. $request = new Request();
  577. $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.host.com?query=string'));
  578. $request->getHost();
  579. }
  580. /**
  581. * @covers Symfony\Component\HttpFoundation\Request::setMethod
  582. * @covers Symfony\Component\HttpFoundation\Request::getMethod
  583. */
  584. public function testGetSetMethod()
  585. {
  586. $request = new Request();
  587. $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns GET if no method is defined');
  588. $request->setMethod('get');
  589. $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns an uppercased string');
  590. $request->setMethod('PURGE');
  591. $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method even if it is not a standard one');
  592. $request->setMethod('POST');
  593. $this->assertEquals('POST', $request->getMethod(), '->getMethod() returns the method POST if no _method is defined');
  594. $request->setMethod('POST');
  595. $request->request->set('_method', 'purge');
  596. $this->assertEquals('POST', $request->getMethod(), '->getMethod() does not return the method from _method if defined and POST but support not enabled');
  597. $request = new Request();
  598. $request->setMethod('POST');
  599. $request->request->set('_method', 'purge');
  600. $this->assertFalse(Request::getHttpMethodParameterOverride(), 'httpMethodParameterOverride should be disabled by default');
  601. Request::enableHttpMethodParameterOverride();
  602. $this->assertTrue(Request::getHttpMethodParameterOverride(), 'httpMethodParameterOverride should be enabled now but it is not');
  603. $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method from _method if defined and POST');
  604. $this->disableHttpMethodParameterOverride();
  605. $request = new Request();
  606. $request->setMethod('POST');
  607. $request->query->set('_method', 'purge');
  608. $this->assertEquals('POST', $request->getMethod(), '->getMethod() does not return the method from _method if defined and POST but support not enabled');
  609. $request = new Request();
  610. $request->setMethod('POST');
  611. $request->query->set('_method', 'purge');
  612. Request::enableHttpMethodParameterOverride();
  613. $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method from _method if defined and POST');
  614. $this->disableHttpMethodParameterOverride();
  615. $request = new Request();
  616. $request->setMethod('POST');
  617. $request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete');
  618. $this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override even though _method is set if defined and POST');
  619. $request = new Request();
  620. $request->setMethod('POST');
  621. $request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete');
  622. $this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override if defined and POST');
  623. }
  624. /**
  625. * @dataProvider testGetClientIpsProvider
  626. */
  627. public function testGetClientIp($expected, $remoteAddr, $httpForwardedFor, $trustedProxies)
  628. {
  629. $request = $this->getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies);
  630. $this->assertEquals($expected[0], $request->getClientIp());
  631. Request::setTrustedProxies(array());
  632. }
  633. /**
  634. * @dataProvider testGetClientIpsProvider
  635. */
  636. public function testGetClientIps($expected, $remoteAddr, $httpForwardedFor, $trustedProxies)
  637. {
  638. $request = $this->getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies);
  639. $this->assertEquals($expected, $request->getClientIps());
  640. Request::setTrustedProxies(array());
  641. }
  642. public function testGetClientIpsProvider()
  643. {
  644. // $expected $remoteAddr $httpForwardedFor $trustedProxies
  645. return array(
  646. // simple IPv4
  647. array(array('88.88.88.88'), '88.88.88.88', null, null),
  648. // trust the IPv4 remote addr
  649. array(array('88.88.88.88'), '88.88.88.88', null, array('88.88.88.88')),
  650. // simple IPv6
  651. array(array('::1'), '::1', null, null),
  652. // trust the IPv6 remote addr
  653. array(array('::1'), '::1', null, array('::1')),
  654. // forwarded for with remote IPv4 addr not trusted
  655. array(array('127.0.0.1'), '127.0.0.1', '88.88.88.88', null),
  656. // forwarded for with remote IPv4 addr trusted
  657. array(array('88.88.88.88'), '127.0.0.1', '88.88.88.88', array('127.0.0.1')),
  658. // forwarded for with remote IPv4 and all FF addrs trusted
  659. array(array('88.88.88.88'), '127.0.0.1', '88.88.88.88', array('127.0.0.1', '88.88.88.88')),
  660. // forwarded for with remote IPv4 range trusted
  661. array(array('88.88.88.88'), '123.45.67.89', '88.88.88.88', array('123.45.67.0/24')),
  662. // forwarded for with remote IPv6 addr not trusted
  663. array(array('1620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '2620:0:1cfe:face:b00c::3', null),
  664. // forwarded for with remote IPv6 addr trusted
  665. array(array('2620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '2620:0:1cfe:face:b00c::3', array('1620:0:1cfe:face:b00c::3')),
  666. // forwarded for with remote IPv6 range trusted
  667. array(array('88.88.88.88'), '2a01:198:603:0:396e:4789:8e99:890f', '88.88.88.88', array('2a01:198:603:0::/65')),
  668. // multiple forwarded for with remote IPv4 addr trusted
  669. array(array('88.88.88.88', '87.65.43.21', '127.0.0.1'), '123.45.67.89', '127.0.0.1, 87.65.43.21, 88.88.88.88', array('123.45.67.89')),
  670. // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted
  671. array(array('87.65.43.21', '127.0.0.1'), '123.45.67.89', '127.0.0.1, 87.65.43.21, 88.88.88.88', array('123.45.67.89', '88.88.88.88')),
  672. // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted but in the middle
  673. array(array('88.88.88.88', '127.0.0.1'), '123.45.67.89', '127.0.0.1, 87.65.43.21, 88.88.88.88', array('123.45.67.89', '87.65.43.21')),
  674. // multiple forwarded for with remote IPv4 addr and all reverse proxies trusted
  675. array(array('127.0.0.1'), '123.45.67.89', '127.0.0.1, 87.65.43.21, 88.88.88.88', array('123.45.67.89', '87.65.43.21', '88.88.88.88', '127.0.0.1')),
  676. // multiple forwarded for with remote IPv6 addr trusted
  677. array(array('2620:0:1cfe:face:b00c::3', '3620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '3620:0:1cfe:face:b00c::3,2620:0:1cfe:face:b00c::3', array('1620:0:1cfe:face:b00c::3')),
  678. // multiple forwarded for with remote IPv6 addr and some reverse proxies trusted
  679. array(array('3620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '3620:0:1cfe:face:b00c::3,2620:0:1cfe:face:b00c::3', array('1620:0:1cfe:face:b00c::3', '2620:0:1cfe:face:b00c::3')),
  680. // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted but in the middle
  681. array(array('2620:0:1cfe:face:b00c::3', '4620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '4620:0:1cfe:face:b00c::3,3620:0:1cfe:face:b00c::3,2620:0:1cfe:face:b00c::3', array('1620:0:1cfe:face:b00c::3', '3620:0:1cfe:face:b00c::3')),
  682. );
  683. }
  684. public function testGetContentWorksTwiceInDefaultMode()
  685. {
  686. $req = new Request;
  687. $this->assertEquals('', $req->getContent());
  688. $this->assertEquals('', $req->getContent());
  689. }
  690. public function testGetContentReturnsResource()
  691. {
  692. $req = new Request;
  693. $retval = $req->getContent(true);
  694. $this->assertInternalType('resource', $retval);
  695. $this->assertEquals("", fread($retval, 1));
  696. $this->assertTrue(feof($retval));
  697. }
  698. /**
  699. * @expectedException LogicException
  700. * @dataProvider getContentCantBeCalledTwiceWithResourcesProvider
  701. */
  702. public function testGetContentCantBeCalledTwiceWithResources($first, $second)
  703. {
  704. $req = new Request;
  705. $req->getContent($first);
  706. $req->getContent($second);
  707. }
  708. public function getContentCantBeCalledTwiceWithResourcesProvider()
  709. {
  710. return array(
  711. 'Resource then fetch' => array(true, false),
  712. 'Resource then resource' => array(true, true),
  713. 'Fetch then resource' => array(false, true),
  714. );
  715. }
  716. public function provideOverloadedMethods()
  717. {
  718. return array(
  719. array('PUT'),
  720. array('DELETE'),
  721. array('PATCH'),
  722. array('put'),
  723. array('delete'),
  724. array('patch'),
  725. );
  726. }
  727. /**
  728. * @dataProvider provideOverloadedMethods
  729. */
  730. public function testCreateFromGlobals($method)
  731. {
  732. $normalizedMethod = strtoupper($method);
  733. $_GET['foo1'] = 'bar1';
  734. $_POST['foo2'] = 'bar2';
  735. $_COOKIE['foo3'] = 'bar3';
  736. $_FILES['foo4'] = array('bar4');
  737. $_SERVER['foo5'] = 'bar5';
  738. $request = Request::createFromGlobals();
  739. $this->assertEquals('bar1', $request->query->get('foo1'), '::fromGlobals() uses values from $_GET');
  740. $this->assertEquals('bar2', $request->request->get('foo2'), '::fromGlobals() uses values from $_POST');
  741. $this->assertEquals('bar3', $request->cookies->get('foo3'), '::fromGlobals() uses values from $_COOKIE');
  742. $this->assertEquals(array('bar4'), $request->files->get('foo4'), '::fromGlobals() uses values from $_FILES');
  743. $this->assertEquals('bar5', $request->server->get('foo5'), '::fromGlobals() uses values from $_SERVER');
  744. unset($_GET['foo1'], $_POST['foo2'], $_COOKIE['foo3'], $_FILES['foo4'], $_SERVER['foo5']);
  745. $_SERVER['REQUEST_METHOD'] = $method;
  746. $_SERVER['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
  747. $request = RequestContentProxy::createFromGlobals();
  748. $this->assertEquals($normalizedMethod, $request->getMethod());
  749. $this->assertEquals('mycontent', $request->request->get('content'));
  750. unset($_SERVER['REQUEST_METHOD'], $_SERVER['CONTENT_TYPE']);
  751. Request::createFromGlobals();
  752. Request::enableHttpMethodParameterOverride();
  753. $_POST['_method'] = $method;
  754. $_POST['foo6'] = 'bar6';
  755. $_SERVER['REQUEST_METHOD'] = 'PoSt';
  756. $request = Request::createFromGlobals();
  757. $this->assertEquals($normalizedMethod, $request->getMethod());
  758. $this->assertEquals('POST', $request->getRealMethod());
  759. $this->assertEquals('bar6', $request->request->get('foo6'));
  760. unset($_POST['_method'], $_POST['foo6'], $_SERVER['REQUEST_METHOD']);
  761. $this->disableHttpMethodParameterOverride();
  762. }
  763. public function testOverrideGlobals()
  764. {
  765. $request = new Request();
  766. $request->initialize(array('foo' => 'bar'));
  767. // as the Request::overrideGlobals really work, it erase $_SERVER, so we must backup it
  768. $server = $_SERVER;
  769. $request->overrideGlobals();
  770. $this->assertEquals(array('foo' => 'bar'), $_GET);
  771. $request->initialize(array(), array('foo' => 'bar'));
  772. $request->overrideGlobals();
  773. $this->assertEquals(array('foo' => 'bar'), $_POST);
  774. $this->assertArrayNotHasKey('HTTP_X_FORWARDED_PROTO', $_SERVER);
  775. $request->headers->set('X_FORWARDED_PROTO', 'https');
  776. Request::setTrustedProxies(array('1.1.1.1'));
  777. $this->assertTrue($request->isSecure());
  778. Request::setTrustedProxies(array());
  779. $request->overrideGlobals();
  780. $this->assertArrayHasKey('HTTP_X_FORWARDED_PROTO', $_SERVER);
  781. // restore initial $_SERVER array
  782. $_SERVER = $server;
  783. }
  784. public function testGetScriptName()
  785. {
  786. $request = new Request();
  787. $this->assertEquals('', $request->getScriptName());
  788. $server = array();
  789. $server['SCRIPT_NAME'] = '/index.php';
  790. $request->initialize(array(), array(), array(), array(), array(), $server);
  791. $this->assertEquals('/index.php', $request->getScriptName());
  792. $server = array();
  793. $server['ORIG_SCRIPT_NAME'] = '/frontend.php';
  794. $request->initialize(array(), array(), array(), array(), array(), $server);
  795. $this->assertEquals('/frontend.php', $request->getScriptName());
  796. $server = array();
  797. $server['SCRIPT_NAME'] = '/index.php';
  798. $server['ORIG_SCRIPT_NAME'] = '/frontend.php';
  799. $request->initialize(array(), array(), array(), array(), array(), $server);
  800. $this->assertEquals('/index.php', $request->getScriptName());
  801. }
  802. public function testGetBasePath()
  803. {
  804. $request = new Request();
  805. $this->assertEquals('', $request->getBasePath());
  806. $server = array();
  807. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  808. $request->initialize(array(), array(), array(), array(), array(), $server);
  809. $this->assertEquals('', $request->getBasePath());
  810. $server = array();
  811. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  812. $server['SCRIPT_NAME'] = '/index.php';
  813. $request->initialize(array(), array(), array(), array(), array(), $server);
  814. $this->assertEquals('', $request->getBasePath());
  815. $server = array();
  816. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  817. $server['PHP_SELF'] = '/index.php';
  818. $request->initialize(array(), array(), array(), array(), array(), $server);
  819. $this->assertEquals('', $request->getBasePath());
  820. $server = array();
  821. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  822. $server['ORIG_SCRIPT_NAME'] = '/index.php';
  823. $request->initialize(array(), array(), array(), array(), array(), $server);
  824. $this->assertEquals('', $request->getBasePath());
  825. }
  826. public function testGetPathInfo()
  827. {
  828. $request = new Request();
  829. $this->assertEquals('/', $request->getPathInfo());
  830. $server = array();
  831. $server['REQUEST_URI'] = '/path/info';
  832. $request->initialize(array(), array(), array(), array(), array(), $server);
  833. $this->assertEquals('/path/info', $request->getPathInfo());
  834. $server = array();
  835. $server['REQUEST_URI'] = '/path%20test/info';
  836. $request->initialize(array(), array(), array(), array(), array(), $server);
  837. $this->assertEquals('/path%20test/info', $request->getPathInfo());
  838. }
  839. public function testGetPreferredLanguage()
  840. {
  841. $request = new Request();
  842. $this->assertNull($request->getPreferredLanguage());
  843. $this->assertNull($request->getPreferredLanguage(array()));
  844. $this->assertEquals('fr', $request->getPreferredLanguage(array('fr')));
  845. $this->assertEquals('fr', $request->getPreferredLanguage(array('fr', 'en')));
  846. $this->assertEquals('en', $request->getPreferredLanguage(array('en', 'fr')));
  847. $this->assertEquals('fr-ch', $request->getPreferredLanguage(array('fr-ch', 'fr-fr')));
  848. $request = new Request();
  849. $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
  850. $this->assertEquals('en', $request->getPreferredLanguage(array('en', 'en-us')));
  851. $request = new Request();
  852. $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
  853. $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));
  854. $request = new Request();
  855. $request->headers->set('Accept-language', 'zh, en-us; q=0.8');
  856. $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));
  857. $request = new Request();
  858. $request->headers->set('Accept-language', 'zh, en-us; q=0.8, fr-fr; q=0.6, fr; q=0.5');
  859. $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));
  860. }
  861. public function testIsXmlHttpRequest()
  862. {
  863. $request = new Request();
  864. $this->assertFalse($request->isXmlHttpRequest());
  865. $request->headers->set('X-Requested-With', 'XMLHttpRequest');
  866. $this->assertTrue($request->isXmlHttpRequest());
  867. $request->headers->remove('X-Requested-With');
  868. $this->assertFalse($request->isXmlHttpRequest());
  869. }
  870. public function testIntlLocale()
  871. {
  872. if (!extension_loaded('intl')) {
  873. $this->markTestSkipped('The intl extension is needed to run this test.');
  874. }
  875. $request = new Request();
  876. $request->setDefaultLocale('fr');
  877. $this->assertEquals('fr', $request->getLocale());
  878. $this->assertEquals('fr', \Locale::getDefault());
  879. $request->setLocale('en');
  880. $this->assertEquals('en', $request->getLocale());
  881. $this->assertEquals('en', \Locale::getDefault());
  882. $request->setDefaultLocale('de');
  883. $this->assertEquals('en', $request->getLocale());
  884. $this->assertEquals('en', \Locale::getDefault());
  885. }
  886. public function testGetCharsets()
  887. {
  888. $request = new Request();
  889. $this->assertEquals(array(), $request->getCharsets());
  890. $request->headers->set('Accept-Charset', 'ISO-8859-1, US-ASCII, UTF-8; q=0.8, ISO-10646-UCS-2; q=0.6');
  891. $this->assertEquals(array(), $request->getCharsets()); // testing caching
  892. $request = new Request();
  893. $request->headers->set('Accept-Charset', 'ISO-8859-1, US-ASCII, UTF-8; q=0.8, ISO-10646-UCS-2; q=0.6');
  894. $this->assertEquals(array('ISO-8859-1', 'US-ASCII', 'UTF-8', 'ISO-10646-UCS-2'), $request->getCharsets());
  895. $request = new Request();
  896. $request->headers->set('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7');
  897. $this->assertEquals(array('ISO-8859-1', 'utf-8', '*'), $request->getCharsets());
  898. }
  899. public function testGetAcceptableContentTypes()
  900. {
  901. $request = new Request();
  902. $this->assertEquals(array(), $request->getAcceptableContentTypes());
  903. $request->headers->set('Accept', 'application/vnd.wap.wmlscriptc, text/vnd.wap.wml, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html, multipart/mixed, */*');
  904. $this->assertEquals(array(), $request->getAcceptableContentTypes()); // testing caching
  905. $request = new Request();
  906. $request->headers->set('Accept', 'application/vnd.wap.wmlscriptc, text/vnd.wap.wml, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html, multipart/mixed, */*');
  907. $this->assertEquals(array('application/vnd.wap.wmlscriptc', 'text/vnd.wap.wml', 'application/vnd.wap.xhtml+xml', 'application/xhtml+xml', 'text/html', 'multipart/mixed', '*/*'), $request->getAcceptableContentTypes());
  908. }
  909. public function testGetLanguages()
  910. {
  911. $request = new Request();
  912. $this->assertEquals(array(), $request->getLanguages());
  913. $request = new Request();
  914. $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
  915. $this->assertEquals(array('zh', 'en_US', 'en'), $request->getLanguages());
  916. $this->assertEquals(array('zh', 'en_US', 'en'), $request->getLanguages());
  917. $request = new Request();
  918. $request->headers->set('Accept-language', 'zh, en-us; q=0.6, en; q=0.8');
  919. $this->assertEquals(array('zh', 'en', 'en_US'), $request->getLanguages()); // Test out of order qvalues
  920. $request = new Request();
  921. $request->headers->set('Accept-language', 'zh, en, en-us');
  922. $this->assertEquals(array('zh', 'en', 'en_US'), $request->getLanguages()); // Test equal weighting without qvalues
  923. $request = new Request();
  924. $request->headers->set('Accept-language', 'zh; q=0.6, en, en-us; q=0.6');
  925. $this->assertEquals(array('en', 'zh', 'en_US'), $request->getLanguages()); // Test equal weighting with qvalues
  926. $request = new Request();
  927. $request->headers->set('Accept-language', 'zh, i-cherokee; q=0.6');
  928. $this->assertEquals(array('zh', 'cherokee'), $request->getLanguages());
  929. }
  930. public function testGetRequestFormat()
  931. {
  932. $request = new Request();
  933. $this->assertEquals('html', $request->getRequestFormat());
  934. $request = new Request();
  935. $this->assertNull($request->getRequestFormat(null));
  936. $request = new Request();
  937. $this->assertNull($request->setRequestFormat('foo'));
  938. $this->assertEquals('foo', $request->getRequestFormat(null));
  939. }
  940. public function testHasSession()
  941. {
  942. $request = new Request();
  943. $this->assertFalse($request->hasSession());
  944. $request->setSession(new Session(new MockArraySessionStorage()));
  945. $this->assertTrue($request->hasSession());
  946. }
  947. public function testGetSession()
  948. {
  949. $request = new Request();
  950. $request->setSession(new Session(new MockArraySessionStorage()));
  951. $this->assertTrue($request->hasSession());
  952. $session = $request->getSession();
  953. $this->assertObjectHasAttribute('storage', $session);
  954. $this->assertObjectHasAttribute('flashName', $session);
  955. $this->assertObjectHasAttribute('attributeName', $session);
  956. }
  957. public function testHasPreviousSession()
  958. {
  959. $request = new Request();
  960. $this->assertFalse($request->hasPreviousSession());
  961. $request->cookies->set('MOCKSESSID', 'foo');
  962. $this->assertFalse($request->hasPreviousSession());
  963. $request->setSession(new Session(new MockArraySessionStorage()));
  964. $this->assertTrue($request->hasPreviousSession());
  965. }
  966. public function testToString()
  967. {
  968. $request = new Request();
  969. $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
  970. $this->assertContains('Accept-Language: zh, en-us; q=0.8, en; q=0.6', $request->__toString());
  971. }
  972. public function testIsMethod()
  973. {
  974. $request = new Request();
  975. $request->setMethod('POST');
  976. $this->assertTrue($request->isMethod('POST'));
  977. $this->assertTrue($request->isMethod('post'));
  978. $this->assertFalse($request->isMethod('GET'));
  979. $this->assertFalse($request->isMethod('get'));
  980. $request->setMethod('GET');
  981. $this->assertTrue($request->isMethod('GET'));
  982. $this->assertTrue($request->isMethod('get'));
  983. $this->assertFalse($request->isMethod('POST'));
  984. $this->assertFalse($request->isMethod('post'));
  985. }
  986. /**
  987. * @dataProvider getBaseUrlData
  988. */
  989. public function testGetBaseUrl($uri, $server, $expectedBaseUrl, $expectedPathInfo)
  990. {
  991. $request = Request::create($uri, 'GET', array(), array(), array(), $server);
  992. $this->assertSame($expectedBaseUrl, $request->getBaseUrl(), 'baseUrl');
  993. $this->assertSame($expectedPathInfo, $request->getPathInfo(), 'pathInfo');
  994. }
  995. public function getBaseUrlData()
  996. {
  997. return array(
  998. array(
  999. '/foo%20bar',
  1000. array(
  1001. 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
  1002. 'SCRIPT_NAME' => '/foo bar/app.php',
  1003. 'PHP_SELF' => '/foo bar/app.php',
  1004. ),
  1005. '/foo%20bar',
  1006. '/',
  1007. ),
  1008. array(
  1009. '/foo%20bar/home',
  1010. array(
  1011. 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
  1012. 'SCRIPT_NAME' => '/foo bar/app.php',
  1013. 'PHP_SELF' => '/foo bar/app.php',
  1014. ),
  1015. '/foo%20bar',
  1016. '/home',
  1017. ),
  1018. array(
  1019. '/foo%20bar/app.php/home',
  1020. array(
  1021. 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
  1022. 'SCRIPT_NAME' => '/foo bar/app.php',
  1023. 'PHP_SELF' => '/foo bar/app.php',
  1024. ),
  1025. '/foo%20bar/app.php',
  1026. '/home',
  1027. ),
  1028. array(
  1029. '/foo%20bar/app.php/home%3Dbaz',
  1030. array(
  1031. 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
  1032. 'SCRIPT_NAME' => '/foo bar/app.php',
  1033. 'PHP_SELF' => '/foo bar/app.php',
  1034. ),
  1035. '/foo%20bar/app.php',
  1036. '/home%3Dbaz',
  1037. ),
  1038. array(
  1039. '/foo/bar+baz',
  1040. array(
  1041. 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo/app.php',
  1042. 'SCRIPT_NAME' => '/foo/app.php',
  1043. 'PHP_SELF' => '/foo/app.php',
  1044. ),
  1045. '/foo',
  1046. '/bar+baz',
  1047. ),
  1048. );
  1049. }
  1050. /**
  1051. * @dataProvider urlencodedStringPrefixData
  1052. */
  1053. public function testUrlencodedStringPrefix($string, $prefix, $expect)
  1054. {
  1055. $request = new Request;
  1056. $me = new \ReflectionMethod($request, 'getUrlencodedPrefix');
  1057. $me->setAccessible(true);
  1058. $this->assertSame($expect, $me->invoke($request, $string, $prefix));
  1059. }
  1060. public function urlencodedStringPrefixData()
  1061. {
  1062. return array(
  1063. array('foo', 'foo', 'foo'),
  1064. array('fo%6f', 'foo', 'fo%6f'),
  1065. array('foo/bar', 'foo', 'foo'),
  1066. array('fo%6f/bar', 'foo', 'fo%6f'),
  1067. array('f%6f%6f/bar', 'foo', 'f%6f%6f'),
  1068. array('%66%6F%6F/bar', 'foo', '%66%6F%6F'),
  1069. array('fo+o/bar', 'fo+o', 'fo+o'),
  1070. array('fo%2Bo/bar', 'fo+o', 'fo%2Bo'),
  1071. );
  1072. }
  1073. private function disableHttpMethodParameterOverride()
  1074. {
  1075. $class = new \ReflectionClass('Symfony\\Component\\HttpFoundation\\Request');
  1076. $property = $class->getProperty('httpMethodParameterOverride');
  1077. $property->setAccessible(true);
  1078. $property->setValue(false);
  1079. }
  1080. private function getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies)
  1081. {
  1082. $request = new Request();
  1083. $server = array('REMOTE_ADDR' => $remoteAddr);
  1084. if (null !== $httpForwardedFor) {
  1085. $server['HTTP_X_FORWARDED_FOR'] = $httpForwardedFor;
  1086. }
  1087. if ($trustedProxies) {
  1088. Request::setTrustedProxies($trustedProxies);
  1089. }
  1090. $request->initialize(array(), array(), array(), array(), array(), $server);
  1091. return $request;
  1092. }
  1093. public function testTrustedProxies()
  1094. {
  1095. $request = Request::create('http://example.com/');
  1096. $request->server->set('REMOTE_ADDR', '3.3.3.3');
  1097. $request->headers->set('X_FORWARDED_FOR', '1.1.1.1, 2.2.2.2');
  1098. $request->headers->set('X_FORWARDED_HOST', 'foo.example.com, real.example.com:8080');
  1099. $request->headers->set('X_FORWARDED_PROTO', 'https');
  1100. $request->headers->set('X_FORWARDED_PORT', 443);
  1101. $request->headers->set('X_MY_FOR', '3.3.3.3, 4.4.4.4');
  1102. $request->headers->set('X_MY_HOST', 'my.example.com');
  1103. $request->headers->set('X_MY_PROTO', 'http');
  1104. $request->headers->set('X_MY_PORT', 81);
  1105. // no trusted proxies
  1106. $this->assertEquals('3.3.3.3', $request->getClientIp());
  1107. $this->assertEquals('example.com', $request->getHost());
  1108. $this->assertEquals(80, $request->getPort());
  1109. $this->assertFalse($request->isSecure());
  1110. // disabling proxy trusting
  1111. Request::setTrustedProxies(array());
  1112. $this->assertEquals('3.3.3.3', $request->getClientIp());
  1113. $this->assertEquals('example.com', $request->getHost());
  1114. $this->assertEquals(80, $request->getPort());
  1115. $this->assertFalse($request->isSecure());
  1116. // trusted proxy via setTrustedProxies()
  1117. Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'));
  1118. $this->assertEquals('1.1.1.1', $request->getClientIp());
  1119. $this->assertEquals('real.example.com', $request->getHost());
  1120. $this->assertEquals(443, $request->getPort());
  1121. $this->assertTrue($request->isSecure());
  1122. // custom header names
  1123. Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_MY_FOR');
  1124. Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_MY_HOST');
  1125. Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_MY_PORT');
  1126. Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_MY_PROTO');
  1127. $this->assertEquals('4.4.4.4', $request->getClientIp());
  1128. $this->assertEquals('my.example.com', $request->getHost());
  1129. $this->assertEquals(81, $request->getPort());
  1130. $this->assertFalse($request->isSecure());
  1131. // disabling via empty header names
  1132. Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, null);
  1133. Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, null);
  1134. Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, null);
  1135. Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, null);
  1136. $this->assertEquals('3.3.3.3', $request->getClientIp());
  1137. $this->assertEquals('example.com', $request->getHost());
  1138. $this->assertEquals(80, $request->getPort());
  1139. $this->assertFalse($request->isSecure());
  1140. // reset
  1141. Request::setTrustedProxies(array());
  1142. Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_FORWARDED_FOR');
  1143. Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_FORWARDED_HOST');
  1144. Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_FORWARDED_PORT');
  1145. Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_FORWARDED_PROTO');
  1146. }
  1147. /**
  1148. * @dataProvider iisRequestUriProvider
  1149. */
  1150. public function testIISRequestUri($headers, $server, $expectedRequestUri)
  1151. {
  1152. $request = new Request();
  1153. $request->headers->replace($headers);
  1154. $request->server->replace($server);
  1155. $this->assertEquals($expectedRequestUri, $request->getRequestUri(), '->getRequestUri() is correct');
  1156. $subRequestUri = '/bar/foo';
  1157. $subRequest = $request::create($subRequestUri, 'get', array(), array(), array(), $request->server->all());
  1158. $this->assertEquals($subRequestUri, $subRequest->getRequestUri(), '->getRequestUri() is correct in sub request');
  1159. }
  1160. public function iisRequestUriProvider()
  1161. {
  1162. return array(
  1163. array(
  1164. array(
  1165. 'X_ORIGINAL_URL' => '/foo/bar',
  1166. ),
  1167. array(),
  1168. '/foo/bar'
  1169. ),
  1170. array(
  1171. array(
  1172. 'X_REWRITE_URL' => '/foo/bar',
  1173. ),
  1174. array(),
  1175. '/foo/bar'
  1176. ),
  1177. array(
  1178. array(),
  1179. array(
  1180. 'IIS_WasUrlRewritten' => '1',
  1181. 'UNENCODED_URL' => '/foo/bar'
  1182. ),
  1183. '/foo/bar'
  1184. ),
  1185. array(
  1186. array(
  1187. 'X_ORIGINAL_URL' => '/foo/bar',
  1188. ),
  1189. array(
  1190. 'HTTP_X_ORIGINAL_URL' => '/foo/bar'
  1191. ),
  1192. '/foo/bar'
  1193. ),
  1194. array(
  1195. array(
  1196. 'X_ORIGINAL_URL' => '/foo/bar',
  1197. ),
  1198. array(
  1199. 'IIS_WasUrlRewritten' => '1',
  1200. 'UNENCODED_URL' => '/foo/bar'
  1201. ),
  1202. '/foo/bar'
  1203. ),
  1204. array(
  1205. array(
  1206. 'X_ORIGINAL_URL' => '/foo/bar',
  1207. ),
  1208. array(
  1209. 'HTTP_X_ORIGINAL_URL' => '/foo/bar',
  1210. 'IIS_WasUrlRewritten' => '1',
  1211. 'UNENCODED_URL' => '/foo/bar'
  1212. ),
  1213. '/foo/bar'
  1214. ),
  1215. array(
  1216. array(),
  1217. array(
  1218. 'ORIG_PATH_INFO' => '/foo/bar',
  1219. ),
  1220. '/foo/bar'
  1221. ),
  1222. array(
  1223. array(),
  1224. array(
  1225. 'ORIG_PATH_INFO' => '/foo/bar',
  1226. 'QUERY_STRING' => 'foo=bar',
  1227. ),
  1228. '/foo/bar?foo=bar'
  1229. )
  1230. );
  1231. }
  1232. public function testTrustedHosts()
  1233. {
  1234. // create a request
  1235. $request = Request::create('/');
  1236. // no trusted host set -> no host check
  1237. $request->headers->set('host', 'evil.com');
  1238. $this->assertEquals('evil.com', $request->getHost());
  1239. // add a trusted domain and all its subdomains
  1240. Request::setTrustedHosts(array('.*\.?trusted.com$'));
  1241. // untrusted host
  1242. $request->headers->set('host', 'evil.com');
  1243. try {
  1244. $request->getHost();
  1245. $this->fail('Request::getHost() should throw an exception when host is not trusted.');
  1246. } catch (\UnexpectedValueException $e) {
  1247. $this->assertEquals('Untrusted Host "evil.com"', $e->getMessage());
  1248. }
  1249. // trusted hosts
  1250. $request->headers->set('host', 'trusted.com');
  1251. $this->assertEquals('trusted.com', $request->getHost());
  1252. $request->headers->set('host', 'subdomain.trusted.com');
  1253. $this->assertEquals('subdomain.trusted.com', $request->getHost());
  1254. // reset request for following tests
  1255. Request::setTrustedHosts(array());
  1256. }
  1257. }
  1258. class RequestContentProxy extends Request
  1259. {
  1260. public function getContent($asResource = false)
  1261. {
  1262. return http_build_query(array('_method' => 'PUT', 'content' => 'mycontent'));
  1263. }
  1264. }