4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\HttpFoundation\Tests;
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
16 use Symfony\Component\HttpFoundation\Request;
17 use Symfony\Component\HttpFoundation\Session\Session;
18 use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
20 class RequestTest extends TestCase
22 protected function tearDown()
24 Request::setTrustedProxies(array(), -1);
25 Request::setTrustedHosts(array());
28 public function testInitialize()
30 $request = new Request();
32 $request->initialize(array('foo' => 'bar'));
33 $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');
38 $request->initialize(array(), array(), array('foo' => 'bar'));
39 $this->assertEquals('bar', $request->attributes->get('foo'), '->initialize() takes an array of attributes as its third argument');
41 $request->initialize(array(), array(), array(), array(), array(), array('HTTP_FOO' => 'bar'));
42 $this->assertEquals('bar', $request->headers->get('FOO'), '->initialize() takes an array of HTTP headers as its sixth argument');
45 public function testGetLocale()
47 $request = new Request();
48 $request->setLocale('pl');
49 $locale = $request->getLocale();
50 $this->assertEquals('pl', $locale);
53 public function testGetUser()
55 $request = Request::create('http://user:password@test.com');
56 $user = $request->getUser();
58 $this->assertEquals('user', $user);
61 public function testGetPassword()
63 $request = Request::create('http://user:password@test.com');
64 $password = $request->getPassword();
66 $this->assertEquals('password', $password);
69 public function testIsNoCache()
71 $request = new Request();
72 $isNoCache = $request->isNoCache();
74 $this->assertFalse($isNoCache);
77 public function testGetContentType()
79 $request = new Request();
80 $contentType = $request->getContentType();
82 $this->assertNull($contentType);
85 public function testSetDefaultLocale()
87 $request = new Request();
88 $request->setDefaultLocale('pl');
89 $locale = $request->getLocale();
91 $this->assertEquals('pl', $locale);
94 public function testCreate()
96 $request = Request::create('http://test.com/foo?bar=baz');
97 $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
98 $this->assertEquals('/foo', $request->getPathInfo());
99 $this->assertEquals('bar=baz', $request->getQueryString());
100 $this->assertEquals(80, $request->getPort());
101 $this->assertEquals('test.com', $request->getHttpHost());
102 $this->assertFalse($request->isSecure());
104 $request = Request::create('http://test.com/foo', 'GET', array('bar' => 'baz'));
105 $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
106 $this->assertEquals('/foo', $request->getPathInfo());
107 $this->assertEquals('bar=baz', $request->getQueryString());
108 $this->assertEquals(80, $request->getPort());
109 $this->assertEquals('test.com', $request->getHttpHost());
110 $this->assertFalse($request->isSecure());
112 $request = Request::create('http://test.com/foo?bar=foo', 'GET', array('bar' => 'baz'));
113 $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
114 $this->assertEquals('/foo', $request->getPathInfo());
115 $this->assertEquals('bar=baz', $request->getQueryString());
116 $this->assertEquals(80, $request->getPort());
117 $this->assertEquals('test.com', $request->getHttpHost());
118 $this->assertFalse($request->isSecure());
120 $request = Request::create('https://test.com/foo?bar=baz');
121 $this->assertEquals('https://test.com/foo?bar=baz', $request->getUri());
122 $this->assertEquals('/foo', $request->getPathInfo());
123 $this->assertEquals('bar=baz', $request->getQueryString());
124 $this->assertEquals(443, $request->getPort());
125 $this->assertEquals('test.com', $request->getHttpHost());
126 $this->assertTrue($request->isSecure());
128 $request = Request::create('test.com:90/foo');
129 $this->assertEquals('http://test.com:90/foo', $request->getUri());
130 $this->assertEquals('/foo', $request->getPathInfo());
131 $this->assertEquals('test.com', $request->getHost());
132 $this->assertEquals('test.com:90', $request->getHttpHost());
133 $this->assertEquals(90, $request->getPort());
134 $this->assertFalse($request->isSecure());
136 $request = Request::create('https://test.com:90/foo');
137 $this->assertEquals('https://test.com:90/foo', $request->getUri());
138 $this->assertEquals('/foo', $request->getPathInfo());
139 $this->assertEquals('test.com', $request->getHost());
140 $this->assertEquals('test.com:90', $request->getHttpHost());
141 $this->assertEquals(90, $request->getPort());
142 $this->assertTrue($request->isSecure());
144 $request = Request::create('https://127.0.0.1:90/foo');
145 $this->assertEquals('https://127.0.0.1:90/foo', $request->getUri());
146 $this->assertEquals('/foo', $request->getPathInfo());
147 $this->assertEquals('127.0.0.1', $request->getHost());
148 $this->assertEquals('127.0.0.1:90', $request->getHttpHost());
149 $this->assertEquals(90, $request->getPort());
150 $this->assertTrue($request->isSecure());
152 $request = Request::create('https://[::1]:90/foo');
153 $this->assertEquals('https://[::1]:90/foo', $request->getUri());
154 $this->assertEquals('/foo', $request->getPathInfo());
155 $this->assertEquals('[::1]', $request->getHost());
156 $this->assertEquals('[::1]:90', $request->getHttpHost());
157 $this->assertEquals(90, $request->getPort());
158 $this->assertTrue($request->isSecure());
160 $request = Request::create('https://[::1]/foo');
161 $this->assertEquals('https://[::1]/foo', $request->getUri());
162 $this->assertEquals('/foo', $request->getPathInfo());
163 $this->assertEquals('[::1]', $request->getHost());
164 $this->assertEquals('[::1]', $request->getHttpHost());
165 $this->assertEquals(443, $request->getPort());
166 $this->assertTrue($request->isSecure());
168 $json = '{"jsonrpc":"2.0","method":"echo","id":7,"params":["Hello World"]}';
169 $request = Request::create('http://example.com/jsonrpc', 'POST', array(), array(), array(), array(), $json);
170 $this->assertEquals($json, $request->getContent());
171 $this->assertFalse($request->isSecure());
173 $request = Request::create('http://test.com');
174 $this->assertEquals('http://test.com/', $request->getUri());
175 $this->assertEquals('/', $request->getPathInfo());
176 $this->assertEquals('', $request->getQueryString());
177 $this->assertEquals(80, $request->getPort());
178 $this->assertEquals('test.com', $request->getHttpHost());
179 $this->assertFalse($request->isSecure());
181 $request = Request::create('http://test.com?test=1');
182 $this->assertEquals('http://test.com/?test=1', $request->getUri());
183 $this->assertEquals('/', $request->getPathInfo());
184 $this->assertEquals('test=1', $request->getQueryString());
185 $this->assertEquals(80, $request->getPort());
186 $this->assertEquals('test.com', $request->getHttpHost());
187 $this->assertFalse($request->isSecure());
189 $request = Request::create('http://test.com:90/?test=1');
190 $this->assertEquals('http://test.com:90/?test=1', $request->getUri());
191 $this->assertEquals('/', $request->getPathInfo());
192 $this->assertEquals('test=1', $request->getQueryString());
193 $this->assertEquals(90, $request->getPort());
194 $this->assertEquals('test.com:90', $request->getHttpHost());
195 $this->assertFalse($request->isSecure());
197 $request = Request::create('http://username:password@test.com');
198 $this->assertEquals('http://test.com/', $request->getUri());
199 $this->assertEquals('/', $request->getPathInfo());
200 $this->assertEquals('', $request->getQueryString());
201 $this->assertEquals(80, $request->getPort());
202 $this->assertEquals('test.com', $request->getHttpHost());
203 $this->assertEquals('username', $request->getUser());
204 $this->assertEquals('password', $request->getPassword());
205 $this->assertFalse($request->isSecure());
207 $request = Request::create('http://username@test.com');
208 $this->assertEquals('http://test.com/', $request->getUri());
209 $this->assertEquals('/', $request->getPathInfo());
210 $this->assertEquals('', $request->getQueryString());
211 $this->assertEquals(80, $request->getPort());
212 $this->assertEquals('test.com', $request->getHttpHost());
213 $this->assertEquals('username', $request->getUser());
214 $this->assertSame('', $request->getPassword());
215 $this->assertFalse($request->isSecure());
217 $request = Request::create('http://test.com/?foo');
218 $this->assertEquals('/?foo', $request->getRequestUri());
219 $this->assertEquals(array('foo' => ''), $request->query->all());
221 // assume rewrite rule: (.*) --> app/app.php; app/ is a symlink to a symfony web/ directory
222 $request = Request::create('http://test.com/apparthotel-1234', 'GET', array(), array(), array(),
224 'DOCUMENT_ROOT' => '/var/www/www.test.com',
225 'SCRIPT_FILENAME' => '/var/www/www.test.com/app/app.php',
226 'SCRIPT_NAME' => '/app/app.php',
227 'PHP_SELF' => '/app/app.php/apparthotel-1234',
229 $this->assertEquals('http://test.com/apparthotel-1234', $request->getUri());
230 $this->assertEquals('/apparthotel-1234', $request->getPathInfo());
231 $this->assertEquals('', $request->getQueryString());
232 $this->assertEquals(80, $request->getPort());
233 $this->assertEquals('test.com', $request->getHttpHost());
234 $this->assertFalse($request->isSecure());
237 public function testCreateCheckPrecedence()
239 // server is used by default
240 $request = Request::create('/', 'DELETE', array(), array(), array(), array(
241 'HTTP_HOST' => 'example.com',
243 'SERVER_PORT' => 443,
244 'PHP_AUTH_USER' => 'fabien',
245 'PHP_AUTH_PW' => 'pa$$',
246 'QUERY_STRING' => 'foo=bar',
247 'CONTENT_TYPE' => 'application/json',
249 $this->assertEquals('example.com', $request->getHost());
250 $this->assertEquals(443, $request->getPort());
251 $this->assertTrue($request->isSecure());
252 $this->assertEquals('fabien', $request->getUser());
253 $this->assertEquals('pa$$', $request->getPassword());
254 $this->assertEquals('', $request->getQueryString());
255 $this->assertEquals('application/json', $request->headers->get('CONTENT_TYPE'));
257 // URI has precedence over server
258 $request = Request::create('http://thomas:pokemon@example.net:8080/?foo=bar', 'GET', array(), array(), array(), array(
259 'HTTP_HOST' => 'example.com',
261 'SERVER_PORT' => 443,
263 $this->assertEquals('example.net', $request->getHost());
264 $this->assertEquals(8080, $request->getPort());
265 $this->assertFalse($request->isSecure());
266 $this->assertEquals('thomas', $request->getUser());
267 $this->assertEquals('pokemon', $request->getPassword());
268 $this->assertEquals('foo=bar', $request->getQueryString());
271 public function testDuplicate()
273 $request = new Request(array('foo' => 'bar'), array('foo' => 'bar'), array('foo' => 'bar'), array(), array(), array('HTTP_FOO' => 'bar'));
274 $dup = $request->duplicate();
276 $this->assertEquals($request->query->all(), $dup->query->all(), '->duplicate() duplicates a request an copy the current query parameters');
277 $this->assertEquals($request->request->all(), $dup->request->all(), '->duplicate() duplicates a request an copy the current request parameters');
278 $this->assertEquals($request->attributes->all(), $dup->attributes->all(), '->duplicate() duplicates a request an copy the current attributes');
279 $this->assertEquals($request->headers->all(), $dup->headers->all(), '->duplicate() duplicates a request an copy the current HTTP headers');
281 $dup = $request->duplicate(array('foo' => 'foobar'), array('foo' => 'foobar'), array('foo' => 'foobar'), array(), array(), array('HTTP_FOO' => 'foobar'));
283 $this->assertEquals(array('foo' => 'foobar'), $dup->query->all(), '->duplicate() overrides the query parameters if provided');
284 $this->assertEquals(array('foo' => 'foobar'), $dup->request->all(), '->duplicate() overrides the request parameters if provided');
285 $this->assertEquals(array('foo' => 'foobar'), $dup->attributes->all(), '->duplicate() overrides the attributes if provided');
286 $this->assertEquals(array('foo' => array('foobar')), $dup->headers->all(), '->duplicate() overrides the HTTP header if provided');
289 public function testDuplicateWithFormat()
291 $request = new Request(array(), array(), array('_format' => 'json'));
292 $dup = $request->duplicate();
294 $this->assertEquals('json', $dup->getRequestFormat());
295 $this->assertEquals('json', $dup->attributes->get('_format'));
297 $request = new Request();
298 $request->setRequestFormat('xml');
299 $dup = $request->duplicate();
301 $this->assertEquals('xml', $dup->getRequestFormat());
305 * @dataProvider getFormatToMimeTypeMapProviderWithAdditionalNullFormat
307 public function testGetFormatFromMimeType($format, $mimeTypes)
309 $request = new Request();
310 foreach ($mimeTypes as $mime) {
311 $this->assertEquals($format, $request->getFormat($mime));
313 $request->setFormat($format, $mimeTypes);
314 foreach ($mimeTypes as $mime) {
315 $this->assertEquals($format, $request->getFormat($mime));
317 if (null !== $format) {
318 $this->assertEquals($mimeTypes[0], $request->getMimeType($format));
323 public function getFormatToMimeTypeMapProviderWithAdditionalNullFormat()
326 array(array(null, array(null, 'unexistent-mime-type'))),
327 $this->getFormatToMimeTypeMapProvider()
331 public function testGetFormatFromMimeTypeWithParameters()
333 $request = new Request();
334 $this->assertEquals('json', $request->getFormat('application/json; charset=utf-8'));
338 * @dataProvider getFormatToMimeTypeMapProvider
340 public function testGetMimeTypeFromFormat($format, $mimeTypes)
342 $request = new Request();
343 $this->assertEquals($mimeTypes[0], $request->getMimeType($format));
347 * @dataProvider getFormatToMimeTypeMapProvider
349 public function testGetMimeTypesFromFormat($format, $mimeTypes)
351 $this->assertEquals($mimeTypes, Request::getMimeTypes($format));
354 public function testGetMimeTypesFromInexistentFormat()
356 $request = new Request();
357 $this->assertNull($request->getMimeType('foo'));
358 $this->assertEquals(array(), Request::getMimeTypes('foo'));
361 public function testGetFormatWithCustomMimeType()
363 $request = new Request();
364 $request->setFormat('custom', 'application/vnd.foo.api;myversion=2.3');
365 $this->assertEquals('custom', $request->getFormat('application/vnd.foo.api;myversion=2.3'));
368 public function getFormatToMimeTypeMapProvider()
371 array('txt', array('text/plain')),
372 array('js', array('application/javascript', 'application/x-javascript', 'text/javascript')),
373 array('css', array('text/css')),
374 array('json', array('application/json', 'application/x-json')),
375 array('jsonld', array('application/ld+json')),
376 array('xml', array('text/xml', 'application/xml', 'application/x-xml')),
377 array('rdf', array('application/rdf+xml')),
378 array('atom', array('application/atom+xml')),
382 public function testGetUri()
386 // Standard Request on non default PORT
387 // http://host:8080/index.php/path/info?query=string
389 $server['HTTP_HOST'] = 'host:8080';
390 $server['SERVER_NAME'] = 'servername';
391 $server['SERVER_PORT'] = '8080';
393 $server['QUERY_STRING'] = 'query=string';
394 $server['REQUEST_URI'] = '/index.php/path/info?query=string';
395 $server['SCRIPT_NAME'] = '/index.php';
396 $server['PATH_INFO'] = '/path/info';
397 $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
398 $server['PHP_SELF'] = '/index_dev.php/path/info';
399 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
401 $request = new Request();
403 $request->initialize(array(), array(), array(), array(), array(), $server);
405 $this->assertEquals('http://host:8080/index.php/path/info?query=string', $request->getUri(), '->getUri() with non default port');
407 // Use std port number
408 $server['HTTP_HOST'] = 'host';
409 $server['SERVER_NAME'] = 'servername';
410 $server['SERVER_PORT'] = '80';
412 $request->initialize(array(), array(), array(), array(), array(), $server);
414 $this->assertEquals('http://host/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port');
416 // Without HOST HEADER
417 unset($server['HTTP_HOST']);
418 $server['SERVER_NAME'] = 'servername';
419 $server['SERVER_PORT'] = '80';
421 $request->initialize(array(), array(), array(), array(), array(), $server);
423 $this->assertEquals('http://servername/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port without HOST_HEADER');
425 // Request with URL REWRITING (hide index.php)
426 // RewriteCond %{REQUEST_FILENAME} !-f
427 // RewriteRule ^(.*)$ index.php [QSA,L]
428 // http://host:8080/path/info?query=string
430 $server['HTTP_HOST'] = 'host:8080';
431 $server['SERVER_NAME'] = 'servername';
432 $server['SERVER_PORT'] = '8080';
434 $server['REDIRECT_QUERY_STRING'] = 'query=string';
435 $server['REDIRECT_URL'] = '/path/info';
436 $server['SCRIPT_NAME'] = '/index.php';
437 $server['QUERY_STRING'] = 'query=string';
438 $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
439 $server['SCRIPT_NAME'] = '/index.php';
440 $server['PHP_SELF'] = '/index.php';
441 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
443 $request->initialize(array(), array(), array(), array(), array(), $server);
444 $this->assertEquals('http://host:8080/path/info?query=string', $request->getUri(), '->getUri() with rewrite');
446 // Use std port number
447 // http://host/path/info?query=string
448 $server['HTTP_HOST'] = 'host';
449 $server['SERVER_NAME'] = 'servername';
450 $server['SERVER_PORT'] = '80';
452 $request->initialize(array(), array(), array(), array(), array(), $server);
454 $this->assertEquals('http://host/path/info?query=string', $request->getUri(), '->getUri() with rewrite and default port');
456 // Without HOST HEADER
457 unset($server['HTTP_HOST']);
458 $server['SERVER_NAME'] = 'servername';
459 $server['SERVER_PORT'] = '80';
461 $request->initialize(array(), array(), array(), array(), array(), $server);
463 $this->assertEquals('http://servername/path/info?query=string', $request->getUri(), '->getUri() with rewrite, default port without HOST_HEADER');
465 // With encoded characters
468 'HTTP_HOST' => 'host:8080',
469 'SERVER_NAME' => 'servername',
470 'SERVER_PORT' => '8080',
471 'QUERY_STRING' => 'query=string',
472 'REQUEST_URI' => '/ba%20se/index_dev.php/foo%20bar/in+fo?query=string',
473 'SCRIPT_NAME' => '/ba se/index_dev.php',
474 'PATH_TRANSLATED' => 'redirect:/index.php/foo bar/in+fo',
475 'PHP_SELF' => '/ba se/index_dev.php/path/info',
476 'SCRIPT_FILENAME' => '/some/where/ba se/index_dev.php',
479 $request->initialize(array(), array(), array(), array(), array(), $server);
482 'http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string',
488 $server['PHP_AUTH_USER'] = 'fabien';
489 $request->initialize(array(), array(), array(), array(), array(), $server);
490 $this->assertEquals('http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri());
492 $server['PHP_AUTH_PW'] = 'symfony';
493 $request->initialize(array(), array(), array(), array(), array(), $server);
494 $this->assertEquals('http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri());
497 public function testGetUriForPath()
499 $request = Request::create('http://test.com/foo?bar=baz');
500 $this->assertEquals('http://test.com/some/path', $request->getUriForPath('/some/path'));
502 $request = Request::create('http://test.com:90/foo?bar=baz');
503 $this->assertEquals('http://test.com:90/some/path', $request->getUriForPath('/some/path'));
505 $request = Request::create('https://test.com/foo?bar=baz');
506 $this->assertEquals('https://test.com/some/path', $request->getUriForPath('/some/path'));
508 $request = Request::create('https://test.com:90/foo?bar=baz');
509 $this->assertEquals('https://test.com:90/some/path', $request->getUriForPath('/some/path'));
513 // Standard Request on non default PORT
514 // http://host:8080/index.php/path/info?query=string
516 $server['HTTP_HOST'] = 'host:8080';
517 $server['SERVER_NAME'] = 'servername';
518 $server['SERVER_PORT'] = '8080';
520 $server['QUERY_STRING'] = 'query=string';
521 $server['REQUEST_URI'] = '/index.php/path/info?query=string';
522 $server['SCRIPT_NAME'] = '/index.php';
523 $server['PATH_INFO'] = '/path/info';
524 $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
525 $server['PHP_SELF'] = '/index_dev.php/path/info';
526 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
528 $request = new Request();
530 $request->initialize(array(), array(), array(), array(), array(), $server);
532 $this->assertEquals('http://host:8080/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with non default port');
534 // Use std port number
535 $server['HTTP_HOST'] = 'host';
536 $server['SERVER_NAME'] = 'servername';
537 $server['SERVER_PORT'] = '80';
539 $request->initialize(array(), array(), array(), array(), array(), $server);
541 $this->assertEquals('http://host/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port');
543 // Without HOST HEADER
544 unset($server['HTTP_HOST']);
545 $server['SERVER_NAME'] = 'servername';
546 $server['SERVER_PORT'] = '80';
548 $request->initialize(array(), array(), array(), array(), array(), $server);
550 $this->assertEquals('http://servername/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port without HOST_HEADER');
552 // Request with URL REWRITING (hide index.php)
553 // RewriteCond %{REQUEST_FILENAME} !-f
554 // RewriteRule ^(.*)$ index.php [QSA,L]
555 // http://host:8080/path/info?query=string
557 $server['HTTP_HOST'] = 'host:8080';
558 $server['SERVER_NAME'] = 'servername';
559 $server['SERVER_PORT'] = '8080';
561 $server['REDIRECT_QUERY_STRING'] = 'query=string';
562 $server['REDIRECT_URL'] = '/path/info';
563 $server['SCRIPT_NAME'] = '/index.php';
564 $server['QUERY_STRING'] = 'query=string';
565 $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
566 $server['SCRIPT_NAME'] = '/index.php';
567 $server['PHP_SELF'] = '/index.php';
568 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
570 $request->initialize(array(), array(), array(), array(), array(), $server);
571 $this->assertEquals('http://host:8080/some/path', $request->getUriForPath('/some/path'), '->getUri() with rewrite');
573 // Use std port number
574 // http://host/path/info?query=string
575 $server['HTTP_HOST'] = 'host';
576 $server['SERVER_NAME'] = 'servername';
577 $server['SERVER_PORT'] = '80';
579 $request->initialize(array(), array(), array(), array(), array(), $server);
581 $this->assertEquals('http://host/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite and default port');
583 // Without HOST HEADER
584 unset($server['HTTP_HOST']);
585 $server['SERVER_NAME'] = 'servername';
586 $server['SERVER_PORT'] = '80';
588 $request->initialize(array(), array(), array(), array(), array(), $server);
590 $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite, default port without HOST_HEADER');
591 $this->assertEquals('servername', $request->getHttpHost());
595 $server['PHP_AUTH_USER'] = 'fabien';
596 $request->initialize(array(), array(), array(), array(), array(), $server);
597 $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'));
599 $server['PHP_AUTH_PW'] = 'symfony';
600 $request->initialize(array(), array(), array(), array(), array(), $server);
601 $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'));
605 * @dataProvider getRelativeUriForPathData()
607 public function testGetRelativeUriForPath($expected, $pathinfo, $path)
609 $this->assertEquals($expected, Request::create($pathinfo)->getRelativeUriForPath($path));
612 public function getRelativeUriForPathData()
615 array('me.png', '/foo', '/me.png'),
616 array('../me.png', '/foo/bar', '/me.png'),
617 array('me.png', '/foo/bar', '/foo/me.png'),
618 array('../baz/me.png', '/foo/bar/b', '/foo/baz/me.png'),
619 array('../../fooz/baz/me.png', '/foo/bar/b', '/fooz/baz/me.png'),
620 array('baz/me.png', '/foo/bar/b', 'baz/me.png'),
624 public function testGetUserInfo()
626 $request = new Request();
628 $server = array('PHP_AUTH_USER' => 'fabien');
629 $request->initialize(array(), array(), array(), array(), array(), $server);
630 $this->assertEquals('fabien', $request->getUserInfo());
632 $server['PHP_AUTH_USER'] = '0';
633 $request->initialize(array(), array(), array(), array(), array(), $server);
634 $this->assertEquals('0', $request->getUserInfo());
636 $server['PHP_AUTH_PW'] = '0';
637 $request->initialize(array(), array(), array(), array(), array(), $server);
638 $this->assertEquals('0:0', $request->getUserInfo());
641 public function testGetSchemeAndHttpHost()
643 $request = new Request();
646 $server['SERVER_NAME'] = 'servername';
647 $server['SERVER_PORT'] = '90';
648 $request->initialize(array(), array(), array(), array(), array(), $server);
649 $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
651 $server['PHP_AUTH_USER'] = 'fabien';
652 $request->initialize(array(), array(), array(), array(), array(), $server);
653 $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
655 $server['PHP_AUTH_USER'] = '0';
656 $request->initialize(array(), array(), array(), array(), array(), $server);
657 $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
659 $server['PHP_AUTH_PW'] = '0';
660 $request->initialize(array(), array(), array(), array(), array(), $server);
661 $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
665 * @dataProvider getQueryStringNormalizationData
667 public function testGetQueryString($query, $expectedQuery, $msg)
669 $request = new Request();
671 $request->server->set('QUERY_STRING', $query);
672 $this->assertSame($expectedQuery, $request->getQueryString(), $msg);
675 public function getQueryStringNormalizationData()
678 array('foo', 'foo', 'works with valueless parameters'),
679 array('foo=', 'foo=', 'includes a dangling equal sign'),
680 array('bar=&foo=bar', 'bar=&foo=bar', '->works with empty parameters'),
681 array('foo=bar&bar=', 'bar=&foo=bar', 'sorts keys alphabetically'),
683 // GET parameters, that are submitted from a HTML form, encode spaces as "+" by default (as defined in enctype application/x-www-form-urlencoded).
684 // PHP also converts "+" to spaces when filling the global _GET or when using the function parse_str.
685 array('him=John%20Doe&her=Jane+Doe', 'her=Jane%20Doe&him=John%20Doe', 'normalizes spaces in both encodings "%20" and "+"'),
687 array('foo[]=1&foo[]=2', 'foo%5B%5D=1&foo%5B%5D=2', 'allows array notation'),
688 array('foo=1&foo=2', 'foo=1&foo=2', 'allows repeated parameters'),
689 array('pa%3Dram=foo%26bar%3Dbaz&test=test', 'pa%3Dram=foo%26bar%3Dbaz&test=test', 'works with encoded delimiters'),
690 array('0', '0', 'allows "0"'),
691 array('Jane Doe&John%20Doe', 'Jane%20Doe&John%20Doe', 'normalizes encoding in keys'),
692 array('her=Jane Doe&him=John%20Doe', 'her=Jane%20Doe&him=John%20Doe', 'normalizes encoding in values'),
693 array('foo=bar&&&test&&', 'foo=bar&test', 'removes unneeded delimiters'),
694 array('formula=e=m*c^2', 'formula=e%3Dm%2Ac%5E2', 'correctly treats only the first "=" as delimiter and the next as value'),
696 // Ignore pairs with empty key, even if there was a value, e.g. "=value", as such nameless values cannot be retrieved anyway.
697 // PHP also does not include them when building _GET.
698 array('foo=bar&=a=b&=x=y', 'foo=bar', 'removes params with empty key'),
702 public function testGetQueryStringReturnsNull()
704 $request = new Request();
706 $this->assertNull($request->getQueryString(), '->getQueryString() returns null for non-existent query string');
708 $request->server->set('QUERY_STRING', '');
709 $this->assertNull($request->getQueryString(), '->getQueryString() returns null for empty query string');
712 public function testGetHost()
714 $request = new Request();
716 $request->initialize(array('foo' => 'bar'));
717 $this->assertEquals('', $request->getHost(), '->getHost() return empty string if not initialized');
719 $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.example.com'));
720 $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from Host Header');
722 // Host header with port number
723 $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.example.com:8080'));
724 $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from Host Header with port number');
727 $request->initialize(array(), array(), array(), array(), array(), array('SERVER_NAME' => 'www.example.com'));
728 $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from server name');
730 $request->initialize(array(), array(), array(), array(), array(), array('SERVER_NAME' => 'www.example.com', 'HTTP_HOST' => 'www.host.com'));
731 $this->assertEquals('www.host.com', $request->getHost(), '->getHost() value from Host header has priority over SERVER_NAME ');
734 public function testGetPort()
736 $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
737 'HTTP_X_FORWARDED_PROTO' => 'https',
738 'HTTP_X_FORWARDED_PORT' => '443',
740 $port = $request->getPort();
742 $this->assertEquals(80, $port, 'Without trusted proxies FORWARDED_PROTO and FORWARDED_PORT are ignored.');
744 Request::setTrustedProxies(array('1.1.1.1'), Request::HEADER_X_FORWARDED_ALL);
745 $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
746 'HTTP_X_FORWARDED_PROTO' => 'https',
747 'HTTP_X_FORWARDED_PORT' => '8443',
749 $this->assertEquals(80, $request->getPort(), 'With PROTO and PORT on untrusted connection server value takes precedence.');
750 $request->server->set('REMOTE_ADDR', '1.1.1.1');
751 $this->assertEquals(8443, $request->getPort(), 'With PROTO and PORT set PORT takes precedence.');
753 $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
754 'HTTP_X_FORWARDED_PROTO' => 'https',
756 $this->assertEquals(80, $request->getPort(), 'With only PROTO set getPort() ignores trusted headers on untrusted connection.');
757 $request->server->set('REMOTE_ADDR', '1.1.1.1');
758 $this->assertEquals(443, $request->getPort(), 'With only PROTO set getPort() defaults to 443.');
760 $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
761 'HTTP_X_FORWARDED_PROTO' => 'http',
763 $this->assertEquals(80, $request->getPort(), 'If X_FORWARDED_PROTO is set to HTTP getPort() ignores trusted headers on untrusted connection.');
764 $request->server->set('REMOTE_ADDR', '1.1.1.1');
765 $this->assertEquals(80, $request->getPort(), 'If X_FORWARDED_PROTO is set to HTTP getPort() returns port of the original request.');
767 $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
768 'HTTP_X_FORWARDED_PROTO' => 'On',
770 $this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is On, getPort() ignores trusted headers on untrusted connection.');
771 $request->server->set('REMOTE_ADDR', '1.1.1.1');
772 $this->assertEquals(443, $request->getPort(), 'With only PROTO set and value is On, getPort() defaults to 443.');
774 $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
775 'HTTP_X_FORWARDED_PROTO' => '1',
777 $this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is 1, getPort() ignores trusted headers on untrusted connection.');
778 $request->server->set('REMOTE_ADDR', '1.1.1.1');
779 $this->assertEquals(443, $request->getPort(), 'With only PROTO set and value is 1, getPort() defaults to 443.');
781 $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
782 'HTTP_X_FORWARDED_PROTO' => 'something-else',
784 $port = $request->getPort();
785 $this->assertEquals(80, $port, 'With only PROTO set and value is not recognized, getPort() defaults to 80.');
789 * @expectedException \RuntimeException
791 public function testGetHostWithFakeHttpHostValue()
793 $request = new Request();
794 $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.host.com?query=string'));
798 public function testGetSetMethod()
800 $request = new Request();
802 $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns GET if no method is defined');
804 $request->setMethod('get');
805 $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns an uppercased string');
807 $request->setMethod('PURGE');
808 $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method even if it is not a standard one');
810 $request->setMethod('POST');
811 $this->assertEquals('POST', $request->getMethod(), '->getMethod() returns the method POST if no _method is defined');
813 $request->setMethod('POST');
814 $request->request->set('_method', 'purge');
815 $this->assertEquals('POST', $request->getMethod(), '->getMethod() does not return the method from _method if defined and POST but support not enabled');
817 $request = new Request();
818 $request->setMethod('POST');
819 $request->request->set('_method', 'purge');
821 $this->assertFalse(Request::getHttpMethodParameterOverride(), 'httpMethodParameterOverride should be disabled by default');
823 Request::enableHttpMethodParameterOverride();
825 $this->assertTrue(Request::getHttpMethodParameterOverride(), 'httpMethodParameterOverride should be enabled now but it is not');
827 $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method from _method if defined and POST');
828 $this->disableHttpMethodParameterOverride();
830 $request = new Request();
831 $request->setMethod('POST');
832 $request->query->set('_method', 'purge');
833 $this->assertEquals('POST', $request->getMethod(), '->getMethod() does not return the method from _method if defined and POST but support not enabled');
835 $request = new Request();
836 $request->setMethod('POST');
837 $request->query->set('_method', 'purge');
838 Request::enableHttpMethodParameterOverride();
839 $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method from _method if defined and POST');
840 $this->disableHttpMethodParameterOverride();
842 $request = new Request();
843 $request->setMethod('POST');
844 $request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete');
845 $this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override even though _method is set if defined and POST');
847 $request = new Request();
848 $request->setMethod('POST');
849 $request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete');
850 $this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override if defined and POST');
852 $request = new Request();
853 $request->setMethod('POST');
854 $request->query->set('_method', array('delete', 'patch'));
855 $this->assertSame('POST', $request->getMethod(), '->getMethod() returns the request method if invalid type is defined in query');
859 * @dataProvider getClientIpsProvider
861 public function testGetClientIp($expected, $remoteAddr, $httpForwardedFor, $trustedProxies)
863 $request = $this->getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies);
865 $this->assertEquals($expected[0], $request->getClientIp());
869 * @dataProvider getClientIpsProvider
871 public function testGetClientIps($expected, $remoteAddr, $httpForwardedFor, $trustedProxies)
873 $request = $this->getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies);
875 $this->assertEquals($expected, $request->getClientIps());
879 * @dataProvider getClientIpsForwardedProvider
881 public function testGetClientIpsForwarded($expected, $remoteAddr, $httpForwarded, $trustedProxies)
883 $request = $this->getRequestInstanceForClientIpsForwardedTests($remoteAddr, $httpForwarded, $trustedProxies);
885 $this->assertEquals($expected, $request->getClientIps());
888 public function getClientIpsForwardedProvider()
890 // $expected $remoteAddr $httpForwarded $trustedProxies
892 array(array('127.0.0.1'), '127.0.0.1', 'for="_gazonk"', null),
893 array(array('127.0.0.1'), '127.0.0.1', 'for="_gazonk"', array('127.0.0.1')),
894 array(array('88.88.88.88'), '127.0.0.1', 'for="88.88.88.88:80"', array('127.0.0.1')),
895 array(array('192.0.2.60'), '::1', 'for=192.0.2.60;proto=http;by=203.0.113.43', array('::1')),
896 array(array('2620:0:1cfe:face:b00c::3', '192.0.2.43'), '::1', 'for=192.0.2.43, for=2620:0:1cfe:face:b00c::3', array('::1')),
897 array(array('2001:db8:cafe::17'), '::1', 'for="[2001:db8:cafe::17]:4711', array('::1')),
901 public function getClientIpsProvider()
903 // $expected $remoteAddr $httpForwardedFor $trustedProxies
906 array(array('88.88.88.88'), '88.88.88.88', null, null),
907 // trust the IPv4 remote addr
908 array(array('88.88.88.88'), '88.88.88.88', null, array('88.88.88.88')),
911 array(array('::1'), '::1', null, null),
912 // trust the IPv6 remote addr
913 array(array('::1'), '::1', null, array('::1')),
915 // forwarded for with remote IPv4 addr not trusted
916 array(array('127.0.0.1'), '127.0.0.1', '88.88.88.88', null),
917 // forwarded for with remote IPv4 addr trusted + comma
918 array(array('88.88.88.88'), '127.0.0.1', '88.88.88.88,', array('127.0.0.1')),
919 // forwarded for with remote IPv4 and all FF addrs trusted
920 array(array('88.88.88.88'), '127.0.0.1', '88.88.88.88', array('127.0.0.1', '88.88.88.88')),
921 // forwarded for with remote IPv4 range trusted
922 array(array('88.88.88.88'), '123.45.67.89', '88.88.88.88', array('123.45.67.0/24')),
924 // forwarded for with remote IPv6 addr not trusted
925 array(array('1620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '2620:0:1cfe:face:b00c::3', null),
926 // forwarded for with remote IPv6 addr trusted
927 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')),
928 // forwarded for with remote IPv6 range trusted
929 array(array('88.88.88.88'), '2a01:198:603:0:396e:4789:8e99:890f', '88.88.88.88', array('2a01:198:603:0::/65')),
931 // multiple forwarded for with remote IPv4 addr trusted
932 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')),
933 // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted
934 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')),
935 // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted but in the middle
936 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')),
937 // multiple forwarded for with remote IPv4 addr and all reverse proxies trusted
938 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')),
940 // multiple forwarded for with remote IPv6 addr trusted
941 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')),
942 // multiple forwarded for with remote IPv6 addr and some reverse proxies trusted
943 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')),
944 // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted but in the middle
945 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')),
947 // client IP with port
948 array(array('88.88.88.88'), '127.0.0.1', '88.88.88.88:12345, 127.0.0.1', array('127.0.0.1')),
950 // invalid forwarded IP is ignored
951 array(array('88.88.88.88'), '127.0.0.1', 'unknown,88.88.88.88', array('127.0.0.1')),
952 array(array('88.88.88.88'), '127.0.0.1', '}__test|O:21:"JDatabaseDriverMysqli":3:{s:2,88.88.88.88', array('127.0.0.1')),
957 * @expectedException \Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException
958 * @dataProvider getClientIpsWithConflictingHeadersProvider
960 public function testGetClientIpsWithConflictingHeaders($httpForwarded, $httpXForwardedFor)
962 $request = new Request();
965 'REMOTE_ADDR' => '88.88.88.88',
966 'HTTP_FORWARDED' => $httpForwarded,
967 'HTTP_X_FORWARDED_FOR' => $httpXForwardedFor,
970 Request::setTrustedProxies(array('88.88.88.88'), Request::HEADER_X_FORWARDED_ALL | Request::HEADER_FORWARDED);
972 $request->initialize(array(), array(), array(), array(), array(), $server);
974 $request->getClientIps();
978 * @dataProvider getClientIpsWithConflictingHeadersProvider
980 public function testGetClientIpsOnlyXHttpForwardedForTrusted($httpForwarded, $httpXForwardedFor)
982 $request = new Request();
985 'REMOTE_ADDR' => '88.88.88.88',
986 'HTTP_FORWARDED' => $httpForwarded,
987 'HTTP_X_FORWARDED_FOR' => $httpXForwardedFor,
990 Request::setTrustedProxies(array('88.88.88.88'), Request::HEADER_X_FORWARDED_FOR);
992 $request->initialize(array(), array(), array(), array(), array(), $server);
994 $this->assertSame(array_reverse(explode(',', $httpXForwardedFor)), $request->getClientIps());
997 public function getClientIpsWithConflictingHeadersProvider()
999 // $httpForwarded $httpXForwardedFor
1001 array('for=87.65.43.21', '192.0.2.60'),
1002 array('for=87.65.43.21, for=192.0.2.60', '192.0.2.60'),
1003 array('for=192.0.2.60', '192.0.2.60,87.65.43.21'),
1004 array('for="::face", for=192.0.2.60', '192.0.2.60,192.0.2.43'),
1005 array('for=87.65.43.21, for=192.0.2.60', '192.0.2.60,87.65.43.21'),
1010 * @dataProvider getClientIpsWithAgreeingHeadersProvider
1012 public function testGetClientIpsWithAgreeingHeaders($httpForwarded, $httpXForwardedFor, $expectedIps)
1014 $request = new Request();
1017 'REMOTE_ADDR' => '88.88.88.88',
1018 'HTTP_FORWARDED' => $httpForwarded,
1019 'HTTP_X_FORWARDED_FOR' => $httpXForwardedFor,
1022 Request::setTrustedProxies(array('88.88.88.88'), -1);
1024 $request->initialize(array(), array(), array(), array(), array(), $server);
1026 $clientIps = $request->getClientIps();
1028 $this->assertSame($expectedIps, $clientIps);
1031 public function getClientIpsWithAgreeingHeadersProvider()
1033 // $httpForwarded $httpXForwardedFor
1035 array('for="192.0.2.60"', '192.0.2.60', array('192.0.2.60')),
1036 array('for=192.0.2.60, for=87.65.43.21', '192.0.2.60,87.65.43.21', array('87.65.43.21', '192.0.2.60')),
1037 array('for="[::face]", for=192.0.2.60', '::face,192.0.2.60', array('192.0.2.60', '::face')),
1038 array('for="192.0.2.60:80"', '192.0.2.60', array('192.0.2.60')),
1039 array('for=192.0.2.60;proto=http;by=203.0.113.43', '192.0.2.60', array('192.0.2.60')),
1040 array('for="[2001:db8:cafe::17]:4711"', '2001:db8:cafe::17', array('2001:db8:cafe::17')),
1044 public function testGetContentWorksTwiceInDefaultMode()
1046 $req = new Request();
1047 $this->assertEquals('', $req->getContent());
1048 $this->assertEquals('', $req->getContent());
1051 public function testGetContentReturnsResource()
1053 $req = new Request();
1054 $retval = $req->getContent(true);
1055 $this->assertInternalType('resource', $retval);
1056 $this->assertEquals('', fread($retval, 1));
1057 $this->assertTrue(feof($retval));
1060 public function testGetContentReturnsResourceWhenContentSetInConstructor()
1062 $req = new Request(array(), array(), array(), array(), array(), array(), 'MyContent');
1063 $resource = $req->getContent(true);
1065 $this->assertInternalType('resource', $resource);
1066 $this->assertEquals('MyContent', stream_get_contents($resource));
1069 public function testContentAsResource()
1071 $resource = fopen('php://memory', 'r+');
1072 fwrite($resource, 'My other content');
1075 $req = new Request(array(), array(), array(), array(), array(), array(), $resource);
1076 $this->assertEquals('My other content', stream_get_contents($req->getContent(true)));
1077 $this->assertEquals('My other content', $req->getContent());
1081 * @expectedException \LogicException
1082 * @dataProvider getContentCantBeCalledTwiceWithResourcesProvider
1084 public function testGetContentCantBeCalledTwiceWithResources($first, $second)
1086 if (\PHP_VERSION_ID >= 50600) {
1087 $this->markTestSkipped('PHP >= 5.6 allows to open php://input several times.');
1090 $req = new Request();
1091 $req->getContent($first);
1092 $req->getContent($second);
1095 public function getContentCantBeCalledTwiceWithResourcesProvider()
1098 'Resource then fetch' => array(true, false),
1099 'Resource then resource' => array(true, true),
1104 * @dataProvider getContentCanBeCalledTwiceWithResourcesProvider
1107 public function testGetContentCanBeCalledTwiceWithResources($first, $second)
1109 $req = new Request();
1110 $a = $req->getContent($first);
1111 $b = $req->getContent($second);
1114 $a = stream_get_contents($a);
1118 $b = stream_get_contents($b);
1121 $this->assertSame($a, $b);
1124 public function getContentCanBeCalledTwiceWithResourcesProvider()
1127 'Fetch then fetch' => array(false, false),
1128 'Fetch then resource' => array(false, true),
1129 'Resource then fetch' => array(true, false),
1130 'Resource then resource' => array(true, true),
1134 public function provideOverloadedMethods()
1147 * @dataProvider provideOverloadedMethods
1149 public function testCreateFromGlobals($method)
1151 $normalizedMethod = strtoupper($method);
1153 $_GET['foo1'] = 'bar1';
1154 $_POST['foo2'] = 'bar2';
1155 $_COOKIE['foo3'] = 'bar3';
1156 $_FILES['foo4'] = array('bar4');
1157 $_SERVER['foo5'] = 'bar5';
1159 $request = Request::createFromGlobals();
1160 $this->assertEquals('bar1', $request->query->get('foo1'), '::fromGlobals() uses values from $_GET');
1161 $this->assertEquals('bar2', $request->request->get('foo2'), '::fromGlobals() uses values from $_POST');
1162 $this->assertEquals('bar3', $request->cookies->get('foo3'), '::fromGlobals() uses values from $_COOKIE');
1163 $this->assertEquals(array('bar4'), $request->files->get('foo4'), '::fromGlobals() uses values from $_FILES');
1164 $this->assertEquals('bar5', $request->server->get('foo5'), '::fromGlobals() uses values from $_SERVER');
1166 unset($_GET['foo1'], $_POST['foo2'], $_COOKIE['foo3'], $_FILES['foo4'], $_SERVER['foo5']);
1168 $_SERVER['REQUEST_METHOD'] = $method;
1169 $_SERVER['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
1170 $request = RequestContentProxy::createFromGlobals();
1171 $this->assertEquals($normalizedMethod, $request->getMethod());
1172 $this->assertEquals('mycontent', $request->request->get('content'));
1174 unset($_SERVER['REQUEST_METHOD'], $_SERVER['CONTENT_TYPE']);
1176 Request::createFromGlobals();
1177 Request::enableHttpMethodParameterOverride();
1178 $_POST['_method'] = $method;
1179 $_POST['foo6'] = 'bar6';
1180 $_SERVER['REQUEST_METHOD'] = 'PoSt';
1181 $request = Request::createFromGlobals();
1182 $this->assertEquals($normalizedMethod, $request->getMethod());
1183 $this->assertEquals('POST', $request->getRealMethod());
1184 $this->assertEquals('bar6', $request->request->get('foo6'));
1186 unset($_POST['_method'], $_POST['foo6'], $_SERVER['REQUEST_METHOD']);
1187 $this->disableHttpMethodParameterOverride();
1190 public function testOverrideGlobals()
1192 $request = new Request();
1193 $request->initialize(array('foo' => 'bar'));
1195 // as the Request::overrideGlobals really work, it erase $_SERVER, so we must backup it
1198 $request->overrideGlobals();
1200 $this->assertEquals(array('foo' => 'bar'), $_GET);
1202 $request->initialize(array(), array('foo' => 'bar'));
1203 $request->overrideGlobals();
1205 $this->assertEquals(array('foo' => 'bar'), $_POST);
1207 $this->assertArrayNotHasKey('HTTP_X_FORWARDED_PROTO', $_SERVER);
1209 $request->headers->set('X_FORWARDED_PROTO', 'https');
1211 Request::setTrustedProxies(array('1.1.1.1'), Request::HEADER_X_FORWARDED_ALL);
1212 $this->assertFalse($request->isSecure());
1213 $request->server->set('REMOTE_ADDR', '1.1.1.1');
1214 $this->assertTrue($request->isSecure());
1216 $request->overrideGlobals();
1218 $this->assertArrayHasKey('HTTP_X_FORWARDED_PROTO', $_SERVER);
1220 $request->headers->set('CONTENT_TYPE', 'multipart/form-data');
1221 $request->headers->set('CONTENT_LENGTH', 12345);
1223 $request->overrideGlobals();
1225 $this->assertArrayHasKey('CONTENT_TYPE', $_SERVER);
1226 $this->assertArrayHasKey('CONTENT_LENGTH', $_SERVER);
1228 $request->initialize(array('foo' => 'bar', 'baz' => 'foo'));
1229 $request->query->remove('baz');
1231 $request->overrideGlobals();
1233 $this->assertEquals(array('foo' => 'bar'), $_GET);
1234 $this->assertEquals('foo=bar', $_SERVER['QUERY_STRING']);
1235 $this->assertEquals('foo=bar', $request->server->get('QUERY_STRING'));
1237 // restore initial $_SERVER array
1241 public function testGetScriptName()
1243 $request = new Request();
1244 $this->assertEquals('', $request->getScriptName());
1247 $server['SCRIPT_NAME'] = '/index.php';
1249 $request->initialize(array(), array(), array(), array(), array(), $server);
1251 $this->assertEquals('/index.php', $request->getScriptName());
1254 $server['ORIG_SCRIPT_NAME'] = '/frontend.php';
1255 $request->initialize(array(), array(), array(), array(), array(), $server);
1257 $this->assertEquals('/frontend.php', $request->getScriptName());
1260 $server['SCRIPT_NAME'] = '/index.php';
1261 $server['ORIG_SCRIPT_NAME'] = '/frontend.php';
1262 $request->initialize(array(), array(), array(), array(), array(), $server);
1264 $this->assertEquals('/index.php', $request->getScriptName());
1267 public function testGetBasePath()
1269 $request = new Request();
1270 $this->assertEquals('', $request->getBasePath());
1273 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
1274 $request->initialize(array(), array(), array(), array(), array(), $server);
1275 $this->assertEquals('', $request->getBasePath());
1278 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
1279 $server['SCRIPT_NAME'] = '/index.php';
1280 $request->initialize(array(), array(), array(), array(), array(), $server);
1282 $this->assertEquals('', $request->getBasePath());
1285 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
1286 $server['PHP_SELF'] = '/index.php';
1287 $request->initialize(array(), array(), array(), array(), array(), $server);
1289 $this->assertEquals('', $request->getBasePath());
1292 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
1293 $server['ORIG_SCRIPT_NAME'] = '/index.php';
1294 $request->initialize(array(), array(), array(), array(), array(), $server);
1296 $this->assertEquals('', $request->getBasePath());
1299 public function testGetPathInfo()
1301 $request = new Request();
1302 $this->assertEquals('/', $request->getPathInfo());
1305 $server['REQUEST_URI'] = '/path/info';
1306 $request->initialize(array(), array(), array(), array(), array(), $server);
1308 $this->assertEquals('/path/info', $request->getPathInfo());
1311 $server['REQUEST_URI'] = '/path%20test/info';
1312 $request->initialize(array(), array(), array(), array(), array(), $server);
1314 $this->assertEquals('/path%20test/info', $request->getPathInfo());
1317 $server['REQUEST_URI'] = '?a=b';
1318 $request->initialize(array(), array(), array(), array(), array(), $server);
1320 $this->assertEquals('/', $request->getPathInfo());
1323 public function testGetParameterPrecedence()
1325 $request = new Request();
1326 $request->attributes->set('foo', 'attr');
1327 $request->query->set('foo', 'query');
1328 $request->request->set('foo', 'body');
1330 $this->assertSame('attr', $request->get('foo'));
1332 $request->attributes->remove('foo');
1333 $this->assertSame('query', $request->get('foo'));
1335 $request->query->remove('foo');
1336 $this->assertSame('body', $request->get('foo'));
1338 $request->request->remove('foo');
1339 $this->assertNull($request->get('foo'));
1342 public function testGetPreferredLanguage()
1344 $request = new Request();
1345 $this->assertNull($request->getPreferredLanguage());
1346 $this->assertNull($request->getPreferredLanguage(array()));
1347 $this->assertEquals('fr', $request->getPreferredLanguage(array('fr')));
1348 $this->assertEquals('fr', $request->getPreferredLanguage(array('fr', 'en')));
1349 $this->assertEquals('en', $request->getPreferredLanguage(array('en', 'fr')));
1350 $this->assertEquals('fr-ch', $request->getPreferredLanguage(array('fr-ch', 'fr-fr')));
1352 $request = new Request();
1353 $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
1354 $this->assertEquals('en', $request->getPreferredLanguage(array('en', 'en-us')));
1356 $request = new Request();
1357 $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
1358 $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));
1360 $request = new Request();
1361 $request->headers->set('Accept-language', 'zh, en-us; q=0.8');
1362 $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));
1364 $request = new Request();
1365 $request->headers->set('Accept-language', 'zh, en-us; q=0.8, fr-fr; q=0.6, fr; q=0.5');
1366 $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));
1369 public function testIsXmlHttpRequest()
1371 $request = new Request();
1372 $this->assertFalse($request->isXmlHttpRequest());
1374 $request->headers->set('X-Requested-With', 'XMLHttpRequest');
1375 $this->assertTrue($request->isXmlHttpRequest());
1377 $request->headers->remove('X-Requested-With');
1378 $this->assertFalse($request->isXmlHttpRequest());
1382 * @requires extension intl
1384 public function testIntlLocale()
1386 $request = new Request();
1388 $request->setDefaultLocale('fr');
1389 $this->assertEquals('fr', $request->getLocale());
1390 $this->assertEquals('fr', \Locale::getDefault());
1392 $request->setLocale('en');
1393 $this->assertEquals('en', $request->getLocale());
1394 $this->assertEquals('en', \Locale::getDefault());
1396 $request->setDefaultLocale('de');
1397 $this->assertEquals('en', $request->getLocale());
1398 $this->assertEquals('en', \Locale::getDefault());
1401 public function testGetCharsets()
1403 $request = new Request();
1404 $this->assertEquals(array(), $request->getCharsets());
1405 $request->headers->set('Accept-Charset', 'ISO-8859-1, US-ASCII, UTF-8; q=0.8, ISO-10646-UCS-2; q=0.6');
1406 $this->assertEquals(array(), $request->getCharsets()); // testing caching
1408 $request = new Request();
1409 $request->headers->set('Accept-Charset', 'ISO-8859-1, US-ASCII, UTF-8; q=0.8, ISO-10646-UCS-2; q=0.6');
1410 $this->assertEquals(array('ISO-8859-1', 'US-ASCII', 'UTF-8', 'ISO-10646-UCS-2'), $request->getCharsets());
1412 $request = new Request();
1413 $request->headers->set('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7');
1414 $this->assertEquals(array('ISO-8859-1', 'utf-8', '*'), $request->getCharsets());
1417 public function testGetEncodings()
1419 $request = new Request();
1420 $this->assertEquals(array(), $request->getEncodings());
1421 $request->headers->set('Accept-Encoding', 'gzip,deflate,sdch');
1422 $this->assertEquals(array(), $request->getEncodings()); // testing caching
1424 $request = new Request();
1425 $request->headers->set('Accept-Encoding', 'gzip,deflate,sdch');
1426 $this->assertEquals(array('gzip', 'deflate', 'sdch'), $request->getEncodings());
1428 $request = new Request();
1429 $request->headers->set('Accept-Encoding', 'gzip;q=0.4,deflate;q=0.9,compress;q=0.7');
1430 $this->assertEquals(array('deflate', 'compress', 'gzip'), $request->getEncodings());
1433 public function testGetAcceptableContentTypes()
1435 $request = new Request();
1436 $this->assertEquals(array(), $request->getAcceptableContentTypes());
1437 $request->headers->set('Accept', 'application/vnd.wap.wmlscriptc, text/vnd.wap.wml, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html, multipart/mixed, */*');
1438 $this->assertEquals(array(), $request->getAcceptableContentTypes()); // testing caching
1440 $request = new Request();
1441 $request->headers->set('Accept', 'application/vnd.wap.wmlscriptc, text/vnd.wap.wml, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html, multipart/mixed, */*');
1442 $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());
1445 public function testGetLanguages()
1447 $request = new Request();
1448 $this->assertEquals(array(), $request->getLanguages());
1450 $request = new Request();
1451 $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
1452 $this->assertEquals(array('zh', 'en_US', 'en'), $request->getLanguages());
1453 $this->assertEquals(array('zh', 'en_US', 'en'), $request->getLanguages());
1455 $request = new Request();
1456 $request->headers->set('Accept-language', 'zh, en-us; q=0.6, en; q=0.8');
1457 $this->assertEquals(array('zh', 'en', 'en_US'), $request->getLanguages()); // Test out of order qvalues
1459 $request = new Request();
1460 $request->headers->set('Accept-language', 'zh, en, en-us');
1461 $this->assertEquals(array('zh', 'en', 'en_US'), $request->getLanguages()); // Test equal weighting without qvalues
1463 $request = new Request();
1464 $request->headers->set('Accept-language', 'zh; q=0.6, en, en-us; q=0.6');
1465 $this->assertEquals(array('en', 'zh', 'en_US'), $request->getLanguages()); // Test equal weighting with qvalues
1467 $request = new Request();
1468 $request->headers->set('Accept-language', 'zh, i-cherokee; q=0.6');
1469 $this->assertEquals(array('zh', 'cherokee'), $request->getLanguages());
1472 public function testGetRequestFormat()
1474 $request = new Request();
1475 $this->assertEquals('html', $request->getRequestFormat());
1477 // Ensure that setting different default values over time is possible,
1478 // aka. setRequestFormat determines the state.
1479 $this->assertEquals('json', $request->getRequestFormat('json'));
1480 $this->assertEquals('html', $request->getRequestFormat('html'));
1482 $request = new Request();
1483 $this->assertNull($request->getRequestFormat(null));
1485 $request = new Request();
1486 $this->assertNull($request->setRequestFormat('foo'));
1487 $this->assertEquals('foo', $request->getRequestFormat(null));
1489 $request = new Request(array('_format' => 'foo'));
1490 $this->assertEquals('html', $request->getRequestFormat());
1493 public function testHasSession()
1495 $request = new Request();
1497 $this->assertFalse($request->hasSession());
1498 $request->setSession(new Session(new MockArraySessionStorage()));
1499 $this->assertTrue($request->hasSession());
1502 public function testGetSession()
1504 $request = new Request();
1506 $request->setSession(new Session(new MockArraySessionStorage()));
1507 $this->assertTrue($request->hasSession());
1509 $session = $request->getSession();
1510 $this->assertObjectHasAttribute('storage', $session);
1511 $this->assertObjectHasAttribute('flashName', $session);
1512 $this->assertObjectHasAttribute('attributeName', $session);
1515 public function testHasPreviousSession()
1517 $request = new Request();
1519 $this->assertFalse($request->hasPreviousSession());
1520 $request->cookies->set('MOCKSESSID', 'foo');
1521 $this->assertFalse($request->hasPreviousSession());
1522 $request->setSession(new Session(new MockArraySessionStorage()));
1523 $this->assertTrue($request->hasPreviousSession());
1526 public function testToString()
1528 $request = new Request();
1530 $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
1531 $request->cookies->set('Foo', 'Bar');
1533 $asString = (string) $request;
1535 $this->assertContains('Accept-Language: zh, en-us; q=0.8, en; q=0.6', $asString);
1536 $this->assertContains('Cookie: Foo=Bar', $asString);
1538 $request->cookies->set('Another', 'Cookie');
1540 $asString = (string) $request;
1542 $this->assertContains('Cookie: Foo=Bar; Another=Cookie', $asString);
1545 public function testIsMethod()
1547 $request = new Request();
1548 $request->setMethod('POST');
1549 $this->assertTrue($request->isMethod('POST'));
1550 $this->assertTrue($request->isMethod('post'));
1551 $this->assertFalse($request->isMethod('GET'));
1552 $this->assertFalse($request->isMethod('get'));
1554 $request->setMethod('GET');
1555 $this->assertTrue($request->isMethod('GET'));
1556 $this->assertTrue($request->isMethod('get'));
1557 $this->assertFalse($request->isMethod('POST'));
1558 $this->assertFalse($request->isMethod('post'));
1562 * @dataProvider getBaseUrlData
1564 public function testGetBaseUrl($uri, $server, $expectedBaseUrl, $expectedPathInfo)
1566 $request = Request::create($uri, 'GET', array(), array(), array(), $server);
1568 $this->assertSame($expectedBaseUrl, $request->getBaseUrl(), 'baseUrl');
1569 $this->assertSame($expectedPathInfo, $request->getPathInfo(), 'pathInfo');
1572 public function getBaseUrlData()
1576 '/fruit/strawberry/1234index.php/blah',
1578 'SCRIPT_FILENAME' => 'E:/Sites/cc-new/public_html/fruit/index.php',
1579 'SCRIPT_NAME' => '/fruit/index.php',
1580 'PHP_SELF' => '/fruit/index.php',
1583 '/strawberry/1234index.php/blah',
1586 '/fruit/strawberry/1234index.php/blah',
1588 'SCRIPT_FILENAME' => 'E:/Sites/cc-new/public_html/index.php',
1589 'SCRIPT_NAME' => '/index.php',
1590 'PHP_SELF' => '/index.php',
1593 '/fruit/strawberry/1234index.php/blah',
1598 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
1599 'SCRIPT_NAME' => '/foo bar/app.php',
1600 'PHP_SELF' => '/foo bar/app.php',
1608 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
1609 'SCRIPT_NAME' => '/foo bar/app.php',
1610 'PHP_SELF' => '/foo bar/app.php',
1616 '/foo%20bar/app.php/home',
1618 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
1619 'SCRIPT_NAME' => '/foo bar/app.php',
1620 'PHP_SELF' => '/foo bar/app.php',
1622 '/foo%20bar/app.php',
1626 '/foo%20bar/app.php/home%3Dbaz',
1628 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
1629 'SCRIPT_NAME' => '/foo bar/app.php',
1630 'PHP_SELF' => '/foo bar/app.php',
1632 '/foo%20bar/app.php',
1638 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo/app.php',
1639 'SCRIPT_NAME' => '/foo/app.php',
1640 'PHP_SELF' => '/foo/app.php',
1649 * @dataProvider urlencodedStringPrefixData
1651 public function testUrlencodedStringPrefix($string, $prefix, $expect)
1653 $request = new Request();
1655 $me = new \ReflectionMethod($request, 'getUrlencodedPrefix');
1656 $me->setAccessible(true);
1658 $this->assertSame($expect, $me->invoke($request, $string, $prefix));
1661 public function urlencodedStringPrefixData()
1664 array('foo', 'foo', 'foo'),
1665 array('fo%6f', 'foo', 'fo%6f'),
1666 array('foo/bar', 'foo', 'foo'),
1667 array('fo%6f/bar', 'foo', 'fo%6f'),
1668 array('f%6f%6f/bar', 'foo', 'f%6f%6f'),
1669 array('%66%6F%6F/bar', 'foo', '%66%6F%6F'),
1670 array('fo+o/bar', 'fo+o', 'fo+o'),
1671 array('fo%2Bo/bar', 'fo+o', 'fo%2Bo'),
1675 private function disableHttpMethodParameterOverride()
1677 $class = new \ReflectionClass('Symfony\\Component\\HttpFoundation\\Request');
1678 $property = $class->getProperty('httpMethodParameterOverride');
1679 $property->setAccessible(true);
1680 $property->setValue(false);
1683 private function getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies)
1685 $request = new Request();
1687 $server = array('REMOTE_ADDR' => $remoteAddr);
1688 if (null !== $httpForwardedFor) {
1689 $server['HTTP_X_FORWARDED_FOR'] = $httpForwardedFor;
1692 if ($trustedProxies) {
1693 Request::setTrustedProxies($trustedProxies, Request::HEADER_X_FORWARDED_ALL);
1696 $request->initialize(array(), array(), array(), array(), array(), $server);
1701 private function getRequestInstanceForClientIpsForwardedTests($remoteAddr, $httpForwarded, $trustedProxies)
1703 $request = new Request();
1705 $server = array('REMOTE_ADDR' => $remoteAddr);
1707 if (null !== $httpForwarded) {
1708 $server['HTTP_FORWARDED'] = $httpForwarded;
1711 if ($trustedProxies) {
1712 Request::setTrustedProxies($trustedProxies, Request::HEADER_FORWARDED);
1715 $request->initialize(array(), array(), array(), array(), array(), $server);
1720 public function testTrustedProxiesXForwardedFor()
1722 $request = Request::create('http://example.com/');
1723 $request->server->set('REMOTE_ADDR', '3.3.3.3');
1724 $request->headers->set('X_FORWARDED_FOR', '1.1.1.1, 2.2.2.2');
1725 $request->headers->set('X_FORWARDED_HOST', 'foo.example.com:1234, real.example.com:8080');
1726 $request->headers->set('X_FORWARDED_PROTO', 'https');
1727 $request->headers->set('X_FORWARDED_PORT', 443);
1729 // no trusted proxies
1730 $this->assertEquals('3.3.3.3', $request->getClientIp());
1731 $this->assertEquals('example.com', $request->getHost());
1732 $this->assertEquals(80, $request->getPort());
1733 $this->assertFalse($request->isSecure());
1735 // disabling proxy trusting
1736 Request::setTrustedProxies(array(), Request::HEADER_X_FORWARDED_ALL);
1737 $this->assertEquals('3.3.3.3', $request->getClientIp());
1738 $this->assertEquals('example.com', $request->getHost());
1739 $this->assertEquals(80, $request->getPort());
1740 $this->assertFalse($request->isSecure());
1742 // request is forwarded by a non-trusted proxy
1743 Request::setTrustedProxies(array('2.2.2.2'), Request::HEADER_X_FORWARDED_ALL);
1744 $this->assertEquals('3.3.3.3', $request->getClientIp());
1745 $this->assertEquals('example.com', $request->getHost());
1746 $this->assertEquals(80, $request->getPort());
1747 $this->assertFalse($request->isSecure());
1749 // trusted proxy via setTrustedProxies()
1750 Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'), Request::HEADER_X_FORWARDED_ALL);
1751 $this->assertEquals('1.1.1.1', $request->getClientIp());
1752 $this->assertEquals('foo.example.com', $request->getHost());
1753 $this->assertEquals(443, $request->getPort());
1754 $this->assertTrue($request->isSecure());
1756 // trusted proxy via setTrustedProxies()
1757 Request::setTrustedProxies(array('3.3.3.4', '2.2.2.2'), Request::HEADER_X_FORWARDED_ALL);
1758 $this->assertEquals('3.3.3.3', $request->getClientIp());
1759 $this->assertEquals('example.com', $request->getHost());
1760 $this->assertEquals(80, $request->getPort());
1761 $this->assertFalse($request->isSecure());
1763 // check various X_FORWARDED_PROTO header values
1764 Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'), Request::HEADER_X_FORWARDED_ALL);
1765 $request->headers->set('X_FORWARDED_PROTO', 'ssl');
1766 $this->assertTrue($request->isSecure());
1768 $request->headers->set('X_FORWARDED_PROTO', 'https, http');
1769 $this->assertTrue($request->isSecure());
1774 * @expectedDeprecation The "Symfony\Component\HttpFoundation\Request::setTrustedHeaderName()" method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the $trustedHeaderSet argument of the Request::setTrustedProxies() method instead.
1776 public function testLegacyTrustedProxies()
1778 $request = Request::create('http://example.com/');
1779 $request->server->set('REMOTE_ADDR', '3.3.3.3');
1780 $request->headers->set('X_FORWARDED_FOR', '1.1.1.1, 2.2.2.2');
1781 $request->headers->set('X_FORWARDED_HOST', 'foo.example.com, real.example.com:8080');
1782 $request->headers->set('X_FORWARDED_PROTO', 'https');
1783 $request->headers->set('X_FORWARDED_PORT', 443);
1784 $request->headers->set('X_MY_FOR', '3.3.3.3, 4.4.4.4');
1785 $request->headers->set('X_MY_HOST', 'my.example.com');
1786 $request->headers->set('X_MY_PROTO', 'http');
1787 $request->headers->set('X_MY_PORT', 81);
1789 Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'), Request::HEADER_X_FORWARDED_ALL);
1791 // custom header names
1792 Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_MY_FOR');
1793 Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_MY_HOST');
1794 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_MY_PORT');
1795 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_MY_PROTO');
1796 $this->assertEquals('4.4.4.4', $request->getClientIp());
1797 $this->assertEquals('my.example.com', $request->getHost());
1798 $this->assertEquals(81, $request->getPort());
1799 $this->assertFalse($request->isSecure());
1801 // disabling via empty header names
1802 Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, null);
1803 Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, null);
1804 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, null);
1805 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, null);
1806 $this->assertEquals('3.3.3.3', $request->getClientIp());
1807 $this->assertEquals('example.com', $request->getHost());
1808 $this->assertEquals(80, $request->getPort());
1809 $this->assertFalse($request->isSecure());
1812 Request::setTrustedHeaderName(Request::HEADER_FORWARDED, 'FORWARDED');
1813 Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_FORWARDED_FOR');
1814 Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_FORWARDED_HOST');
1815 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_FORWARDED_PORT');
1816 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_FORWARDED_PROTO');
1819 public function testTrustedProxiesForwarded()
1821 $request = Request::create('http://example.com/');
1822 $request->server->set('REMOTE_ADDR', '3.3.3.3');
1823 $request->headers->set('FORWARDED', 'for=1.1.1.1, host=foo.example.com:8080, proto=https, for=2.2.2.2, host=real.example.com:8080');
1825 // no trusted proxies
1826 $this->assertEquals('3.3.3.3', $request->getClientIp());
1827 $this->assertEquals('example.com', $request->getHost());
1828 $this->assertEquals(80, $request->getPort());
1829 $this->assertFalse($request->isSecure());
1831 // disabling proxy trusting
1832 Request::setTrustedProxies(array(), Request::HEADER_FORWARDED);
1833 $this->assertEquals('3.3.3.3', $request->getClientIp());
1834 $this->assertEquals('example.com', $request->getHost());
1835 $this->assertEquals(80, $request->getPort());
1836 $this->assertFalse($request->isSecure());
1838 // request is forwarded by a non-trusted proxy
1839 Request::setTrustedProxies(array('2.2.2.2'), Request::HEADER_FORWARDED);
1840 $this->assertEquals('3.3.3.3', $request->getClientIp());
1841 $this->assertEquals('example.com', $request->getHost());
1842 $this->assertEquals(80, $request->getPort());
1843 $this->assertFalse($request->isSecure());
1845 // trusted proxy via setTrustedProxies()
1846 Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'), Request::HEADER_FORWARDED);
1847 $this->assertEquals('1.1.1.1', $request->getClientIp());
1848 $this->assertEquals('foo.example.com', $request->getHost());
1849 $this->assertEquals(8080, $request->getPort());
1850 $this->assertTrue($request->isSecure());
1852 // trusted proxy via setTrustedProxies()
1853 Request::setTrustedProxies(array('3.3.3.4', '2.2.2.2'), Request::HEADER_FORWARDED);
1854 $this->assertEquals('3.3.3.3', $request->getClientIp());
1855 $this->assertEquals('example.com', $request->getHost());
1856 $this->assertEquals(80, $request->getPort());
1857 $this->assertFalse($request->isSecure());
1859 // check various X_FORWARDED_PROTO header values
1860 Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'), Request::HEADER_FORWARDED);
1861 $request->headers->set('FORWARDED', 'proto=ssl');
1862 $this->assertTrue($request->isSecure());
1864 $request->headers->set('FORWARDED', 'proto=https, proto=http');
1865 $this->assertTrue($request->isSecure());
1870 * @expectedException \InvalidArgumentException
1872 public function testSetTrustedProxiesInvalidHeaderName()
1874 Request::create('http://example.com/');
1875 Request::setTrustedHeaderName('bogus name', 'X_MY_FOR');
1880 * @expectedException \InvalidArgumentException
1882 public function testGetTrustedProxiesInvalidHeaderName()
1884 Request::create('http://example.com/');
1885 Request::getTrustedHeaderName('bogus name');
1889 * @dataProvider iisRequestUriProvider
1891 public function testIISRequestUri($headers, $server, $expectedRequestUri)
1893 $request = new Request();
1894 $request->headers->replace($headers);
1895 $request->server->replace($server);
1897 $this->assertEquals($expectedRequestUri, $request->getRequestUri(), '->getRequestUri() is correct');
1899 $subRequestUri = '/bar/foo';
1900 $subRequest = Request::create($subRequestUri, 'get', array(), array(), array(), $request->server->all());
1901 $this->assertEquals($subRequestUri, $subRequest->getRequestUri(), '->getRequestUri() is correct in sub request');
1904 public function iisRequestUriProvider()
1910 'IIS_WasUrlRewritten' => '1',
1911 'UNENCODED_URL' => '/foo/bar',
1918 'ORIG_PATH_INFO' => '/foo/bar',
1925 'ORIG_PATH_INFO' => '/foo/bar',
1926 'QUERY_STRING' => 'foo=bar',
1933 public function testTrustedHosts()
1936 $request = Request::create('/');
1938 // no trusted host set -> no host check
1939 $request->headers->set('host', 'evil.com');
1940 $this->assertEquals('evil.com', $request->getHost());
1942 // add a trusted domain and all its subdomains
1943 Request::setTrustedHosts(array('^([a-z]{9}\.)?trusted\.com$'));
1946 $request->headers->set('host', 'evil.com');
1948 $request->getHost();
1949 $this->fail('Request::getHost() should throw an exception when host is not trusted.');
1950 } catch (SuspiciousOperationException $e) {
1951 $this->assertEquals('Untrusted Host "evil.com".', $e->getMessage());
1955 $request->headers->set('host', 'trusted.com');
1956 $this->assertEquals('trusted.com', $request->getHost());
1957 $this->assertEquals(80, $request->getPort());
1959 $request->server->set('HTTPS', true);
1960 $request->headers->set('host', 'trusted.com');
1961 $this->assertEquals('trusted.com', $request->getHost());
1962 $this->assertEquals(443, $request->getPort());
1963 $request->server->set('HTTPS', false);
1965 $request->headers->set('host', 'trusted.com:8000');
1966 $this->assertEquals('trusted.com', $request->getHost());
1967 $this->assertEquals(8000, $request->getPort());
1969 $request->headers->set('host', 'subdomain.trusted.com');
1970 $this->assertEquals('subdomain.trusted.com', $request->getHost());
1973 public function testSetTrustedHostsDoesNotBreakOnSpecialCharacters()
1975 Request::setTrustedHosts(array('localhost(\.local){0,1}#,example.com', 'localhost'));
1977 $request = Request::create('/');
1978 $request->headers->set('host', 'localhost');
1979 $this->assertSame('localhost', $request->getHost());
1982 public function testFactory()
1984 Request::setFactory(function (array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) {
1985 return new NewRequest();
1988 $this->assertEquals('foo', Request::create('/')->getFoo());
1990 Request::setFactory(null);
1994 * @dataProvider getLongHostNames
1996 public function testVeryLongHosts($host)
1998 $start = microtime(true);
2000 $request = Request::create('/');
2001 $request->headers->set('host', $host);
2002 $this->assertEquals($host, $request->getHost());
2003 $this->assertLessThan(5, microtime(true) - $start);
2007 * @dataProvider getHostValidities
2009 public function testHostValidity($host, $isValid, $expectedHost = null, $expectedPort = null)
2011 $request = Request::create('/');
2012 $request->headers->set('host', $host);
2015 $this->assertSame($expectedHost ?: $host, $request->getHost());
2016 if ($expectedPort) {
2017 $this->assertSame($expectedPort, $request->getPort());
2020 if (method_exists($this, 'expectException')) {
2021 $this->expectException(SuspiciousOperationException::class);
2022 $this->expectExceptionMessage('Invalid Host');
2024 $this->setExpectedException(SuspiciousOperationException::class, 'Invalid Host');
2027 $request->getHost();
2031 public function getHostValidities()
2035 array('a..', false),
2037 array("\xE9", false),
2038 array('[::1]', true),
2039 array('[::1]:80', true, '[::1]', 80),
2040 array(str_repeat('.', 101), false),
2044 public function getLongHostNames()
2047 array('a'.str_repeat('.a', 40000)),
2048 array(str_repeat(':', 101)),
2053 * @dataProvider methodIdempotentProvider
2055 public function testMethodIdempotent($method, $idempotent)
2057 $request = new Request();
2058 $request->setMethod($method);
2059 $this->assertEquals($idempotent, $request->isMethodIdempotent());
2062 public function methodIdempotentProvider()
2065 array('HEAD', true),
2067 array('POST', false),
2069 array('PATCH', false),
2070 array('DELETE', true),
2071 array('PURGE', true),
2072 array('OPTIONS', true),
2073 array('TRACE', true),
2074 array('CONNECT', false),
2079 * @dataProvider methodSafeProvider
2081 public function testMethodSafe($method, $safe)
2083 $request = new Request();
2084 $request->setMethod($method);
2085 $this->assertEquals($safe, $request->isMethodSafe(false));
2088 public function methodSafeProvider()
2091 array('HEAD', true),
2093 array('POST', false),
2094 array('PUT', false),
2095 array('PATCH', false),
2096 array('DELETE', false),
2097 array('PURGE', false),
2098 array('OPTIONS', true),
2099 array('TRACE', true),
2100 array('CONNECT', false),
2106 * @expectedDeprecation Checking only for cacheable HTTP methods with Symfony\Component\HttpFoundation\Request::isMethodSafe() is deprecated since Symfony 3.2 and will throw an exception in 4.0. Disable checking only for cacheable methods by calling the method with `false` as first argument or use the Request::isMethodCacheable() instead.
2108 public function testMethodSafeChecksCacheable()
2110 $request = new Request();
2111 $request->setMethod('OPTIONS');
2112 $this->assertFalse($request->isMethodSafe());
2116 * @dataProvider methodCacheableProvider
2118 public function testMethodCacheable($method, $cacheable)
2120 $request = new Request();
2121 $request->setMethod($method);
2122 $this->assertEquals($cacheable, $request->isMethodCacheable());
2125 public function methodCacheableProvider()
2128 array('HEAD', true),
2130 array('POST', false),
2131 array('PUT', false),
2132 array('PATCH', false),
2133 array('DELETE', false),
2134 array('PURGE', false),
2135 array('OPTIONS', false),
2136 array('TRACE', false),
2137 array('CONNECT', false),
2144 public function testGetTrustedHeaderName()
2146 Request::setTrustedProxies(array('8.8.8.8'), Request::HEADER_X_FORWARDED_ALL);
2148 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
2149 $this->assertSame('X_FORWARDED_FOR', Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP));
2150 $this->assertSame('X_FORWARDED_HOST', Request::getTrustedHeaderName(Request::HEADER_CLIENT_HOST));
2151 $this->assertSame('X_FORWARDED_PORT', Request::getTrustedHeaderName(Request::HEADER_CLIENT_PORT));
2152 $this->assertSame('X_FORWARDED_PROTO', Request::getTrustedHeaderName(Request::HEADER_CLIENT_PROTO));
2154 Request::setTrustedProxies(array('8.8.8.8'), Request::HEADER_FORWARDED);
2156 $this->assertSame('FORWARDED', Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
2157 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP));
2158 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_HOST));
2159 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_PORT));
2160 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_PROTO));
2162 Request::setTrustedHeaderName(Request::HEADER_FORWARDED, 'A');
2163 Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'B');
2164 Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'C');
2165 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'D');
2166 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'E');
2168 Request::setTrustedProxies(array('8.8.8.8'), Request::HEADER_FORWARDED);
2170 $this->assertSame('A', Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
2171 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP));
2172 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_HOST));
2173 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_PORT));
2174 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_PROTO));
2176 Request::setTrustedProxies(array('8.8.8.8'), Request::HEADER_X_FORWARDED_ALL);
2178 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
2179 $this->assertSame('B', Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP));
2180 $this->assertSame('C', Request::getTrustedHeaderName(Request::HEADER_CLIENT_HOST));
2181 $this->assertSame('D', Request::getTrustedHeaderName(Request::HEADER_CLIENT_PORT));
2182 $this->assertSame('E', Request::getTrustedHeaderName(Request::HEADER_CLIENT_PROTO));
2184 Request::setTrustedProxies(array('8.8.8.8'), Request::HEADER_FORWARDED);
2186 $this->assertSame('A', Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
2189 Request::setTrustedHeaderName(Request::HEADER_FORWARDED, 'FORWARDED');
2190 Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_FORWARDED_FOR');
2191 Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_FORWARDED_HOST');
2192 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_FORWARDED_PORT');
2193 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_FORWARDED_PROTO');
2197 * @dataProvider protocolVersionProvider
2199 public function testProtocolVersion($serverProtocol, $trustedProxy, $via, $expected)
2201 if ($trustedProxy) {
2202 Request::setTrustedProxies(array('1.1.1.1'), -1);
2205 $request = new Request();
2206 $request->server->set('SERVER_PROTOCOL', $serverProtocol);
2207 $request->server->set('REMOTE_ADDR', '1.1.1.1');
2208 $request->headers->set('Via', $via);
2210 $this->assertSame($expected, $request->getProtocolVersion());
2213 public function protocolVersionProvider()
2216 'untrusted without via' => array('HTTP/2.0', false, '', 'HTTP/2.0'),
2217 'untrusted with via' => array('HTTP/2.0', false, '1.0 fred, 1.1 nowhere.com (Apache/1.1)', 'HTTP/2.0'),
2218 'trusted without via' => array('HTTP/2.0', true, '', 'HTTP/2.0'),
2219 'trusted with via' => array('HTTP/2.0', true, '1.0 fred, 1.1 nowhere.com (Apache/1.1)', 'HTTP/1.0'),
2220 'trusted with via and protocol name' => array('HTTP/2.0', true, 'HTTP/1.0 fred, HTTP/1.1 nowhere.com (Apache/1.1)', 'HTTP/1.0'),
2221 'trusted with broken via' => array('HTTP/2.0', true, 'HTTP/1^0 foo', 'HTTP/2.0'),
2222 'trusted with partially-broken via' => array('HTTP/2.0', true, '1.0 fred, foo', 'HTTP/1.0'),
2226 public function nonstandardRequestsData()
2229 array('', '', '/', 'http://host:8080/', ''),
2230 array('/', '', '/', 'http://host:8080/', ''),
2232 array('hello/app.php/x', '', '/x', 'http://host:8080/hello/app.php/x', '/hello', '/hello/app.php'),
2233 array('/hello/app.php/x', '', '/x', 'http://host:8080/hello/app.php/x', '/hello', '/hello/app.php'),
2235 array('', 'a=b', '/', 'http://host:8080/?a=b'),
2236 array('?a=b', 'a=b', '/', 'http://host:8080/?a=b'),
2237 array('/?a=b', 'a=b', '/', 'http://host:8080/?a=b'),
2239 array('x', 'a=b', '/x', 'http://host:8080/x?a=b'),
2240 array('x?a=b', 'a=b', '/x', 'http://host:8080/x?a=b'),
2241 array('/x?a=b', 'a=b', '/x', 'http://host:8080/x?a=b'),
2243 array('hello/x', '', '/x', 'http://host:8080/hello/x', '/hello'),
2244 array('/hello/x', '', '/x', 'http://host:8080/hello/x', '/hello'),
2246 array('hello/app.php/x', 'a=b', '/x', 'http://host:8080/hello/app.php/x?a=b', '/hello', '/hello/app.php'),
2247 array('hello/app.php/x?a=b', 'a=b', '/x', 'http://host:8080/hello/app.php/x?a=b', '/hello', '/hello/app.php'),
2248 array('/hello/app.php/x?a=b', 'a=b', '/x', 'http://host:8080/hello/app.php/x?a=b', '/hello', '/hello/app.php'),
2253 * @dataProvider nonstandardRequestsData
2255 public function testNonstandardRequests($requestUri, $queryString, $expectedPathInfo, $expectedUri, $expectedBasePath = '', $expectedBaseUrl = null)
2257 if (null === $expectedBaseUrl) {
2258 $expectedBaseUrl = $expectedBasePath;
2262 'HTTP_HOST' => 'host:8080',
2263 'SERVER_PORT' => '8080',
2264 'QUERY_STRING' => $queryString,
2265 'PHP_SELF' => '/hello/app.php',
2266 'SCRIPT_FILENAME' => '/some/path/app.php',
2267 'REQUEST_URI' => $requestUri,
2270 $request = new Request(array(), array(), array(), array(), array(), $server);
2272 $this->assertEquals($expectedPathInfo, $request->getPathInfo());
2273 $this->assertEquals($expectedUri, $request->getUri());
2274 $this->assertEquals($queryString, $request->getQueryString());
2275 $this->assertEquals(8080, $request->getPort());
2276 $this->assertEquals('host:8080', $request->getHttpHost());
2277 $this->assertEquals($expectedBaseUrl, $request->getBaseUrl());
2278 $this->assertEquals($expectedBasePath, $request->getBasePath());
2281 public function testTrustedHost()
2283 Request::setTrustedProxies(array('1.1.1.1'), -1);
2285 $request = Request::create('/');
2286 $request->server->set('REMOTE_ADDR', '1.1.1.1');
2287 $request->headers->set('Forwarded', 'host=localhost:8080');
2288 $request->headers->set('X-Forwarded-Host', 'localhost:8080');
2290 $this->assertSame('localhost:8080', $request->getHttpHost());
2291 $this->assertSame(8080, $request->getPort());
2293 $request = Request::create('/');
2294 $request->server->set('REMOTE_ADDR', '1.1.1.1');
2295 $request->headers->set('Forwarded', 'host="[::1]:443"');
2296 $request->headers->set('X-Forwarded-Host', '[::1]:443');
2297 $request->headers->set('X-Forwarded-Port', 443);
2299 $this->assertSame('[::1]:443', $request->getHttpHost());
2300 $this->assertSame(443, $request->getPort());
2303 public function testTrustedPort()
2305 Request::setTrustedProxies(array('1.1.1.1'), -1);
2307 $request = Request::create('/');
2308 $request->server->set('REMOTE_ADDR', '1.1.1.1');
2309 $request->headers->set('Forwarded', 'host=localhost:8080');
2310 $request->headers->set('X-Forwarded-Port', 8080);
2312 $this->assertSame(8080, $request->getPort());
2314 $request = Request::create('/');
2315 $request->server->set('REMOTE_ADDR', '1.1.1.1');
2316 $request->headers->set('Forwarded', 'host=localhost');
2317 $request->headers->set('X-Forwarded-Port', 80);
2319 $this->assertSame(80, $request->getPort());
2321 $request = Request::create('/');
2322 $request->server->set('REMOTE_ADDR', '1.1.1.1');
2323 $request->headers->set('Forwarded', 'host="[::1]"');
2324 $request->headers->set('X-Forwarded-Proto', 'https');
2325 $request->headers->set('X-Forwarded-Port', 443);
2327 $this->assertSame(443, $request->getPort());
2331 class RequestContentProxy extends Request
2333 public function getContent($asResource = false)
2335 return http_build_query(array('_method' => 'PUT', 'content' => 'mycontent'), '', '&');
2339 class NewRequest extends Request
2341 public function getFoo()