RequestTest.php 37KB

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