RequestTest.php 40KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929
  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\Tests\Component\HttpFoundation;
  11. use Symfony\Component\HttpFoundation\SessionStorage\ArraySessionStorage;
  12. use Symfony\Component\HttpFoundation\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. /**
  39. * @covers Symfony\Component\HttpFoundation\Request::create
  40. */
  41. public function testCreate()
  42. {
  43. $request = Request::create('http://test.com/foo?bar=baz');
  44. $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
  45. $this->assertEquals('/foo', $request->getPathInfo());
  46. $this->assertEquals('bar=baz', $request->getQueryString());
  47. $this->assertEquals(80, $request->getPort());
  48. $this->assertEquals('test.com', $request->getHttpHost());
  49. $this->assertFalse($request->isSecure());
  50. $request = Request::create('https://test.com/foo?bar=baz');
  51. $this->assertEquals('https://test.com/foo?bar=baz', $request->getUri());
  52. $this->assertEquals('/foo', $request->getPathInfo());
  53. $this->assertEquals('bar=baz', $request->getQueryString());
  54. $this->assertEquals(443, $request->getPort());
  55. $this->assertEquals('test.com', $request->getHttpHost());
  56. $this->assertTrue($request->isSecure());
  57. $request = Request::create('test.com:90/foo');
  58. $this->assertEquals('http://test.com:90/foo', $request->getUri());
  59. $this->assertEquals('/foo', $request->getPathInfo());
  60. $this->assertEquals('test.com', $request->getHost());
  61. $this->assertEquals('test.com:90', $request->getHttpHost());
  62. $this->assertEquals(90, $request->getPort());
  63. $this->assertFalse($request->isSecure());
  64. $request = Request::create('https://test.com:90/foo');
  65. $this->assertEquals('https://test.com:90/foo', $request->getUri());
  66. $this->assertEquals('/foo', $request->getPathInfo());
  67. $this->assertEquals('test.com', $request->getHost());
  68. $this->assertEquals('test.com:90', $request->getHttpHost());
  69. $this->assertEquals(90, $request->getPort());
  70. $this->assertTrue($request->isSecure());
  71. $request = Request::create('https://127.0.0.1:90/foo');
  72. $this->assertEquals('https://127.0.0.1:90/foo', $request->getUri());
  73. $this->assertEquals('/foo', $request->getPathInfo());
  74. $this->assertEquals('127.0.0.1', $request->getHost());
  75. $this->assertEquals('127.0.0.1:90', $request->getHttpHost());
  76. $this->assertEquals(90, $request->getPort());
  77. $this->assertTrue($request->isSecure());
  78. $request = Request::create('https://[::1]:90/foo');
  79. $this->assertEquals('https://[::1]:90/foo', $request->getUri());
  80. $this->assertEquals('/foo', $request->getPathInfo());
  81. $this->assertEquals('[::1]', $request->getHost());
  82. $this->assertEquals('[::1]:90', $request->getHttpHost());
  83. $this->assertEquals(90, $request->getPort());
  84. $this->assertTrue($request->isSecure());
  85. $json = '{"jsonrpc":"2.0","method":"echo","id":7,"params":["Hello World"]}';
  86. $request = Request::create('http://example.com/jsonrpc', 'POST', array(), array(), array(), array(), $json);
  87. $this->assertEquals($json, $request->getContent());
  88. $this->assertFalse($request->isSecure());
  89. $request = Request::create('http://test.com');
  90. $this->assertEquals('http://test.com/', $request->getUri());
  91. $this->assertEquals('/', $request->getPathInfo());
  92. $this->assertEquals('', $request->getQueryString());
  93. $this->assertEquals(80, $request->getPort());
  94. $this->assertEquals('test.com', $request->getHttpHost());
  95. $this->assertFalse($request->isSecure());
  96. $request = Request::create('http://test.com:90/?test=1');
  97. $this->assertEquals('http://test.com:90/?test=1', $request->getUri());
  98. $this->assertEquals('/', $request->getPathInfo());
  99. $this->assertEquals('test=1', $request->getQueryString());
  100. $this->assertEquals(90, $request->getPort());
  101. $this->assertEquals('test.com:90', $request->getHttpHost());
  102. $this->assertFalse($request->isSecure());
  103. }
  104. /**
  105. * @covers Symfony\Component\HttpFoundation\Request::duplicate
  106. */
  107. public function testDuplicate()
  108. {
  109. $request = new Request(array('foo' => 'bar'), array('foo' => 'bar'), array('foo' => 'bar'), array(), array(), array('HTTP_FOO' => 'bar'));
  110. $dup = $request->duplicate();
  111. $this->assertEquals($request->query->all(), $dup->query->all(), '->duplicate() duplicates a request an copy the current query parameters');
  112. $this->assertEquals($request->request->all(), $dup->request->all(), '->duplicate() duplicates a request an copy the current request parameters');
  113. $this->assertEquals($request->attributes->all(), $dup->attributes->all(), '->duplicate() duplicates a request an copy the current attributes');
  114. $this->assertEquals($request->headers->all(), $dup->headers->all(), '->duplicate() duplicates a request an copy the current HTTP headers');
  115. $dup = $request->duplicate(array('foo' => 'foobar'), array('foo' => 'foobar'), array('foo' => 'foobar'), array(), array(), array('HTTP_FOO' => 'foobar'));
  116. $this->assertEquals(array('foo' => 'foobar'), $dup->query->all(), '->duplicate() overrides the query parameters if provided');
  117. $this->assertEquals(array('foo' => 'foobar'), $dup->request->all(), '->duplicate() overrides the request parameters if provided');
  118. $this->assertEquals(array('foo' => 'foobar'), $dup->attributes->all(), '->duplicate() overrides the attributes if provided');
  119. $this->assertEquals(array('foo' => array('foobar')), $dup->headers->all(), '->duplicate() overrides the HTTP header if provided');
  120. }
  121. /**
  122. * @covers Symfony\Component\HttpFoundation\Request::getFormat
  123. * @covers Symfony\Component\HttpFoundation\Request::setFormat
  124. * @dataProvider getFormatToMimeTypeMapProvider
  125. */
  126. public function testGetFormatFromMimeType($format, $mimeTypes)
  127. {
  128. $request = new Request();
  129. foreach ($mimeTypes as $mime) {
  130. $this->assertEquals($format, $request->getFormat($mime));
  131. }
  132. $request->setFormat($format, $mimeTypes);
  133. foreach ($mimeTypes as $mime) {
  134. $this->assertEquals($format, $request->getFormat($mime));
  135. }
  136. }
  137. /**
  138. * @covers Symfony\Component\HttpFoundation\Request::getFormat
  139. */
  140. public function testGetFormatFromMimeTypeWithParameters()
  141. {
  142. $request = new Request();
  143. $this->assertEquals('json', $request->getFormat('application/json; charset=utf-8'));
  144. }
  145. /**
  146. * @covers Symfony\Component\HttpFoundation\Request::getMimeType
  147. * @dataProvider getFormatToMimeTypeMapProvider
  148. */
  149. public function testGetMimeTypeFromFormat($format, $mimeTypes)
  150. {
  151. if (null !== $format) {
  152. $request = new Request();
  153. $this->assertEquals($mimeTypes[0], $request->getMimeType($format));
  154. }
  155. }
  156. public function getFormatToMimeTypeMapProvider()
  157. {
  158. return array(
  159. array(null, array(null, 'unexistent-mime-type')),
  160. array('txt', array('text/plain')),
  161. array('js', array('application/javascript', 'application/x-javascript', 'text/javascript')),
  162. array('css', array('text/css')),
  163. array('json', array('application/json', 'application/x-json')),
  164. array('xml', array('text/xml', 'application/xml', 'application/x-xml')),
  165. array('rdf', array('application/rdf+xml')),
  166. array('atom',array('application/atom+xml')),
  167. );
  168. }
  169. /**
  170. * @covers Symfony\Component\HttpFoundation\Request::getUri
  171. */
  172. public function testGetUri()
  173. {
  174. $server = array();
  175. // Standard Request on non default PORT
  176. // http://hostname:8080/index.php/path/info?query=string
  177. $server['HTTP_HOST'] = 'hostname:8080';
  178. $server['SERVER_NAME'] = 'servername';
  179. $server['SERVER_PORT'] = '8080';
  180. $server['QUERY_STRING'] = 'query=string';
  181. $server['REQUEST_URI'] = '/index.php/path/info?query=string';
  182. $server['SCRIPT_NAME'] = '/index.php';
  183. $server['PATH_INFO'] = '/path/info';
  184. $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
  185. $server['PHP_SELF'] = '/index_dev.php/path/info';
  186. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  187. $request = new Request();
  188. $request->initialize(array(), array(), array(), array(), array(), $server);
  189. $this->assertEquals('http://hostname:8080/index.php/path/info?query=string', $request->getUri(), '->getUri() with non default port');
  190. // Use std port number
  191. $server['HTTP_HOST'] = 'hostname';
  192. $server['SERVER_NAME'] = 'servername';
  193. $server['SERVER_PORT'] = '80';
  194. $request->initialize(array(), array(), array(), array(), array(), $server);
  195. $this->assertEquals('http://hostname/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port');
  196. // Without HOST HEADER
  197. unset($server['HTTP_HOST']);
  198. $server['SERVER_NAME'] = 'servername';
  199. $server['SERVER_PORT'] = '80';
  200. $request->initialize(array(), array(), array(), array(), array(), $server);
  201. $this->assertEquals('http://servername/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port without HOST_HEADER');
  202. // Request with URL REWRITING (hide index.php)
  203. // RewriteCond %{REQUEST_FILENAME} !-f
  204. // RewriteRule ^(.*)$ index.php [QSA,L]
  205. // http://hostname:8080/path/info?query=string
  206. $server = array();
  207. $server['HTTP_HOST'] = 'hostname:8080';
  208. $server['SERVER_NAME'] = 'servername';
  209. $server['SERVER_PORT'] = '8080';
  210. $server['REDIRECT_QUERY_STRING'] = 'query=string';
  211. $server['REDIRECT_URL'] = '/path/info';
  212. $server['SCRIPT_NAME'] = '/index.php';
  213. $server['QUERY_STRING'] = 'query=string';
  214. $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
  215. $server['SCRIPT_NAME'] = '/index.php';
  216. $server['PHP_SELF'] = '/index.php';
  217. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  218. $request->initialize(array(), array(), array(), array(), array(), $server);
  219. $this->assertEquals('http://hostname:8080/path/info?query=string', $request->getUri(), '->getUri() with rewrite');
  220. // Use std port number
  221. // http://hostname/path/info?query=string
  222. $server['HTTP_HOST'] = 'hostname';
  223. $server['SERVER_NAME'] = 'servername';
  224. $server['SERVER_PORT'] = '80';
  225. $request->initialize(array(), array(), array(), array(), array(), $server);
  226. $this->assertEquals('http://hostname/path/info?query=string', $request->getUri(), '->getUri() with rewrite and default port');
  227. // Without HOST HEADER
  228. unset($server['HTTP_HOST']);
  229. $server['SERVER_NAME'] = 'servername';
  230. $server['SERVER_PORT'] = '80';
  231. $request->initialize(array(), array(), array(), array(), array(), $server);
  232. $this->assertEquals('http://servername/path/info?query=string', $request->getUri(), '->getUri() with rewrite, default port without HOST_HEADER');
  233. }
  234. /**
  235. * @covers Symfony\Component\HttpFoundation\Request::getUriForPath
  236. */
  237. public function testGetUriForPath()
  238. {
  239. $request = Request::create('http://test.com/foo?bar=baz');
  240. $this->assertEquals('http://test.com/some/path', $request->getUriForPath('/some/path'));
  241. $request = Request::create('http://test.com:90/foo?bar=baz');
  242. $this->assertEquals('http://test.com:90/some/path', $request->getUriForPath('/some/path'));
  243. $request = Request::create('https://test.com/foo?bar=baz');
  244. $this->assertEquals('https://test.com/some/path', $request->getUriForPath('/some/path'));
  245. $request = Request::create('https://test.com:90/foo?bar=baz');
  246. $this->assertEquals('https://test.com:90/some/path', $request->getUriForPath('/some/path'));
  247. $server = array();
  248. // Standard Request on non default PORT
  249. // http://hostname:8080/index.php/path/info?query=string
  250. $server['HTTP_HOST'] = 'hostname:8080';
  251. $server['SERVER_NAME'] = 'servername';
  252. $server['SERVER_PORT'] = '8080';
  253. $server['QUERY_STRING'] = 'query=string';
  254. $server['REQUEST_URI'] = '/index.php/path/info?query=string';
  255. $server['SCRIPT_NAME'] = '/index.php';
  256. $server['PATH_INFO'] = '/path/info';
  257. $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
  258. $server['PHP_SELF'] = '/index_dev.php/path/info';
  259. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  260. $request = new Request();
  261. $request->initialize(array(), array(), array(), array(), array(),$server);
  262. $this->assertEquals('http://hostname:8080/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with non default port');
  263. // Use std port number
  264. $server['HTTP_HOST'] = 'hostname';
  265. $server['SERVER_NAME'] = 'servername';
  266. $server['SERVER_PORT'] = '80';
  267. $request->initialize(array(), array(), array(), array(), array(), $server);
  268. $this->assertEquals('http://hostname/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port');
  269. // Without HOST HEADER
  270. unset($server['HTTP_HOST']);
  271. $server['SERVER_NAME'] = 'servername';
  272. $server['SERVER_PORT'] = '80';
  273. $request->initialize(array(), array(), array(), array(), array(), $server);
  274. $this->assertEquals('http://servername/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port without HOST_HEADER');
  275. // Request with URL REWRITING (hide index.php)
  276. // RewriteCond %{REQUEST_FILENAME} !-f
  277. // RewriteRule ^(.*)$ index.php [QSA,L]
  278. // http://hostname:8080/path/info?query=string
  279. $server = array();
  280. $server['HTTP_HOST'] = 'hostname:8080';
  281. $server['SERVER_NAME'] = 'servername';
  282. $server['SERVER_PORT'] = '8080';
  283. $server['REDIRECT_QUERY_STRING'] = 'query=string';
  284. $server['REDIRECT_URL'] = '/path/info';
  285. $server['SCRIPT_NAME'] = '/index.php';
  286. $server['QUERY_STRING'] = 'query=string';
  287. $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
  288. $server['SCRIPT_NAME'] = '/index.php';
  289. $server['PHP_SELF'] = '/index.php';
  290. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  291. $request->initialize(array(), array(), array(), array(), array(), $server);
  292. $this->assertEquals('http://hostname:8080/some/path', $request->getUriForPath('/some/path'), '->getUri() with rewrite');
  293. // Use std port number
  294. // http://hostname/path/info?query=string
  295. $server['HTTP_HOST'] = 'hostname';
  296. $server['SERVER_NAME'] = 'servername';
  297. $server['SERVER_PORT'] = '80';
  298. $request->initialize(array(), array(), array(), array(), array(), $server);
  299. $this->assertEquals('http://hostname/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite and default port');
  300. // Without HOST HEADER
  301. unset($server['HTTP_HOST']);
  302. $server['SERVER_NAME'] = 'servername';
  303. $server['SERVER_PORT'] = '80';
  304. $request->initialize(array(), array(), array(), array(), array(), $server);
  305. $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite, default port without HOST_HEADER');
  306. $this->assertEquals('servername', $request->getHttpHost());
  307. }
  308. /**
  309. * @covers Symfony\Component\HttpFoundation\Request::getQueryString
  310. */
  311. public function testGetQueryString()
  312. {
  313. $request = new Request();
  314. $request->server->set('QUERY_STRING', 'foo');
  315. $this->assertEquals('foo', $request->getQueryString(), '->getQueryString() works with valueless parameters');
  316. $request->server->set('QUERY_STRING', 'foo=');
  317. $this->assertEquals('foo=', $request->getQueryString(), '->getQueryString() includes a dangling equal sign');
  318. $request->server->set('QUERY_STRING', 'bar=&foo=bar');
  319. $this->assertEquals('bar=&foo=bar', $request->getQueryString(), '->getQueryString() works when empty parameters');
  320. $request->server->set('QUERY_STRING', 'foo=bar&bar=');
  321. $this->assertEquals('bar=&foo=bar', $request->getQueryString(), '->getQueryString() sorts keys alphabetically');
  322. $request->server->set('QUERY_STRING', 'him=John%20Doe&her=Jane+Doe');
  323. $this->assertEquals('her=Jane%2BDoe&him=John%20Doe', $request->getQueryString(), '->getQueryString() normalizes encoding');
  324. $request->server->set('QUERY_STRING', 'foo[]=1&foo[]=2');
  325. $this->assertEquals('foo%5B%5D=1&foo%5B%5D=2', $request->getQueryString(), '->getQueryString() allows array notation');
  326. $request->server->set('QUERY_STRING', 'foo=1&foo=2');
  327. $this->assertEquals('foo=1&foo=2', $request->getQueryString(), '->getQueryString() allows repeated parameters');
  328. }
  329. public function testGetHost()
  330. {
  331. $request = new Request();
  332. $request->initialize(array('foo' => 'bar'));
  333. $this->assertEquals('', $request->getHost(), '->getHost() return empty string if not initialized');
  334. $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.exemple.com'));
  335. $this->assertEquals('www.exemple.com', $request->getHost(), '->getHost() from Host Header');
  336. // Host header with port number
  337. $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.exemple.com:8080'));
  338. $this->assertEquals('www.exemple.com', $request->getHost(), '->getHost() from Host Header with port number');
  339. // Server values
  340. $request->initialize(array(), array(), array(), array(), array(), array('SERVER_NAME' => 'www.exemple.com'));
  341. $this->assertEquals('www.exemple.com', $request->getHost(), '->getHost() from server name');
  342. $request->initialize(array(), array(), array(), array(), array(), array('SERVER_NAME' => 'www.exemple.com', 'HTTP_HOST' => 'www.host.com'));
  343. $this->assertEquals('www.host.com', $request->getHost(), '->getHost() value from Host header has priority over SERVER_NAME ');
  344. }
  345. /**
  346. * @expectedException RuntimeException
  347. */
  348. public function testGetHostWithFakeHttpHostValue()
  349. {
  350. $request = new Request();
  351. $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.host.com?query=string'));
  352. $request->getHost();
  353. }
  354. /**
  355. * @covers Symfony\Component\HttpFoundation\Request::setMethod
  356. * @covers Symfony\Component\HttpFoundation\Request::getMethod
  357. */
  358. public function testGetSetMethod()
  359. {
  360. $request = new Request();
  361. $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns GET if no method is defined');
  362. $request->setMethod('get');
  363. $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns an uppercased string');
  364. $request->setMethod('PURGE');
  365. $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method even if it is not a standard one');
  366. $request->setMethod('POST');
  367. $this->assertEquals('POST', $request->getMethod(), '->getMethod() returns the method POST if no _method is defined');
  368. $request->setMethod('POST');
  369. $request->request->set('_method', 'purge');
  370. $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method from _method if defined and POST');
  371. $request->setMethod('POST');
  372. $request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete');
  373. $this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override even though _method is set if defined and POST');
  374. $request = new Request();
  375. $request->setMethod('POST');
  376. $request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete');
  377. $this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override if defined and POST');
  378. }
  379. /**
  380. * @dataProvider testGetClientIpProvider
  381. */
  382. public function testGetClientIp($expected, $proxy, $remoteAddr, $httpForwardedFor, $trustedProxies)
  383. {
  384. $request = new Request();
  385. $server = array('REMOTE_ADDR' => $remoteAddr);
  386. if (null !== $httpForwardedFor) {
  387. $server['HTTP_X_FORWARDED_FOR'] = $httpForwardedFor;
  388. }
  389. if ($proxy || $trustedProxies) {
  390. Request::setTrustedProxies(null === $trustedProxies ? array($remoteAddr) : $trustedProxies);
  391. }
  392. $request->initialize(array(), array(), array(), array(), array(), $server);
  393. $this->assertEquals($expected, $request->getClientIp($proxy));
  394. Request::setTrustedProxies(array());
  395. }
  396. public function testGetClientIpProvider()
  397. {
  398. return array(
  399. array('88.88.88.88', false, '88.88.88.88', null, null),
  400. array('127.0.0.1', false, '127.0.0.1', null, null),
  401. array('::1', false, '::1', null, null),
  402. array('127.0.0.1', false, '127.0.0.1', '88.88.88.88', null),
  403. array('88.88.88.88', true, '127.0.0.1', '88.88.88.88', null),
  404. array('2620:0:1cfe:face:b00c::3', true, '::1', '2620:0:1cfe:face:b00c::3', null),
  405. array('88.88.88.88', true, '123.45.67.89', '127.0.0.1, 87.65.43.21, 88.88.88.88', null),
  406. array('87.65.43.21', true, '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')),
  407. array('87.65.43.21', false, '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')),
  408. );
  409. }
  410. public function testGetContentWorksTwiceInDefaultMode()
  411. {
  412. $req = new Request;
  413. $this->assertEquals('', $req->getContent());
  414. $this->assertEquals('', $req->getContent());
  415. }
  416. public function testGetContentReturnsResource()
  417. {
  418. $req = new Request;
  419. $retval = $req->getContent(true);
  420. $this->assertInternalType('resource', $retval);
  421. $this->assertEquals("", fread($retval, 1));
  422. $this->assertTrue(feof($retval));
  423. }
  424. /**
  425. * @expectedException LogicException
  426. * @dataProvider getContentCantBeCalledTwiceWithResourcesProvider
  427. */
  428. public function testGetContentCantBeCalledTwiceWithResources($first, $second)
  429. {
  430. $req = new Request;
  431. $req->getContent($first);
  432. $req->getContent($second);
  433. }
  434. public function getContentCantBeCalledTwiceWithResourcesProvider()
  435. {
  436. return array(
  437. 'Resource then fetch' => array(true, false),
  438. 'Resource then resource' => array(true, true),
  439. 'Fetch then resource' => array(false, true),
  440. );
  441. }
  442. public function testCreateFromGlobals()
  443. {
  444. $_GET['foo1'] = 'bar1';
  445. $_POST['foo2'] = 'bar2';
  446. $_COOKIE['foo3'] = 'bar3';
  447. $_FILES['foo4'] = array('bar4');
  448. $_SERVER['foo5'] = 'bar5';
  449. $request = Request::createFromGlobals();
  450. $this->assertEquals('bar1', $request->query->get('foo1'), '::fromGlobals() uses values from $_GET');
  451. $this->assertEquals('bar2', $request->request->get('foo2'), '::fromGlobals() uses values from $_POST');
  452. $this->assertEquals('bar3', $request->cookies->get('foo3'), '::fromGlobals() uses values from $_COOKIE');
  453. $this->assertEquals(array('bar4'), $request->files->get('foo4'), '::fromGlobals() uses values from $_FILES');
  454. $this->assertEquals('bar5', $request->server->get('foo5'), '::fromGlobals() uses values from $_SERVER');
  455. unset($_GET['foo1'], $_POST['foo2'], $_COOKIE['foo3'], $_FILES['foo4'], $_SERVER['foo5']);
  456. $_SERVER['REQUEST_METHOD'] = 'PUT';
  457. $_SERVER['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
  458. $request = RequestContentProxy::createFromGlobals();
  459. $this->assertEquals('PUT', $request->getMethod());
  460. $this->assertEquals('mycontent', $request->request->get('content'));
  461. unset($_SERVER['REQUEST_METHOD'], $_SERVER['CONTENT_TYPE']);
  462. $_POST['_method'] = 'PUT';
  463. $_POST['foo6'] = 'bar6';
  464. $_SERVER['REQUEST_METHOD'] = 'POST';
  465. $request = Request::createFromGlobals();
  466. $this->assertEquals('PUT', $request->getMethod());
  467. $this->assertEquals('bar6', $request->request->get('foo6'));
  468. unset($_POST['_method'], $_POST['foo6'], $_SERVER['REQUEST_METHOD']);
  469. }
  470. public function testOverrideGlobals()
  471. {
  472. $request = new Request();
  473. $request->initialize(array('foo' => 'bar'));
  474. // as the Request::overrideGlobals really work, it erase $_SERVER, so we must backup it
  475. $server = $_SERVER;
  476. $request->overrideGlobals();
  477. $this->assertEquals(array('foo' => 'bar'), $_GET);
  478. $request->initialize(array(), array('foo' => 'bar'));
  479. $request->overrideGlobals();
  480. $this->assertEquals(array('foo' => 'bar'), $_POST);
  481. $this->assertArrayNotHasKey('HTTP_X_FORWARDED_PROTO', $_SERVER);
  482. $request->headers->set('X_FORWARDED_PROTO', 'https');
  483. Request::setTrustedProxies(array('1.1.1.1'));
  484. $this->assertTrue($request->isSecure());
  485. Request::setTrustedProxies(array());
  486. $request->overrideGlobals();
  487. $this->assertArrayHasKey('HTTP_X_FORWARDED_PROTO', $_SERVER);
  488. // restore initial $_SERVER array
  489. $_SERVER = $server;
  490. }
  491. public function testGetScriptName()
  492. {
  493. $request = new Request();
  494. $this->assertEquals('', $request->getScriptName());
  495. $server = array();
  496. $server['SCRIPT_NAME'] = '/index.php';
  497. $request->initialize(array(), array(), array(), array(), array(), $server);
  498. $this->assertEquals('/index.php', $request->getScriptName());
  499. $server = array();
  500. $server['ORIG_SCRIPT_NAME'] = '/frontend.php';
  501. $request->initialize(array(), array(), array(), array(), array(), $server);
  502. $this->assertEquals('/frontend.php', $request->getScriptName());
  503. $server = array();
  504. $server['SCRIPT_NAME'] = '/index.php';
  505. $server['ORIG_SCRIPT_NAME'] = '/frontend.php';
  506. $request->initialize(array(), array(), array(), array(), array(), $server);
  507. $this->assertEquals('/index.php', $request->getScriptName());
  508. }
  509. public function testGetBasePath()
  510. {
  511. $request = new Request();
  512. $this->assertEquals('', $request->getBasePath());
  513. $server = array();
  514. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  515. $request->initialize(array(), array(), array(), array(), array(), $server);
  516. $this->assertEquals('', $request->getBasePath());
  517. $server = array();
  518. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  519. $server['SCRIPT_NAME'] = '/index.php';
  520. $request->initialize(array(), array(), array(), array(), array(), $server);
  521. $this->assertEquals('', $request->getBasePath());
  522. $server = array();
  523. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  524. $server['PHP_SELF'] = '/index.php';
  525. $request->initialize(array(), array(), array(), array(), array(), $server);
  526. $this->assertEquals('', $request->getBasePath());
  527. $server = array();
  528. $server['SCRIPT_FILENAME'] = '/some/where/index.php';
  529. $server['ORIG_SCRIPT_NAME'] = '/index.php';
  530. $request->initialize(array(), array(), array(), array(), array(), $server);
  531. $this->assertEquals('', $request->getBasePath());
  532. }
  533. public function testGetPathInfo()
  534. {
  535. $request = new Request();
  536. $this->assertEquals('/', $request->getPathInfo());
  537. $server = array();
  538. $server['REQUEST_URI'] = '/path/info';
  539. $request->initialize(array(), array(), array(), array(), array(), $server);
  540. $this->assertEquals('/path/info', $request->getPathInfo());
  541. $server = array();
  542. $server['REQUEST_URI'] = '/path test/info';
  543. $request->initialize(array(), array(), array(), array(), array(), $server);
  544. $this->assertEquals('/path test/info', $request->getPathInfo());
  545. $server = array();
  546. $server['REQUEST_URI'] = '/path%20test/info';
  547. $request->initialize(array(), array(), array(), array(), array(), $server);
  548. $this->assertEquals('/path test/info', $request->getPathInfo());
  549. }
  550. public function testGetPreferredLanguage()
  551. {
  552. $request = new Request();
  553. $this->assertNull($request->getPreferredLanguage());
  554. $this->assertNull($request->getPreferredLanguage(array()));
  555. $this->assertEquals('fr', $request->getPreferredLanguage(array('fr')));
  556. $this->assertEquals('fr', $request->getPreferredLanguage(array('fr', 'en')));
  557. $this->assertEquals('en', $request->getPreferredLanguage(array('en', 'fr')));
  558. $this->assertEquals('fr-ch', $request->getPreferredLanguage(array('fr-ch', 'fr-fr')));
  559. $request = new Request();
  560. $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
  561. $this->assertEquals('en', $request->getPreferredLanguage(array('en', 'en-us')));
  562. $request = new Request();
  563. $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
  564. $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));
  565. }
  566. public function testIsXmlHttpRequest()
  567. {
  568. $request = new Request();
  569. $this->assertFalse($request->isXmlHttpRequest());
  570. $request->headers->set('X-Requested-With', 'XMLHttpRequest');
  571. $this->assertTrue($request->isXmlHttpRequest());
  572. $request->headers->remove('X-Requested-With');
  573. $this->assertFalse($request->isXmlHttpRequest());
  574. }
  575. public function testGetCharsets()
  576. {
  577. $request = new Request();
  578. $this->assertEquals(array(), $request->getCharsets());
  579. $request->headers->set('Accept-Charset', 'ISO-8859-1, US-ASCII, UTF-8; q=0.8, ISO-10646-UCS-2; q=0.6');
  580. $this->assertEquals(array(), $request->getCharsets()); // testing caching
  581. $request = new Request();
  582. $request->headers->set('Accept-Charset', 'ISO-8859-1, US-ASCII, UTF-8; q=0.8, ISO-10646-UCS-2; q=0.6');
  583. $this->assertEquals(array('ISO-8859-1', 'US-ASCII', 'UTF-8', 'ISO-10646-UCS-2'), $request->getCharsets());
  584. $request = new Request();
  585. $request->headers->set('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7');
  586. $this->assertEquals(array('ISO-8859-1', 'utf-8', '*'), $request->getCharsets());
  587. }
  588. public function testGetAcceptableContentTypes()
  589. {
  590. $request = new Request();
  591. $this->assertEquals(array(), $request->getAcceptableContentTypes());
  592. $request->headers->set('Accept', 'application/vnd.wap.wmlscriptc, text/vnd.wap.wml, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html, multipart/mixed, */*');
  593. $this->assertEquals(array(), $request->getAcceptableContentTypes()); // testing caching
  594. $request = new Request();
  595. $request->headers->set('Accept', 'application/vnd.wap.wmlscriptc, text/vnd.wap.wml, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html, multipart/mixed, */*');
  596. $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());
  597. }
  598. public function testGetLanguages()
  599. {
  600. $request = new Request();
  601. $this->assertEquals(array(), $request->getLanguages());
  602. $request = new Request();
  603. $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
  604. $this->assertEquals(array('zh', 'en_US', 'en'), $request->getLanguages());
  605. $this->assertEquals(array('zh', 'en_US', 'en'), $request->getLanguages());
  606. $request = new Request();
  607. $request->headers->set('Accept-language', 'zh, en-us; q=0.6, en; q=0.8');
  608. $this->assertEquals(array('zh', 'en', 'en_US'), $request->getLanguages()); // Test out of order qvalues
  609. $request = new Request();
  610. $request->headers->set('Accept-language', 'zh, en, en-us');
  611. $this->assertEquals(array('zh', 'en', 'en_US'), $request->getLanguages()); // Test equal weighting without qvalues
  612. $request = new Request();
  613. $request->headers->set('Accept-language', 'zh; q=0.6, en, en-us; q=0.6');
  614. $this->assertEquals(array('en', 'zh', 'en_US'), $request->getLanguages()); // Test equal weighting with qvalues
  615. $request = new Request();
  616. $request->headers->set('Accept-language', 'zh, i-cherokee; q=0.6');
  617. $this->assertEquals(array('zh', 'cherokee'), $request->getLanguages());
  618. }
  619. public function testGetRequestFormat()
  620. {
  621. $request = new Request();
  622. $this->assertEquals('html', $request->getRequestFormat());
  623. $request = new Request();
  624. $this->assertNull($request->getRequestFormat(null));
  625. $request = new Request();
  626. $request->setRequestFormat('foo');
  627. $this->assertEquals('foo', $request->getRequestFormat(null));
  628. }
  629. public function testHasSession()
  630. {
  631. $request = new Request;
  632. $this->assertFalse($request->hasSession());
  633. $request->setSession(new Session(new ArraySessionStorage()));
  634. $this->assertTrue($request->hasSession());
  635. }
  636. public function testHasPreviousSession()
  637. {
  638. $request = new Request;
  639. $this->assertFalse($request->hasPreviousSession());
  640. $request->cookies->set(session_name(), 'foo');
  641. $this->assertFalse($request->hasPreviousSession());
  642. $request->setSession(new Session(new ArraySessionStorage()));
  643. $this->assertTrue($request->hasPreviousSession());
  644. }
  645. public function testToString()
  646. {
  647. $request = new Request();
  648. $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
  649. $this->assertContains('Accept-Language: zh, en-us; q=0.8, en; q=0.6', $request->__toString());
  650. }
  651. /**
  652. * @dataProvider splitHttpAcceptHeaderData
  653. */
  654. public function testSplitHttpAcceptHeader($acceptHeader, $expected)
  655. {
  656. $request = new Request();
  657. $this->assertEquals($expected, $request->splitHttpAcceptHeader($acceptHeader));
  658. }
  659. public function splitHttpAcceptHeaderData()
  660. {
  661. return array(
  662. array(null, array()),
  663. array('text/html;q=0.8', array('text/html' => 0.8)),
  664. array('text/html;foo=bar;q=0.8 ', array('text/html;foo=bar' => 0.8)),
  665. array('text/html;charset=utf-8; q=0.8', array('text/html;charset=utf-8' => 0.8)),
  666. array('text/html,application/xml;q=0.9,*/*;charset=utf-8; q=0.8', array('text/html' => 1, 'application/xml' => 0.9, '*/*;charset=utf-8' => 0.8)),
  667. array('text/html,application/xhtml+xml;q=0.9,*/*;q=0.8; foo=bar', array('text/html' => 1, 'application/xhtml+xml' => 0.9, '*/*' => 0.8)),
  668. array('text/html,application/xhtml+xml;charset=utf-8;q=0.9; foo=bar,*/*', array('text/html' => 1, '*/*' => 1, 'application/xhtml+xml;charset=utf-8' => 0.9)),
  669. array('text/html,application/xhtml+xml', array('application/xhtml+xml' => 1, 'text/html' => 1)),
  670. );
  671. }
  672. public function testTrustedProxies()
  673. {
  674. $request = Request::create('http://example.com/');
  675. $request->server->set('REMOTE_ADDR', '3.3.3.3');
  676. $request->headers->set('X_FORWARDED_FOR', '1.1.1.1, 2.2.2.2');
  677. $request->headers->set('X_FORWARDED_HOST', 'foo.example.com, real.example.com:8080');
  678. $request->headers->set('X_FORWARDED_PROTO', 'https');
  679. $request->headers->set('X_FORWARDED_PORT', 443);
  680. $request->headers->set('X_MY_FOR', '3.3.3.3, 4.4.4.4');
  681. $request->headers->set('X_MY_HOST', 'my.example.com');
  682. $request->headers->set('X_MY_PROTO', 'http');
  683. $request->headers->set('X_MY_PORT', 81);
  684. // no trusted proxies
  685. $this->assertEquals('3.3.3.3', $request->getClientIp());
  686. $this->assertEquals('example.com', $request->getHost());
  687. $this->assertEquals(80, $request->getPort());
  688. $this->assertFalse($request->isSecure());
  689. // trusted proxy via deprecated trustProxyData()
  690. Request::trustProxyData();
  691. $this->assertEquals('2.2.2.2', $request->getClientIp());
  692. $this->assertEquals('real.example.com', $request->getHost());
  693. $this->assertEquals(443, $request->getPort());
  694. $this->assertTrue($request->isSecure());
  695. // disabling proxy trusting
  696. Request::setTrustedProxies(array());
  697. $this->assertEquals('3.3.3.3', $request->getClientIp());
  698. $this->assertEquals('example.com', $request->getHost());
  699. $this->assertEquals(80, $request->getPort());
  700. $this->assertFalse($request->isSecure());
  701. // trusted proxy via setTrustedProxies()
  702. Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'));
  703. $this->assertEquals('1.1.1.1', $request->getClientIp());
  704. $this->assertEquals('real.example.com', $request->getHost());
  705. $this->assertEquals(443, $request->getPort());
  706. $this->assertTrue($request->isSecure());
  707. // custom header names
  708. Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_MY_FOR');
  709. Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_MY_HOST');
  710. Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_MY_PORT');
  711. Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_MY_PROTO');
  712. $this->assertEquals('4.4.4.4', $request->getClientIp());
  713. $this->assertEquals('my.example.com', $request->getHost());
  714. $this->assertEquals(81, $request->getPort());
  715. $this->assertFalse($request->isSecure());
  716. // disabling via empty header names
  717. Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, null);
  718. Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, null);
  719. Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, null);
  720. Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, null);
  721. $this->assertEquals('3.3.3.3', $request->getClientIp());
  722. $this->assertEquals('example.com', $request->getHost());
  723. $this->assertEquals(80, $request->getPort());
  724. $this->assertFalse($request->isSecure());
  725. // reset
  726. Request::setTrustedProxies(array());
  727. }
  728. }
  729. class RequestContentProxy extends Request
  730. {
  731. public function getContent($asResource = false)
  732. {
  733. return http_build_query(array('_method' => 'PUT', 'content' => 'mycontent'));
  734. }
  735. }