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\Session\Storage\MockArraySessionStorage;
16 use Symfony\Component\HttpFoundation\Session\Session;
17 use Symfony\Component\HttpFoundation\Request;
19 class RequestTest extends TestCase
21 public function testInitialize()
23 $request = new Request();
25 $request->initialize(array('foo' => 'bar'));
26 $this->assertEquals('bar', $request->query->get('foo'), '->initialize() takes an array of query parameters as its first argument');
28 $request->initialize(array(), array('foo' => 'bar'));
29 $this->assertEquals('bar', $request->request->get('foo'), '->initialize() takes an array of request parameters as its second argument');
31 $request->initialize(array(), array(), array('foo' => 'bar'));
32 $this->assertEquals('bar', $request->attributes->get('foo'), '->initialize() takes an array of attributes as its third argument');
34 $request->initialize(array(), array(), array(), array(), array(), array('HTTP_FOO' => 'bar'));
35 $this->assertEquals('bar', $request->headers->get('FOO'), '->initialize() takes an array of HTTP headers as its sixth argument');
38 public function testGetLocale()
40 $request = new Request();
41 $request->setLocale('pl');
42 $locale = $request->getLocale();
43 $this->assertEquals('pl', $locale);
46 public function testGetUser()
48 $request = Request::create('http://user_test:password_test@test.com/');
49 $user = $request->getUser();
51 $this->assertEquals('user_test', $user);
54 public function testGetPassword()
56 $request = Request::create('http://user_test:password_test@test.com/');
57 $password = $request->getPassword();
59 $this->assertEquals('password_test', $password);
62 public function testIsNoCache()
64 $request = new Request();
65 $isNoCache = $request->isNoCache();
67 $this->assertFalse($isNoCache);
70 public function testGetContentType()
72 $request = new Request();
73 $contentType = $request->getContentType();
75 $this->assertNull($contentType);
78 public function testSetDefaultLocale()
80 $request = new Request();
81 $request->setDefaultLocale('pl');
82 $locale = $request->getLocale();
84 $this->assertEquals('pl', $locale);
87 public function testCreate()
89 $request = Request::create('http://test.com/foo?bar=baz');
90 $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
91 $this->assertEquals('/foo', $request->getPathInfo());
92 $this->assertEquals('bar=baz', $request->getQueryString());
93 $this->assertEquals(80, $request->getPort());
94 $this->assertEquals('test.com', $request->getHttpHost());
95 $this->assertFalse($request->isSecure());
97 $request = Request::create('http://test.com/foo', 'GET', array('bar' => 'baz'));
98 $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
99 $this->assertEquals('/foo', $request->getPathInfo());
100 $this->assertEquals('bar=baz', $request->getQueryString());
101 $this->assertEquals(80, $request->getPort());
102 $this->assertEquals('test.com', $request->getHttpHost());
103 $this->assertFalse($request->isSecure());
105 $request = Request::create('http://test.com/foo?bar=foo', 'GET', array('bar' => 'baz'));
106 $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
107 $this->assertEquals('/foo', $request->getPathInfo());
108 $this->assertEquals('bar=baz', $request->getQueryString());
109 $this->assertEquals(80, $request->getPort());
110 $this->assertEquals('test.com', $request->getHttpHost());
111 $this->assertFalse($request->isSecure());
113 $request = Request::create('https://test.com/foo?bar=baz');
114 $this->assertEquals('https://test.com/foo?bar=baz', $request->getUri());
115 $this->assertEquals('/foo', $request->getPathInfo());
116 $this->assertEquals('bar=baz', $request->getQueryString());
117 $this->assertEquals(443, $request->getPort());
118 $this->assertEquals('test.com', $request->getHttpHost());
119 $this->assertTrue($request->isSecure());
121 $request = Request::create('test.com:90/foo');
122 $this->assertEquals('http://test.com:90/foo', $request->getUri());
123 $this->assertEquals('/foo', $request->getPathInfo());
124 $this->assertEquals('test.com', $request->getHost());
125 $this->assertEquals('test.com:90', $request->getHttpHost());
126 $this->assertEquals(90, $request->getPort());
127 $this->assertFalse($request->isSecure());
129 $request = Request::create('https://test.com:90/foo');
130 $this->assertEquals('https://test.com:90/foo', $request->getUri());
131 $this->assertEquals('/foo', $request->getPathInfo());
132 $this->assertEquals('test.com', $request->getHost());
133 $this->assertEquals('test.com:90', $request->getHttpHost());
134 $this->assertEquals(90, $request->getPort());
135 $this->assertTrue($request->isSecure());
137 $request = Request::create('https://127.0.0.1:90/foo');
138 $this->assertEquals('https://127.0.0.1:90/foo', $request->getUri());
139 $this->assertEquals('/foo', $request->getPathInfo());
140 $this->assertEquals('127.0.0.1', $request->getHost());
141 $this->assertEquals('127.0.0.1:90', $request->getHttpHost());
142 $this->assertEquals(90, $request->getPort());
143 $this->assertTrue($request->isSecure());
145 $request = Request::create('https://[::1]:90/foo');
146 $this->assertEquals('https://[::1]:90/foo', $request->getUri());
147 $this->assertEquals('/foo', $request->getPathInfo());
148 $this->assertEquals('[::1]', $request->getHost());
149 $this->assertEquals('[::1]:90', $request->getHttpHost());
150 $this->assertEquals(90, $request->getPort());
151 $this->assertTrue($request->isSecure());
153 $request = Request::create('https://[::1]/foo');
154 $this->assertEquals('https://[::1]/foo', $request->getUri());
155 $this->assertEquals('/foo', $request->getPathInfo());
156 $this->assertEquals('[::1]', $request->getHost());
157 $this->assertEquals('[::1]', $request->getHttpHost());
158 $this->assertEquals(443, $request->getPort());
159 $this->assertTrue($request->isSecure());
161 $json = '{"jsonrpc":"2.0","method":"echo","id":7,"params":["Hello World"]}';
162 $request = Request::create('http://example.com/jsonrpc', 'POST', array(), array(), array(), array(), $json);
163 $this->assertEquals($json, $request->getContent());
164 $this->assertFalse($request->isSecure());
166 $request = Request::create('http://test.com');
167 $this->assertEquals('http://test.com/', $request->getUri());
168 $this->assertEquals('/', $request->getPathInfo());
169 $this->assertEquals('', $request->getQueryString());
170 $this->assertEquals(80, $request->getPort());
171 $this->assertEquals('test.com', $request->getHttpHost());
172 $this->assertFalse($request->isSecure());
174 $request = Request::create('http://test.com?test=1');
175 $this->assertEquals('http://test.com/?test=1', $request->getUri());
176 $this->assertEquals('/', $request->getPathInfo());
177 $this->assertEquals('test=1', $request->getQueryString());
178 $this->assertEquals(80, $request->getPort());
179 $this->assertEquals('test.com', $request->getHttpHost());
180 $this->assertFalse($request->isSecure());
182 $request = Request::create('http://test.com:90/?test=1');
183 $this->assertEquals('http://test.com:90/?test=1', $request->getUri());
184 $this->assertEquals('/', $request->getPathInfo());
185 $this->assertEquals('test=1', $request->getQueryString());
186 $this->assertEquals(90, $request->getPort());
187 $this->assertEquals('test.com:90', $request->getHttpHost());
188 $this->assertFalse($request->isSecure());
190 $request = Request::create('http://username:password@test.com');
191 $this->assertEquals('http://test.com/', $request->getUri());
192 $this->assertEquals('/', $request->getPathInfo());
193 $this->assertEquals('', $request->getQueryString());
194 $this->assertEquals(80, $request->getPort());
195 $this->assertEquals('test.com', $request->getHttpHost());
196 $this->assertEquals('username', $request->getUser());
197 $this->assertEquals('password', $request->getPassword());
198 $this->assertFalse($request->isSecure());
200 $request = Request::create('http://username@test.com');
201 $this->assertEquals('http://test.com/', $request->getUri());
202 $this->assertEquals('/', $request->getPathInfo());
203 $this->assertEquals('', $request->getQueryString());
204 $this->assertEquals(80, $request->getPort());
205 $this->assertEquals('test.com', $request->getHttpHost());
206 $this->assertEquals('username', $request->getUser());
207 $this->assertSame('', $request->getPassword());
208 $this->assertFalse($request->isSecure());
210 $request = Request::create('http://test.com/?foo');
211 $this->assertEquals('/?foo', $request->getRequestUri());
212 $this->assertEquals(array('foo' => ''), $request->query->all());
214 // assume rewrite rule: (.*) --> app/app.php; app/ is a symlink to a symfony web/ directory
215 $request = Request::create('http://test.com/apparthotel-1234', 'GET', array(), array(), array(),
217 'DOCUMENT_ROOT' => '/var/www/www.test.com',
218 'SCRIPT_FILENAME' => '/var/www/www.test.com/app/app.php',
219 'SCRIPT_NAME' => '/app/app.php',
220 'PHP_SELF' => '/app/app.php/apparthotel-1234',
222 $this->assertEquals('http://test.com/apparthotel-1234', $request->getUri());
223 $this->assertEquals('/apparthotel-1234', $request->getPathInfo());
224 $this->assertEquals('', $request->getQueryString());
225 $this->assertEquals(80, $request->getPort());
226 $this->assertEquals('test.com', $request->getHttpHost());
227 $this->assertFalse($request->isSecure());
230 public function testCreateCheckPrecedence()
232 // server is used by default
233 $request = Request::create('/', 'DELETE', array(), array(), array(), array(
234 'HTTP_HOST' => 'example.com',
236 'SERVER_PORT' => 443,
237 'PHP_AUTH_USER' => 'fabien',
238 'PHP_AUTH_PW' => 'pa$$',
239 'QUERY_STRING' => 'foo=bar',
240 'CONTENT_TYPE' => 'application/json',
242 $this->assertEquals('example.com', $request->getHost());
243 $this->assertEquals(443, $request->getPort());
244 $this->assertTrue($request->isSecure());
245 $this->assertEquals('fabien', $request->getUser());
246 $this->assertEquals('pa$$', $request->getPassword());
247 $this->assertEquals('', $request->getQueryString());
248 $this->assertEquals('application/json', $request->headers->get('CONTENT_TYPE'));
250 // URI has precedence over server
251 $request = Request::create('http://thomas:pokemon@example.net:8080/?foo=bar', 'GET', array(), array(), array(), array(
252 'HTTP_HOST' => 'example.com',
254 'SERVER_PORT' => 443,
256 $this->assertEquals('example.net', $request->getHost());
257 $this->assertEquals(8080, $request->getPort());
258 $this->assertFalse($request->isSecure());
259 $this->assertEquals('thomas', $request->getUser());
260 $this->assertEquals('pokemon', $request->getPassword());
261 $this->assertEquals('foo=bar', $request->getQueryString());
264 public function testDuplicate()
266 $request = new Request(array('foo' => 'bar'), array('foo' => 'bar'), array('foo' => 'bar'), array(), array(), array('HTTP_FOO' => 'bar'));
267 $dup = $request->duplicate();
269 $this->assertEquals($request->query->all(), $dup->query->all(), '->duplicate() duplicates a request an copy the current query parameters');
270 $this->assertEquals($request->request->all(), $dup->request->all(), '->duplicate() duplicates a request an copy the current request parameters');
271 $this->assertEquals($request->attributes->all(), $dup->attributes->all(), '->duplicate() duplicates a request an copy the current attributes');
272 $this->assertEquals($request->headers->all(), $dup->headers->all(), '->duplicate() duplicates a request an copy the current HTTP headers');
274 $dup = $request->duplicate(array('foo' => 'foobar'), array('foo' => 'foobar'), array('foo' => 'foobar'), array(), array(), array('HTTP_FOO' => 'foobar'));
276 $this->assertEquals(array('foo' => 'foobar'), $dup->query->all(), '->duplicate() overrides the query parameters if provided');
277 $this->assertEquals(array('foo' => 'foobar'), $dup->request->all(), '->duplicate() overrides the request parameters if provided');
278 $this->assertEquals(array('foo' => 'foobar'), $dup->attributes->all(), '->duplicate() overrides the attributes if provided');
279 $this->assertEquals(array('foo' => array('foobar')), $dup->headers->all(), '->duplicate() overrides the HTTP header if provided');
282 public function testDuplicateWithFormat()
284 $request = new Request(array(), array(), array('_format' => 'json'));
285 $dup = $request->duplicate();
287 $this->assertEquals('json', $dup->getRequestFormat());
288 $this->assertEquals('json', $dup->attributes->get('_format'));
290 $request = new Request();
291 $request->setRequestFormat('xml');
292 $dup = $request->duplicate();
294 $this->assertEquals('xml', $dup->getRequestFormat());
298 * @dataProvider getFormatToMimeTypeMapProvider
300 public function testGetFormatFromMimeType($format, $mimeTypes)
302 $request = new Request();
303 foreach ($mimeTypes as $mime) {
304 $this->assertEquals($format, $request->getFormat($mime));
306 $request->setFormat($format, $mimeTypes);
307 foreach ($mimeTypes as $mime) {
308 $this->assertEquals($format, $request->getFormat($mime));
310 if (null !== $format) {
311 $this->assertEquals($mimeTypes[0], $request->getMimeType($format));
316 public function testGetFormatFromMimeTypeWithParameters()
318 $request = new Request();
319 $this->assertEquals('json', $request->getFormat('application/json; charset=utf-8'));
322 public function testGetFormatWithCustomMimeType()
324 $request = new Request();
325 $request->setFormat('custom', 'application/vnd.foo.api;myversion=2.3');
326 $this->assertEquals('custom', $request->getFormat('application/vnd.foo.api;myversion=2.3'));
329 public function getFormatToMimeTypeMapProvider()
332 array(null, array(null, 'unexistent-mime-type')),
333 array('txt', array('text/plain')),
334 array('js', array('application/javascript', 'application/x-javascript', 'text/javascript')),
335 array('css', array('text/css')),
336 array('json', array('application/json', 'application/x-json')),
337 array('xml', array('text/xml', 'application/xml', 'application/x-xml')),
338 array('rdf', array('application/rdf+xml')),
339 array('atom', array('application/atom+xml')),
343 public function testGetUri()
347 // Standard Request on non default PORT
348 // http://host:8080/index.php/path/info?query=string
350 $server['HTTP_HOST'] = 'host:8080';
351 $server['SERVER_NAME'] = 'servername';
352 $server['SERVER_PORT'] = '8080';
354 $server['QUERY_STRING'] = 'query=string';
355 $server['REQUEST_URI'] = '/index.php/path/info?query=string';
356 $server['SCRIPT_NAME'] = '/index.php';
357 $server['PATH_INFO'] = '/path/info';
358 $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
359 $server['PHP_SELF'] = '/index_dev.php/path/info';
360 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
362 $request = new Request();
364 $request->initialize(array(), array(), array(), array(), array(), $server);
366 $this->assertEquals('http://host:8080/index.php/path/info?query=string', $request->getUri(), '->getUri() with non default port');
368 // Use std port number
369 $server['HTTP_HOST'] = 'host';
370 $server['SERVER_NAME'] = 'servername';
371 $server['SERVER_PORT'] = '80';
373 $request->initialize(array(), array(), array(), array(), array(), $server);
375 $this->assertEquals('http://host/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port');
377 // Without HOST HEADER
378 unset($server['HTTP_HOST']);
379 $server['SERVER_NAME'] = 'servername';
380 $server['SERVER_PORT'] = '80';
382 $request->initialize(array(), array(), array(), array(), array(), $server);
384 $this->assertEquals('http://servername/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port without HOST_HEADER');
386 // Request with URL REWRITING (hide index.php)
387 // RewriteCond %{REQUEST_FILENAME} !-f
388 // RewriteRule ^(.*)$ index.php [QSA,L]
389 // http://host:8080/path/info?query=string
391 $server['HTTP_HOST'] = 'host:8080';
392 $server['SERVER_NAME'] = 'servername';
393 $server['SERVER_PORT'] = '8080';
395 $server['REDIRECT_QUERY_STRING'] = 'query=string';
396 $server['REDIRECT_URL'] = '/path/info';
397 $server['SCRIPT_NAME'] = '/index.php';
398 $server['QUERY_STRING'] = 'query=string';
399 $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
400 $server['SCRIPT_NAME'] = '/index.php';
401 $server['PHP_SELF'] = '/index.php';
402 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
404 $request->initialize(array(), array(), array(), array(), array(), $server);
405 $this->assertEquals('http://host:8080/path/info?query=string', $request->getUri(), '->getUri() with rewrite');
407 // Use std port number
408 // http://host/path/info?query=string
409 $server['HTTP_HOST'] = 'host';
410 $server['SERVER_NAME'] = 'servername';
411 $server['SERVER_PORT'] = '80';
413 $request->initialize(array(), array(), array(), array(), array(), $server);
415 $this->assertEquals('http://host/path/info?query=string', $request->getUri(), '->getUri() with rewrite and default port');
417 // Without HOST HEADER
418 unset($server['HTTP_HOST']);
419 $server['SERVER_NAME'] = 'servername';
420 $server['SERVER_PORT'] = '80';
422 $request->initialize(array(), array(), array(), array(), array(), $server);
424 $this->assertEquals('http://servername/path/info?query=string', $request->getUri(), '->getUri() with rewrite, default port without HOST_HEADER');
426 // With encoded characters
429 'HTTP_HOST' => 'host:8080',
430 'SERVER_NAME' => 'servername',
431 'SERVER_PORT' => '8080',
432 'QUERY_STRING' => 'query=string',
433 'REQUEST_URI' => '/ba%20se/index_dev.php/foo%20bar/in+fo?query=string',
434 'SCRIPT_NAME' => '/ba se/index_dev.php',
435 'PATH_TRANSLATED' => 'redirect:/index.php/foo bar/in+fo',
436 'PHP_SELF' => '/ba se/index_dev.php/path/info',
437 'SCRIPT_FILENAME' => '/some/where/ba se/index_dev.php',
440 $request->initialize(array(), array(), array(), array(), array(), $server);
443 'http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string',
449 $server['PHP_AUTH_USER'] = 'fabien';
450 $request->initialize(array(), array(), array(), array(), array(), $server);
451 $this->assertEquals('http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri());
453 $server['PHP_AUTH_PW'] = 'symfony';
454 $request->initialize(array(), array(), array(), array(), array(), $server);
455 $this->assertEquals('http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri());
458 public function testGetUriForPath()
460 $request = Request::create('http://test.com/foo?bar=baz');
461 $this->assertEquals('http://test.com/some/path', $request->getUriForPath('/some/path'));
463 $request = Request::create('http://test.com:90/foo?bar=baz');
464 $this->assertEquals('http://test.com:90/some/path', $request->getUriForPath('/some/path'));
466 $request = Request::create('https://test.com/foo?bar=baz');
467 $this->assertEquals('https://test.com/some/path', $request->getUriForPath('/some/path'));
469 $request = Request::create('https://test.com:90/foo?bar=baz');
470 $this->assertEquals('https://test.com:90/some/path', $request->getUriForPath('/some/path'));
474 // Standard Request on non default PORT
475 // http://host:8080/index.php/path/info?query=string
477 $server['HTTP_HOST'] = 'host:8080';
478 $server['SERVER_NAME'] = 'servername';
479 $server['SERVER_PORT'] = '8080';
481 $server['QUERY_STRING'] = 'query=string';
482 $server['REQUEST_URI'] = '/index.php/path/info?query=string';
483 $server['SCRIPT_NAME'] = '/index.php';
484 $server['PATH_INFO'] = '/path/info';
485 $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
486 $server['PHP_SELF'] = '/index_dev.php/path/info';
487 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
489 $request = new Request();
491 $request->initialize(array(), array(), array(), array(), array(), $server);
493 $this->assertEquals('http://host:8080/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with non default port');
495 // Use std port number
496 $server['HTTP_HOST'] = 'host';
497 $server['SERVER_NAME'] = 'servername';
498 $server['SERVER_PORT'] = '80';
500 $request->initialize(array(), array(), array(), array(), array(), $server);
502 $this->assertEquals('http://host/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port');
504 // Without HOST HEADER
505 unset($server['HTTP_HOST']);
506 $server['SERVER_NAME'] = 'servername';
507 $server['SERVER_PORT'] = '80';
509 $request->initialize(array(), array(), array(), array(), array(), $server);
511 $this->assertEquals('http://servername/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port without HOST_HEADER');
513 // Request with URL REWRITING (hide index.php)
514 // RewriteCond %{REQUEST_FILENAME} !-f
515 // RewriteRule ^(.*)$ index.php [QSA,L]
516 // http://host:8080/path/info?query=string
518 $server['HTTP_HOST'] = 'host:8080';
519 $server['SERVER_NAME'] = 'servername';
520 $server['SERVER_PORT'] = '8080';
522 $server['REDIRECT_QUERY_STRING'] = 'query=string';
523 $server['REDIRECT_URL'] = '/path/info';
524 $server['SCRIPT_NAME'] = '/index.php';
525 $server['QUERY_STRING'] = 'query=string';
526 $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
527 $server['SCRIPT_NAME'] = '/index.php';
528 $server['PHP_SELF'] = '/index.php';
529 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
531 $request->initialize(array(), array(), array(), array(), array(), $server);
532 $this->assertEquals('http://host:8080/some/path', $request->getUriForPath('/some/path'), '->getUri() with rewrite');
534 // Use std port number
535 // http://host/path/info?query=string
536 $server['HTTP_HOST'] = 'host';
537 $server['SERVER_NAME'] = 'servername';
538 $server['SERVER_PORT'] = '80';
540 $request->initialize(array(), array(), array(), array(), array(), $server);
542 $this->assertEquals('http://host/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite and default port');
544 // Without HOST HEADER
545 unset($server['HTTP_HOST']);
546 $server['SERVER_NAME'] = 'servername';
547 $server['SERVER_PORT'] = '80';
549 $request->initialize(array(), array(), array(), array(), array(), $server);
551 $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite, default port without HOST_HEADER');
552 $this->assertEquals('servername', $request->getHttpHost());
556 $server['PHP_AUTH_USER'] = 'fabien';
557 $request->initialize(array(), array(), array(), array(), array(), $server);
558 $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'));
560 $server['PHP_AUTH_PW'] = 'symfony';
561 $request->initialize(array(), array(), array(), array(), array(), $server);
562 $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'));
566 * @dataProvider getRelativeUriForPathData()
568 public function testGetRelativeUriForPath($expected, $pathinfo, $path)
570 $this->assertEquals($expected, Request::create($pathinfo)->getRelativeUriForPath($path));
573 public function getRelativeUriForPathData()
576 array('me.png', '/foo', '/me.png'),
577 array('../me.png', '/foo/bar', '/me.png'),
578 array('me.png', '/foo/bar', '/foo/me.png'),
579 array('../baz/me.png', '/foo/bar/b', '/foo/baz/me.png'),
580 array('../../fooz/baz/me.png', '/foo/bar/b', '/fooz/baz/me.png'),
581 array('baz/me.png', '/foo/bar/b', 'baz/me.png'),
585 public function testGetUserInfo()
587 $request = new Request();
589 $server = array('PHP_AUTH_USER' => 'fabien');
590 $request->initialize(array(), array(), array(), array(), array(), $server);
591 $this->assertEquals('fabien', $request->getUserInfo());
593 $server['PHP_AUTH_USER'] = '0';
594 $request->initialize(array(), array(), array(), array(), array(), $server);
595 $this->assertEquals('0', $request->getUserInfo());
597 $server['PHP_AUTH_PW'] = '0';
598 $request->initialize(array(), array(), array(), array(), array(), $server);
599 $this->assertEquals('0:0', $request->getUserInfo());
602 public function testGetSchemeAndHttpHost()
604 $request = new Request();
607 $server['SERVER_NAME'] = 'servername';
608 $server['SERVER_PORT'] = '90';
609 $request->initialize(array(), array(), array(), array(), array(), $server);
610 $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
612 $server['PHP_AUTH_USER'] = 'fabien';
613 $request->initialize(array(), array(), array(), array(), array(), $server);
614 $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
616 $server['PHP_AUTH_USER'] = '0';
617 $request->initialize(array(), array(), array(), array(), array(), $server);
618 $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
620 $server['PHP_AUTH_PW'] = '0';
621 $request->initialize(array(), array(), array(), array(), array(), $server);
622 $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
626 * @dataProvider getQueryStringNormalizationData
628 public function testGetQueryString($query, $expectedQuery, $msg)
630 $request = new Request();
632 $request->server->set('QUERY_STRING', $query);
633 $this->assertSame($expectedQuery, $request->getQueryString(), $msg);
636 public function getQueryStringNormalizationData()
639 array('foo', 'foo', 'works with valueless parameters'),
640 array('foo=', 'foo=', 'includes a dangling equal sign'),
641 array('bar=&foo=bar', 'bar=&foo=bar', '->works with empty parameters'),
642 array('foo=bar&bar=', 'bar=&foo=bar', 'sorts keys alphabetically'),
644 // GET parameters, that are submitted from a HTML form, encode spaces as "+" by default (as defined in enctype application/x-www-form-urlencoded).
645 // PHP also converts "+" to spaces when filling the global _GET or when using the function parse_str.
646 array('him=John%20Doe&her=Jane+Doe', 'her=Jane%20Doe&him=John%20Doe', 'normalizes spaces in both encodings "%20" and "+"'),
648 array('foo[]=1&foo[]=2', 'foo%5B%5D=1&foo%5B%5D=2', 'allows array notation'),
649 array('foo=1&foo=2', 'foo=1&foo=2', 'allows repeated parameters'),
650 array('pa%3Dram=foo%26bar%3Dbaz&test=test', 'pa%3Dram=foo%26bar%3Dbaz&test=test', 'works with encoded delimiters'),
651 array('0', '0', 'allows "0"'),
652 array('Jane Doe&John%20Doe', 'Jane%20Doe&John%20Doe', 'normalizes encoding in keys'),
653 array('her=Jane Doe&him=John%20Doe', 'her=Jane%20Doe&him=John%20Doe', 'normalizes encoding in values'),
654 array('foo=bar&&&test&&', 'foo=bar&test', 'removes unneeded delimiters'),
655 array('formula=e=m*c^2', 'formula=e%3Dm%2Ac%5E2', 'correctly treats only the first "=" as delimiter and the next as value'),
657 // Ignore pairs with empty key, even if there was a value, e.g. "=value", as such nameless values cannot be retrieved anyway.
658 // PHP also does not include them when building _GET.
659 array('foo=bar&=a=b&=x=y', 'foo=bar', 'removes params with empty key'),
663 public function testGetQueryStringReturnsNull()
665 $request = new Request();
667 $this->assertNull($request->getQueryString(), '->getQueryString() returns null for non-existent query string');
669 $request->server->set('QUERY_STRING', '');
670 $this->assertNull($request->getQueryString(), '->getQueryString() returns null for empty query string');
673 public function testGetHost()
675 $request = new Request();
677 $request->initialize(array('foo' => 'bar'));
678 $this->assertEquals('', $request->getHost(), '->getHost() return empty string if not initialized');
680 $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.example.com'));
681 $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from Host Header');
683 // Host header with port number
684 $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.example.com:8080'));
685 $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from Host Header with port number');
688 $request->initialize(array(), array(), array(), array(), array(), array('SERVER_NAME' => 'www.example.com'));
689 $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from server name');
691 $request->initialize(array(), array(), array(), array(), array(), array('SERVER_NAME' => 'www.example.com', 'HTTP_HOST' => 'www.host.com'));
692 $this->assertEquals('www.host.com', $request->getHost(), '->getHost() value from Host header has priority over SERVER_NAME ');
695 public function testGetPort()
697 $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
698 'HTTP_X_FORWARDED_PROTO' => 'https',
699 'HTTP_X_FORWARDED_PORT' => '443',
701 $port = $request->getPort();
703 $this->assertEquals(80, $port, 'Without trusted proxies FORWARDED_PROTO and FORWARDED_PORT are ignored.');
705 Request::setTrustedProxies(array('1.1.1.1'));
706 $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
707 'HTTP_X_FORWARDED_PROTO' => 'https',
708 'HTTP_X_FORWARDED_PORT' => '8443',
710 $this->assertEquals(80, $request->getPort(), 'With PROTO and PORT on untrusted connection server value takes precedence.');
711 $request->server->set('REMOTE_ADDR', '1.1.1.1');
712 $this->assertEquals(8443, $request->getPort(), 'With PROTO and PORT set PORT takes precedence.');
714 $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
715 'HTTP_X_FORWARDED_PROTO' => 'https',
717 $this->assertEquals(80, $request->getPort(), 'With only PROTO set getPort() ignores trusted headers on untrusted connection.');
718 $request->server->set('REMOTE_ADDR', '1.1.1.1');
719 $this->assertEquals(443, $request->getPort(), 'With only PROTO set getPort() defaults to 443.');
721 $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
722 'HTTP_X_FORWARDED_PROTO' => 'http',
724 $this->assertEquals(80, $request->getPort(), 'If X_FORWARDED_PROTO is set to HTTP getPort() ignores trusted headers on untrusted connection.');
725 $request->server->set('REMOTE_ADDR', '1.1.1.1');
726 $this->assertEquals(80, $request->getPort(), 'If X_FORWARDED_PROTO is set to HTTP getPort() returns port of the original request.');
728 $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
729 'HTTP_X_FORWARDED_PROTO' => 'On',
731 $this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is On, getPort() ignores trusted headers on untrusted connection.');
732 $request->server->set('REMOTE_ADDR', '1.1.1.1');
733 $this->assertEquals(443, $request->getPort(), 'With only PROTO set and value is On, getPort() defaults to 443.');
735 $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
736 'HTTP_X_FORWARDED_PROTO' => '1',
738 $this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is 1, getPort() ignores trusted headers on untrusted connection.');
739 $request->server->set('REMOTE_ADDR', '1.1.1.1');
740 $this->assertEquals(443, $request->getPort(), 'With only PROTO set and value is 1, getPort() defaults to 443.');
742 $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
743 'HTTP_X_FORWARDED_PROTO' => 'something-else',
745 $port = $request->getPort();
746 $this->assertEquals(80, $port, 'With only PROTO set and value is not recognized, getPort() defaults to 80.');
748 Request::setTrustedProxies(array());
752 * @expectedException \RuntimeException
754 public function testGetHostWithFakeHttpHostValue()
756 $request = new Request();
757 $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.host.com?query=string'));
761 public function testGetSetMethod()
763 $request = new Request();
765 $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns GET if no method is defined');
767 $request->setMethod('get');
768 $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns an uppercased string');
770 $request->setMethod('PURGE');
771 $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method even if it is not a standard one');
773 $request->setMethod('POST');
774 $this->assertEquals('POST', $request->getMethod(), '->getMethod() returns the method POST if no _method is defined');
776 $request->setMethod('POST');
777 $request->request->set('_method', 'purge');
778 $this->assertEquals('POST', $request->getMethod(), '->getMethod() does not return the method from _method if defined and POST but support not enabled');
780 $request = new Request();
781 $request->setMethod('POST');
782 $request->request->set('_method', 'purge');
784 $this->assertFalse(Request::getHttpMethodParameterOverride(), 'httpMethodParameterOverride should be disabled by default');
786 Request::enableHttpMethodParameterOverride();
788 $this->assertTrue(Request::getHttpMethodParameterOverride(), 'httpMethodParameterOverride should be enabled now but it is not');
790 $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method from _method if defined and POST');
791 $this->disableHttpMethodParameterOverride();
793 $request = new Request();
794 $request->setMethod('POST');
795 $request->query->set('_method', 'purge');
796 $this->assertEquals('POST', $request->getMethod(), '->getMethod() does not return the method from _method if defined and POST but support not enabled');
798 $request = new Request();
799 $request->setMethod('POST');
800 $request->query->set('_method', 'purge');
801 Request::enableHttpMethodParameterOverride();
802 $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method from _method if defined and POST');
803 $this->disableHttpMethodParameterOverride();
805 $request = new Request();
806 $request->setMethod('POST');
807 $request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete');
808 $this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override even though _method is set if defined and POST');
810 $request = new Request();
811 $request->setMethod('POST');
812 $request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete');
813 $this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override if defined and POST');
817 * @dataProvider getClientIpsProvider
819 public function testGetClientIp($expected, $remoteAddr, $httpForwardedFor, $trustedProxies)
821 $request = $this->getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies);
823 $this->assertEquals($expected[0], $request->getClientIp());
825 Request::setTrustedProxies(array());
829 * @dataProvider getClientIpsProvider
831 public function testGetClientIps($expected, $remoteAddr, $httpForwardedFor, $trustedProxies)
833 $request = $this->getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies);
835 $this->assertEquals($expected, $request->getClientIps());
837 Request::setTrustedProxies(array());
841 * @dataProvider getClientIpsForwardedProvider
843 public function testGetClientIpsForwarded($expected, $remoteAddr, $httpForwarded, $trustedProxies)
845 $request = $this->getRequestInstanceForClientIpsForwardedTests($remoteAddr, $httpForwarded, $trustedProxies);
847 $this->assertEquals($expected, $request->getClientIps());
849 Request::setTrustedProxies(array());
852 public function getClientIpsForwardedProvider()
854 // $expected $remoteAddr $httpForwarded $trustedProxies
856 array(array('127.0.0.1'), '127.0.0.1', 'for="_gazonk"', null),
857 array(array('127.0.0.1'), '127.0.0.1', 'for="_gazonk"', array('127.0.0.1')),
858 array(array('88.88.88.88'), '127.0.0.1', 'for="88.88.88.88:80"', array('127.0.0.1')),
859 array(array('192.0.2.60'), '::1', 'for=192.0.2.60;proto=http;by=203.0.113.43', array('::1')),
860 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')),
861 array(array('2001:db8:cafe::17'), '::1', 'for="[2001:db8:cafe::17]:4711', array('::1')),
865 public function getClientIpsProvider()
867 // $expected $remoteAddr $httpForwardedFor $trustedProxies
870 array(array('88.88.88.88'), '88.88.88.88', null, null),
871 // trust the IPv4 remote addr
872 array(array('88.88.88.88'), '88.88.88.88', null, array('88.88.88.88')),
875 array(array('::1'), '::1', null, null),
876 // trust the IPv6 remote addr
877 array(array('::1'), '::1', null, array('::1')),
879 // forwarded for with remote IPv4 addr not trusted
880 array(array('127.0.0.1'), '127.0.0.1', '88.88.88.88', null),
881 // forwarded for with remote IPv4 addr trusted
882 array(array('88.88.88.88'), '127.0.0.1', '88.88.88.88', array('127.0.0.1')),
883 // forwarded for with remote IPv4 and all FF addrs trusted
884 array(array('88.88.88.88'), '127.0.0.1', '88.88.88.88', array('127.0.0.1', '88.88.88.88')),
885 // forwarded for with remote IPv4 range trusted
886 array(array('88.88.88.88'), '123.45.67.89', '88.88.88.88', array('123.45.67.0/24')),
888 // forwarded for with remote IPv6 addr not trusted
889 array(array('1620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '2620:0:1cfe:face:b00c::3', null),
890 // forwarded for with remote IPv6 addr trusted
891 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')),
892 // forwarded for with remote IPv6 range trusted
893 array(array('88.88.88.88'), '2a01:198:603:0:396e:4789:8e99:890f', '88.88.88.88', array('2a01:198:603:0::/65')),
895 // multiple forwarded for with remote IPv4 addr trusted
896 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')),
897 // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted
898 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')),
899 // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted but in the middle
900 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')),
901 // multiple forwarded for with remote IPv4 addr and all reverse proxies trusted
902 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')),
904 // multiple forwarded for with remote IPv6 addr trusted
905 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')),
906 // multiple forwarded for with remote IPv6 addr and some reverse proxies trusted
907 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')),
908 // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted but in the middle
909 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')),
911 // client IP with port
912 array(array('88.88.88.88'), '127.0.0.1', '88.88.88.88:12345, 127.0.0.1', array('127.0.0.1')),
914 // invalid forwarded IP is ignored
915 array(array('88.88.88.88'), '127.0.0.1', 'unknown,88.88.88.88', array('127.0.0.1')),
916 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')),
921 * @expectedException \Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException
922 * @dataProvider getClientIpsWithConflictingHeadersProvider
924 public function testGetClientIpsWithConflictingHeaders($httpForwarded, $httpXForwardedFor)
926 $request = new Request();
929 'REMOTE_ADDR' => '88.88.88.88',
930 'HTTP_FORWARDED' => $httpForwarded,
931 'HTTP_X_FORWARDED_FOR' => $httpXForwardedFor,
934 Request::setTrustedProxies(array('88.88.88.88'));
936 $request->initialize(array(), array(), array(), array(), array(), $server);
938 $request->getClientIps();
941 public function getClientIpsWithConflictingHeadersProvider()
943 // $httpForwarded $httpXForwardedFor
945 array('for=87.65.43.21', '192.0.2.60'),
946 array('for=87.65.43.21, for=192.0.2.60', '192.0.2.60'),
947 array('for=192.0.2.60', '192.0.2.60,87.65.43.21'),
948 array('for="::face", for=192.0.2.60', '192.0.2.60,192.0.2.43'),
949 array('for=87.65.43.21, for=192.0.2.60', '192.0.2.60,87.65.43.21'),
954 * @dataProvider getClientIpsWithAgreeingHeadersProvider
956 public function testGetClientIpsWithAgreeingHeaders($httpForwarded, $httpXForwardedFor, $expectedIps)
958 $request = new Request();
961 'REMOTE_ADDR' => '88.88.88.88',
962 'HTTP_FORWARDED' => $httpForwarded,
963 'HTTP_X_FORWARDED_FOR' => $httpXForwardedFor,
966 Request::setTrustedProxies(array('88.88.88.88'));
968 $request->initialize(array(), array(), array(), array(), array(), $server);
970 $clientIps = $request->getClientIps();
972 Request::setTrustedProxies(array());
974 $this->assertSame($expectedIps, $clientIps);
977 public function getClientIpsWithAgreeingHeadersProvider()
979 // $httpForwarded $httpXForwardedFor
981 array('for="192.0.2.60"', '192.0.2.60', array('192.0.2.60')),
982 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')),
983 array('for="[::face]", for=192.0.2.60', '::face,192.0.2.60', array('192.0.2.60', '::face')),
984 array('for="192.0.2.60:80"', '192.0.2.60', array('192.0.2.60')),
985 array('for=192.0.2.60;proto=http;by=203.0.113.43', '192.0.2.60', array('192.0.2.60')),
986 array('for="[2001:db8:cafe::17]:4711"', '2001:db8:cafe::17', array('2001:db8:cafe::17')),
990 public function testGetContentWorksTwiceInDefaultMode()
992 $req = new Request();
993 $this->assertEquals('', $req->getContent());
994 $this->assertEquals('', $req->getContent());
997 public function testGetContentReturnsResource()
999 $req = new Request();
1000 $retval = $req->getContent(true);
1001 $this->assertInternalType('resource', $retval);
1002 $this->assertEquals('', fread($retval, 1));
1003 $this->assertTrue(feof($retval));
1006 public function testGetContentReturnsResourceWhenContentSetInConstructor()
1008 $req = new Request(array(), array(), array(), array(), array(), array(), 'MyContent');
1009 $resource = $req->getContent(true);
1011 $this->assertInternalType('resource', $resource);
1012 $this->assertEquals('MyContent', stream_get_contents($resource));
1015 public function testContentAsResource()
1017 $resource = fopen('php://memory', 'r+');
1018 fwrite($resource, 'My other content');
1021 $req = new Request(array(), array(), array(), array(), array(), array(), $resource);
1022 $this->assertEquals('My other content', stream_get_contents($req->getContent(true)));
1023 $this->assertEquals('My other content', $req->getContent());
1027 * @expectedException \LogicException
1028 * @dataProvider getContentCantBeCalledTwiceWithResourcesProvider
1030 public function testGetContentCantBeCalledTwiceWithResources($first, $second)
1032 if (\PHP_VERSION_ID >= 50600) {
1033 $this->markTestSkipped('PHP >= 5.6 allows to open php://input several times.');
1036 $req = new Request();
1037 $req->getContent($first);
1038 $req->getContent($second);
1041 public function getContentCantBeCalledTwiceWithResourcesProvider()
1044 'Resource then fetch' => array(true, false),
1045 'Resource then resource' => array(true, true),
1050 * @dataProvider getContentCanBeCalledTwiceWithResourcesProvider
1053 public function testGetContentCanBeCalledTwiceWithResources($first, $second)
1055 $req = new Request();
1056 $a = $req->getContent($first);
1057 $b = $req->getContent($second);
1060 $a = stream_get_contents($a);
1064 $b = stream_get_contents($b);
1067 $this->assertSame($a, $b);
1070 public function getContentCanBeCalledTwiceWithResourcesProvider()
1073 'Fetch then fetch' => array(false, false),
1074 'Fetch then resource' => array(false, true),
1075 'Resource then fetch' => array(true, false),
1076 'Resource then resource' => array(true, true),
1080 public function provideOverloadedMethods()
1093 * @dataProvider provideOverloadedMethods
1095 public function testCreateFromGlobals($method)
1097 $normalizedMethod = strtoupper($method);
1099 $_GET['foo1'] = 'bar1';
1100 $_POST['foo2'] = 'bar2';
1101 $_COOKIE['foo3'] = 'bar3';
1102 $_FILES['foo4'] = array('bar4');
1103 $_SERVER['foo5'] = 'bar5';
1105 $request = Request::createFromGlobals();
1106 $this->assertEquals('bar1', $request->query->get('foo1'), '::fromGlobals() uses values from $_GET');
1107 $this->assertEquals('bar2', $request->request->get('foo2'), '::fromGlobals() uses values from $_POST');
1108 $this->assertEquals('bar3', $request->cookies->get('foo3'), '::fromGlobals() uses values from $_COOKIE');
1109 $this->assertEquals(array('bar4'), $request->files->get('foo4'), '::fromGlobals() uses values from $_FILES');
1110 $this->assertEquals('bar5', $request->server->get('foo5'), '::fromGlobals() uses values from $_SERVER');
1112 unset($_GET['foo1'], $_POST['foo2'], $_COOKIE['foo3'], $_FILES['foo4'], $_SERVER['foo5']);
1114 $_SERVER['REQUEST_METHOD'] = $method;
1115 $_SERVER['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
1116 $request = RequestContentProxy::createFromGlobals();
1117 $this->assertEquals($normalizedMethod, $request->getMethod());
1118 $this->assertEquals('mycontent', $request->request->get('content'));
1120 unset($_SERVER['REQUEST_METHOD'], $_SERVER['CONTENT_TYPE']);
1122 Request::createFromGlobals();
1123 Request::enableHttpMethodParameterOverride();
1124 $_POST['_method'] = $method;
1125 $_POST['foo6'] = 'bar6';
1126 $_SERVER['REQUEST_METHOD'] = 'PoSt';
1127 $request = Request::createFromGlobals();
1128 $this->assertEquals($normalizedMethod, $request->getMethod());
1129 $this->assertEquals('POST', $request->getRealMethod());
1130 $this->assertEquals('bar6', $request->request->get('foo6'));
1132 unset($_POST['_method'], $_POST['foo6'], $_SERVER['REQUEST_METHOD']);
1133 $this->disableHttpMethodParameterOverride();
1136 public function testOverrideGlobals()
1138 $request = new Request();
1139 $request->initialize(array('foo' => 'bar'));
1141 // as the Request::overrideGlobals really work, it erase $_SERVER, so we must backup it
1144 $request->overrideGlobals();
1146 $this->assertEquals(array('foo' => 'bar'), $_GET);
1148 $request->initialize(array(), array('foo' => 'bar'));
1149 $request->overrideGlobals();
1151 $this->assertEquals(array('foo' => 'bar'), $_POST);
1153 $this->assertArrayNotHasKey('HTTP_X_FORWARDED_PROTO', $_SERVER);
1155 $request->headers->set('X_FORWARDED_PROTO', 'https');
1157 Request::setTrustedProxies(array('1.1.1.1'));
1158 $this->assertFalse($request->isSecure());
1159 $request->server->set('REMOTE_ADDR', '1.1.1.1');
1160 $this->assertTrue($request->isSecure());
1161 Request::setTrustedProxies(array());
1163 $request->overrideGlobals();
1165 $this->assertArrayHasKey('HTTP_X_FORWARDED_PROTO', $_SERVER);
1167 $request->headers->set('CONTENT_TYPE', 'multipart/form-data');
1168 $request->headers->set('CONTENT_LENGTH', 12345);
1170 $request->overrideGlobals();
1172 $this->assertArrayHasKey('CONTENT_TYPE', $_SERVER);
1173 $this->assertArrayHasKey('CONTENT_LENGTH', $_SERVER);
1175 $request->initialize(array('foo' => 'bar', 'baz' => 'foo'));
1176 $request->query->remove('baz');
1178 $request->overrideGlobals();
1180 $this->assertEquals(array('foo' => 'bar'), $_GET);
1181 $this->assertEquals('foo=bar', $_SERVER['QUERY_STRING']);
1182 $this->assertEquals('foo=bar', $request->server->get('QUERY_STRING'));
1184 // restore initial $_SERVER array
1188 public function testGetScriptName()
1190 $request = new Request();
1191 $this->assertEquals('', $request->getScriptName());
1194 $server['SCRIPT_NAME'] = '/index.php';
1196 $request->initialize(array(), array(), array(), array(), array(), $server);
1198 $this->assertEquals('/index.php', $request->getScriptName());
1201 $server['ORIG_SCRIPT_NAME'] = '/frontend.php';
1202 $request->initialize(array(), array(), array(), array(), array(), $server);
1204 $this->assertEquals('/frontend.php', $request->getScriptName());
1207 $server['SCRIPT_NAME'] = '/index.php';
1208 $server['ORIG_SCRIPT_NAME'] = '/frontend.php';
1209 $request->initialize(array(), array(), array(), array(), array(), $server);
1211 $this->assertEquals('/index.php', $request->getScriptName());
1214 public function testGetBasePath()
1216 $request = new Request();
1217 $this->assertEquals('', $request->getBasePath());
1220 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
1221 $request->initialize(array(), array(), array(), array(), array(), $server);
1222 $this->assertEquals('', $request->getBasePath());
1225 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
1226 $server['SCRIPT_NAME'] = '/index.php';
1227 $request->initialize(array(), array(), array(), array(), array(), $server);
1229 $this->assertEquals('', $request->getBasePath());
1232 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
1233 $server['PHP_SELF'] = '/index.php';
1234 $request->initialize(array(), array(), array(), array(), array(), $server);
1236 $this->assertEquals('', $request->getBasePath());
1239 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
1240 $server['ORIG_SCRIPT_NAME'] = '/index.php';
1241 $request->initialize(array(), array(), array(), array(), array(), $server);
1243 $this->assertEquals('', $request->getBasePath());
1246 public function testGetPathInfo()
1248 $request = new Request();
1249 $this->assertEquals('/', $request->getPathInfo());
1252 $server['REQUEST_URI'] = '/path/info';
1253 $request->initialize(array(), array(), array(), array(), array(), $server);
1255 $this->assertEquals('/path/info', $request->getPathInfo());
1258 $server['REQUEST_URI'] = '/path%20test/info';
1259 $request->initialize(array(), array(), array(), array(), array(), $server);
1261 $this->assertEquals('/path%20test/info', $request->getPathInfo());
1264 $server['REQUEST_URI'] = '?a=b';
1265 $request->initialize(array(), array(), array(), array(), array(), $server);
1267 $this->assertEquals('/', $request->getPathInfo());
1270 public function testGetPreferredLanguage()
1272 $request = new Request();
1273 $this->assertNull($request->getPreferredLanguage());
1274 $this->assertNull($request->getPreferredLanguage(array()));
1275 $this->assertEquals('fr', $request->getPreferredLanguage(array('fr')));
1276 $this->assertEquals('fr', $request->getPreferredLanguage(array('fr', 'en')));
1277 $this->assertEquals('en', $request->getPreferredLanguage(array('en', 'fr')));
1278 $this->assertEquals('fr-ch', $request->getPreferredLanguage(array('fr-ch', 'fr-fr')));
1280 $request = new Request();
1281 $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
1282 $this->assertEquals('en', $request->getPreferredLanguage(array('en', 'en-us')));
1284 $request = new Request();
1285 $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
1286 $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));
1288 $request = new Request();
1289 $request->headers->set('Accept-language', 'zh, en-us; q=0.8');
1290 $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));
1292 $request = new Request();
1293 $request->headers->set('Accept-language', 'zh, en-us; q=0.8, fr-fr; q=0.6, fr; q=0.5');
1294 $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));
1297 public function testIsXmlHttpRequest()
1299 $request = new Request();
1300 $this->assertFalse($request->isXmlHttpRequest());
1302 $request->headers->set('X-Requested-With', 'XMLHttpRequest');
1303 $this->assertTrue($request->isXmlHttpRequest());
1305 $request->headers->remove('X-Requested-With');
1306 $this->assertFalse($request->isXmlHttpRequest());
1310 * @requires extension intl
1312 public function testIntlLocale()
1314 $request = new Request();
1316 $request->setDefaultLocale('fr');
1317 $this->assertEquals('fr', $request->getLocale());
1318 $this->assertEquals('fr', \Locale::getDefault());
1320 $request->setLocale('en');
1321 $this->assertEquals('en', $request->getLocale());
1322 $this->assertEquals('en', \Locale::getDefault());
1324 $request->setDefaultLocale('de');
1325 $this->assertEquals('en', $request->getLocale());
1326 $this->assertEquals('en', \Locale::getDefault());
1329 public function testGetCharsets()
1331 $request = new Request();
1332 $this->assertEquals(array(), $request->getCharsets());
1333 $request->headers->set('Accept-Charset', 'ISO-8859-1, US-ASCII, UTF-8; q=0.8, ISO-10646-UCS-2; q=0.6');
1334 $this->assertEquals(array(), $request->getCharsets()); // testing caching
1336 $request = new Request();
1337 $request->headers->set('Accept-Charset', 'ISO-8859-1, US-ASCII, UTF-8; q=0.8, ISO-10646-UCS-2; q=0.6');
1338 $this->assertEquals(array('ISO-8859-1', 'US-ASCII', 'UTF-8', 'ISO-10646-UCS-2'), $request->getCharsets());
1340 $request = new Request();
1341 $request->headers->set('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7');
1342 $this->assertEquals(array('ISO-8859-1', 'utf-8', '*'), $request->getCharsets());
1345 public function testGetEncodings()
1347 $request = new Request();
1348 $this->assertEquals(array(), $request->getEncodings());
1349 $request->headers->set('Accept-Encoding', 'gzip,deflate,sdch');
1350 $this->assertEquals(array(), $request->getEncodings()); // testing caching
1352 $request = new Request();
1353 $request->headers->set('Accept-Encoding', 'gzip,deflate,sdch');
1354 $this->assertEquals(array('gzip', 'deflate', 'sdch'), $request->getEncodings());
1356 $request = new Request();
1357 $request->headers->set('Accept-Encoding', 'gzip;q=0.4,deflate;q=0.9,compress;q=0.7');
1358 $this->assertEquals(array('deflate', 'compress', 'gzip'), $request->getEncodings());
1361 public function testGetAcceptableContentTypes()
1363 $request = new Request();
1364 $this->assertEquals(array(), $request->getAcceptableContentTypes());
1365 $request->headers->set('Accept', 'application/vnd.wap.wmlscriptc, text/vnd.wap.wml, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html, multipart/mixed, */*');
1366 $this->assertEquals(array(), $request->getAcceptableContentTypes()); // testing caching
1368 $request = new Request();
1369 $request->headers->set('Accept', 'application/vnd.wap.wmlscriptc, text/vnd.wap.wml, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html, multipart/mixed, */*');
1370 $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());
1373 public function testGetLanguages()
1375 $request = new Request();
1376 $this->assertEquals(array(), $request->getLanguages());
1378 $request = new Request();
1379 $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
1380 $this->assertEquals(array('zh', 'en_US', 'en'), $request->getLanguages());
1381 $this->assertEquals(array('zh', 'en_US', 'en'), $request->getLanguages());
1383 $request = new Request();
1384 $request->headers->set('Accept-language', 'zh, en-us; q=0.6, en; q=0.8');
1385 $this->assertEquals(array('zh', 'en', 'en_US'), $request->getLanguages()); // Test out of order qvalues
1387 $request = new Request();
1388 $request->headers->set('Accept-language', 'zh, en, en-us');
1389 $this->assertEquals(array('zh', 'en', 'en_US'), $request->getLanguages()); // Test equal weighting without qvalues
1391 $request = new Request();
1392 $request->headers->set('Accept-language', 'zh; q=0.6, en, en-us; q=0.6');
1393 $this->assertEquals(array('en', 'zh', 'en_US'), $request->getLanguages()); // Test equal weighting with qvalues
1395 $request = new Request();
1396 $request->headers->set('Accept-language', 'zh, i-cherokee; q=0.6');
1397 $this->assertEquals(array('zh', 'cherokee'), $request->getLanguages());
1400 public function testGetRequestFormat()
1402 $request = new Request();
1403 $this->assertEquals('html', $request->getRequestFormat());
1405 // Ensure that setting different default values over time is possible,
1406 // aka. setRequestFormat determines the state.
1407 $this->assertEquals('json', $request->getRequestFormat('json'));
1408 $this->assertEquals('html', $request->getRequestFormat('html'));
1410 $request = new Request();
1411 $this->assertNull($request->getRequestFormat(null));
1413 $request = new Request();
1414 $this->assertNull($request->setRequestFormat('foo'));
1415 $this->assertEquals('foo', $request->getRequestFormat(null));
1418 public function testHasSession()
1420 $request = new Request();
1422 $this->assertFalse($request->hasSession());
1423 $request->setSession(new Session(new MockArraySessionStorage()));
1424 $this->assertTrue($request->hasSession());
1427 public function testGetSession()
1429 $request = new Request();
1431 $request->setSession(new Session(new MockArraySessionStorage()));
1432 $this->assertTrue($request->hasSession());
1434 $session = $request->getSession();
1435 $this->assertObjectHasAttribute('storage', $session);
1436 $this->assertObjectHasAttribute('flashName', $session);
1437 $this->assertObjectHasAttribute('attributeName', $session);
1440 public function testHasPreviousSession()
1442 $request = new Request();
1444 $this->assertFalse($request->hasPreviousSession());
1445 $request->cookies->set('MOCKSESSID', 'foo');
1446 $this->assertFalse($request->hasPreviousSession());
1447 $request->setSession(new Session(new MockArraySessionStorage()));
1448 $this->assertTrue($request->hasPreviousSession());
1451 public function testToString()
1453 $request = new Request();
1455 $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
1457 $this->assertContains('Accept-Language: zh, en-us; q=0.8, en; q=0.6', $request->__toString());
1460 public function testIsMethod()
1462 $request = new Request();
1463 $request->setMethod('POST');
1464 $this->assertTrue($request->isMethod('POST'));
1465 $this->assertTrue($request->isMethod('post'));
1466 $this->assertFalse($request->isMethod('GET'));
1467 $this->assertFalse($request->isMethod('get'));
1469 $request->setMethod('GET');
1470 $this->assertTrue($request->isMethod('GET'));
1471 $this->assertTrue($request->isMethod('get'));
1472 $this->assertFalse($request->isMethod('POST'));
1473 $this->assertFalse($request->isMethod('post'));
1477 * @dataProvider getBaseUrlData
1479 public function testGetBaseUrl($uri, $server, $expectedBaseUrl, $expectedPathInfo)
1481 $request = Request::create($uri, 'GET', array(), array(), array(), $server);
1483 $this->assertSame($expectedBaseUrl, $request->getBaseUrl(), 'baseUrl');
1484 $this->assertSame($expectedPathInfo, $request->getPathInfo(), 'pathInfo');
1487 public function getBaseUrlData()
1491 '/fruit/strawberry/1234index.php/blah',
1493 'SCRIPT_FILENAME' => 'E:/Sites/cc-new/public_html/fruit/index.php',
1494 'SCRIPT_NAME' => '/fruit/index.php',
1495 'PHP_SELF' => '/fruit/index.php',
1498 '/strawberry/1234index.php/blah',
1501 '/fruit/strawberry/1234index.php/blah',
1503 'SCRIPT_FILENAME' => 'E:/Sites/cc-new/public_html/index.php',
1504 'SCRIPT_NAME' => '/index.php',
1505 'PHP_SELF' => '/index.php',
1508 '/fruit/strawberry/1234index.php/blah',
1513 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
1514 'SCRIPT_NAME' => '/foo bar/app.php',
1515 'PHP_SELF' => '/foo bar/app.php',
1523 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
1524 'SCRIPT_NAME' => '/foo bar/app.php',
1525 'PHP_SELF' => '/foo bar/app.php',
1531 '/foo%20bar/app.php/home',
1533 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
1534 'SCRIPT_NAME' => '/foo bar/app.php',
1535 'PHP_SELF' => '/foo bar/app.php',
1537 '/foo%20bar/app.php',
1541 '/foo%20bar/app.php/home%3Dbaz',
1543 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
1544 'SCRIPT_NAME' => '/foo bar/app.php',
1545 'PHP_SELF' => '/foo bar/app.php',
1547 '/foo%20bar/app.php',
1553 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo/app.php',
1554 'SCRIPT_NAME' => '/foo/app.php',
1555 'PHP_SELF' => '/foo/app.php',
1564 * @dataProvider urlencodedStringPrefixData
1566 public function testUrlencodedStringPrefix($string, $prefix, $expect)
1568 $request = new Request();
1570 $me = new \ReflectionMethod($request, 'getUrlencodedPrefix');
1571 $me->setAccessible(true);
1573 $this->assertSame($expect, $me->invoke($request, $string, $prefix));
1576 public function urlencodedStringPrefixData()
1579 array('foo', 'foo', 'foo'),
1580 array('fo%6f', 'foo', 'fo%6f'),
1581 array('foo/bar', 'foo', 'foo'),
1582 array('fo%6f/bar', 'foo', 'fo%6f'),
1583 array('f%6f%6f/bar', 'foo', 'f%6f%6f'),
1584 array('%66%6F%6F/bar', 'foo', '%66%6F%6F'),
1585 array('fo+o/bar', 'fo+o', 'fo+o'),
1586 array('fo%2Bo/bar', 'fo+o', 'fo%2Bo'),
1590 private function disableHttpMethodParameterOverride()
1592 $class = new \ReflectionClass('Symfony\\Component\\HttpFoundation\\Request');
1593 $property = $class->getProperty('httpMethodParameterOverride');
1594 $property->setAccessible(true);
1595 $property->setValue(false);
1598 private function getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies)
1600 $request = new Request();
1602 $server = array('REMOTE_ADDR' => $remoteAddr);
1603 if (null !== $httpForwardedFor) {
1604 $server['HTTP_X_FORWARDED_FOR'] = $httpForwardedFor;
1607 if ($trustedProxies) {
1608 Request::setTrustedProxies($trustedProxies);
1611 $request->initialize(array(), array(), array(), array(), array(), $server);
1616 private function getRequestInstanceForClientIpsForwardedTests($remoteAddr, $httpForwarded, $trustedProxies)
1618 $request = new Request();
1620 $server = array('REMOTE_ADDR' => $remoteAddr);
1622 if (null !== $httpForwarded) {
1623 $server['HTTP_FORWARDED'] = $httpForwarded;
1626 if ($trustedProxies) {
1627 Request::setTrustedProxies($trustedProxies);
1630 $request->initialize(array(), array(), array(), array(), array(), $server);
1635 public function testTrustedProxiesXForwardedFor()
1637 $request = Request::create('http://example.com/');
1638 $request->server->set('REMOTE_ADDR', '3.3.3.3');
1639 $request->headers->set('X_FORWARDED_FOR', '1.1.1.1, 2.2.2.2');
1640 $request->headers->set('X_FORWARDED_HOST', 'foo.example.com:1234, real.example.com:8080');
1641 $request->headers->set('X_FORWARDED_PROTO', 'https');
1642 $request->headers->set('X_FORWARDED_PORT', 443);
1643 $request->headers->set('X_MY_FOR', '3.3.3.3, 4.4.4.4');
1644 $request->headers->set('X_MY_HOST', 'my.example.com');
1645 $request->headers->set('X_MY_PROTO', 'http');
1646 $request->headers->set('X_MY_PORT', 81);
1648 // no trusted proxies
1649 $this->assertEquals('3.3.3.3', $request->getClientIp());
1650 $this->assertEquals('example.com', $request->getHost());
1651 $this->assertEquals(80, $request->getPort());
1652 $this->assertFalse($request->isSecure());
1654 // disabling proxy trusting
1655 Request::setTrustedProxies(array());
1656 $this->assertEquals('3.3.3.3', $request->getClientIp());
1657 $this->assertEquals('example.com', $request->getHost());
1658 $this->assertEquals(80, $request->getPort());
1659 $this->assertFalse($request->isSecure());
1661 // request is forwarded by a non-trusted proxy
1662 Request::setTrustedProxies(array('2.2.2.2'));
1663 $this->assertEquals('3.3.3.3', $request->getClientIp());
1664 $this->assertEquals('example.com', $request->getHost());
1665 $this->assertEquals(80, $request->getPort());
1666 $this->assertFalse($request->isSecure());
1668 // trusted proxy via setTrustedProxies()
1669 Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'));
1670 $this->assertEquals('1.1.1.1', $request->getClientIp());
1671 $this->assertEquals('foo.example.com', $request->getHost());
1672 $this->assertEquals(443, $request->getPort());
1673 $this->assertTrue($request->isSecure());
1675 // trusted proxy via setTrustedProxies()
1676 Request::setTrustedProxies(array('3.3.3.4', '2.2.2.2'));
1677 $this->assertEquals('3.3.3.3', $request->getClientIp());
1678 $this->assertEquals('example.com', $request->getHost());
1679 $this->assertEquals(80, $request->getPort());
1680 $this->assertFalse($request->isSecure());
1682 // check various X_FORWARDED_PROTO header values
1683 Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'));
1684 $request->headers->set('X_FORWARDED_PROTO', 'ssl');
1685 $this->assertTrue($request->isSecure());
1687 $request->headers->set('X_FORWARDED_PROTO', 'https, http');
1688 $this->assertTrue($request->isSecure());
1690 // custom header names
1691 Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_MY_FOR');
1692 Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_MY_HOST');
1693 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_MY_PORT');
1694 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_MY_PROTO');
1695 $this->assertEquals('4.4.4.4', $request->getClientIp());
1696 $this->assertEquals('my.example.com', $request->getHost());
1697 $this->assertEquals(81, $request->getPort());
1698 $this->assertFalse($request->isSecure());
1700 // disabling via empty header names
1701 Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, null);
1702 Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, null);
1703 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, null);
1704 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, null);
1705 $this->assertEquals('3.3.3.3', $request->getClientIp());
1706 $this->assertEquals('example.com', $request->getHost());
1707 $this->assertEquals(80, $request->getPort());
1708 $this->assertFalse($request->isSecure());
1711 Request::setTrustedProxies(array());
1712 Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_FORWARDED_FOR');
1713 Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_FORWARDED_HOST');
1714 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_FORWARDED_PORT');
1715 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_FORWARDED_PROTO');
1718 public function testTrustedProxiesForwarded()
1720 $request = Request::create('http://example.com/');
1721 $request->server->set('REMOTE_ADDR', '3.3.3.3');
1722 $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');
1724 // no trusted proxies
1725 $this->assertEquals('3.3.3.3', $request->getClientIp());
1726 $this->assertEquals('example.com', $request->getHost());
1727 $this->assertEquals(80, $request->getPort());
1728 $this->assertFalse($request->isSecure());
1730 // disabling proxy trusting
1731 Request::setTrustedProxies(array());
1732 $this->assertEquals('3.3.3.3', $request->getClientIp());
1733 $this->assertEquals('example.com', $request->getHost());
1734 $this->assertEquals(80, $request->getPort());
1735 $this->assertFalse($request->isSecure());
1737 // request is forwarded by a non-trusted proxy
1738 Request::setTrustedProxies(array('2.2.2.2'));
1739 $this->assertEquals('3.3.3.3', $request->getClientIp());
1740 $this->assertEquals('example.com', $request->getHost());
1741 $this->assertEquals(80, $request->getPort());
1742 $this->assertFalse($request->isSecure());
1744 // trusted proxy via setTrustedProxies()
1745 Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'));
1746 $this->assertEquals('1.1.1.1', $request->getClientIp());
1747 $this->assertEquals('foo.example.com', $request->getHost());
1748 $this->assertEquals(8080, $request->getPort());
1749 $this->assertTrue($request->isSecure());
1751 // trusted proxy via setTrustedProxies()
1752 Request::setTrustedProxies(array('3.3.3.4', '2.2.2.2'));
1753 $this->assertEquals('3.3.3.3', $request->getClientIp());
1754 $this->assertEquals('example.com', $request->getHost());
1755 $this->assertEquals(80, $request->getPort());
1756 $this->assertFalse($request->isSecure());
1758 // check various X_FORWARDED_PROTO header values
1759 Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'));
1760 $request->headers->set('FORWARDED', 'proto=ssl');
1761 $this->assertTrue($request->isSecure());
1763 $request->headers->set('FORWARDED', 'proto=https, proto=http');
1764 $this->assertTrue($request->isSecure());
1768 * @expectedException \InvalidArgumentException
1770 public function testSetTrustedProxiesInvalidHeaderName()
1772 Request::create('http://example.com/');
1773 Request::setTrustedHeaderName('bogus name', 'X_MY_FOR');
1777 * @expectedException \InvalidArgumentException
1779 public function testGetTrustedProxiesInvalidHeaderName()
1781 Request::create('http://example.com/');
1782 Request::getTrustedHeaderName('bogus name');
1786 * @dataProvider iisRequestUriProvider
1788 public function testIISRequestUri($headers, $server, $expectedRequestUri)
1790 $request = new Request();
1791 $request->headers->replace($headers);
1792 $request->server->replace($server);
1794 $this->assertEquals($expectedRequestUri, $request->getRequestUri(), '->getRequestUri() is correct');
1796 $subRequestUri = '/bar/foo';
1797 $subRequest = Request::create($subRequestUri, 'get', array(), array(), array(), $request->server->all());
1798 $this->assertEquals($subRequestUri, $subRequest->getRequestUri(), '->getRequestUri() is correct in sub request');
1801 public function iisRequestUriProvider()
1806 'X_ORIGINAL_URL' => '/foo/bar',
1813 'X_REWRITE_URL' => '/foo/bar',
1821 'IIS_WasUrlRewritten' => '1',
1822 'UNENCODED_URL' => '/foo/bar',
1828 'X_ORIGINAL_URL' => '/foo/bar',
1831 'HTTP_X_ORIGINAL_URL' => '/foo/bar',
1837 'X_ORIGINAL_URL' => '/foo/bar',
1840 'IIS_WasUrlRewritten' => '1',
1841 'UNENCODED_URL' => '/foo/bar',
1847 'X_ORIGINAL_URL' => '/foo/bar',
1850 'HTTP_X_ORIGINAL_URL' => '/foo/bar',
1851 'IIS_WasUrlRewritten' => '1',
1852 'UNENCODED_URL' => '/foo/bar',
1859 'ORIG_PATH_INFO' => '/foo/bar',
1866 'ORIG_PATH_INFO' => '/foo/bar',
1867 'QUERY_STRING' => 'foo=bar',
1874 public function testTrustedHosts()
1877 $request = Request::create('/');
1879 // no trusted host set -> no host check
1880 $request->headers->set('host', 'evil.com');
1881 $this->assertEquals('evil.com', $request->getHost());
1883 // add a trusted domain and all its subdomains
1884 Request::setTrustedHosts(array('^([a-z]{9}\.)?trusted\.com$'));
1887 $request->headers->set('host', 'evil.com');
1889 $request->getHost();
1890 $this->fail('Request::getHost() should throw an exception when host is not trusted.');
1891 } catch (\UnexpectedValueException $e) {
1892 $this->assertEquals('Untrusted Host "evil.com"', $e->getMessage());
1896 $request->headers->set('host', 'trusted.com');
1897 $this->assertEquals('trusted.com', $request->getHost());
1898 $this->assertEquals(80, $request->getPort());
1900 $request->server->set('HTTPS', true);
1901 $request->headers->set('host', 'trusted.com');
1902 $this->assertEquals('trusted.com', $request->getHost());
1903 $this->assertEquals(443, $request->getPort());
1904 $request->server->set('HTTPS', false);
1906 $request->headers->set('host', 'trusted.com:8000');
1907 $this->assertEquals('trusted.com', $request->getHost());
1908 $this->assertEquals(8000, $request->getPort());
1910 $request->headers->set('host', 'subdomain.trusted.com');
1911 $this->assertEquals('subdomain.trusted.com', $request->getHost());
1913 // reset request for following tests
1914 Request::setTrustedHosts(array());
1917 public function testFactory()
1919 Request::setFactory(function (array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) {
1920 return new NewRequest();
1923 $this->assertEquals('foo', Request::create('/')->getFoo());
1925 Request::setFactory(null);
1929 * @dataProvider getLongHostNames
1931 public function testVeryLongHosts($host)
1933 $start = microtime(true);
1935 $request = Request::create('/');
1936 $request->headers->set('host', $host);
1937 $this->assertEquals($host, $request->getHost());
1938 $this->assertLessThan(5, microtime(true) - $start);
1942 * @dataProvider getHostValidities
1944 public function testHostValidity($host, $isValid, $expectedHost = null, $expectedPort = null)
1946 $request = Request::create('/');
1947 $request->headers->set('host', $host);
1950 $this->assertSame($expectedHost ?: $host, $request->getHost());
1951 if ($expectedPort) {
1952 $this->assertSame($expectedPort, $request->getPort());
1955 if (method_exists($this, 'expectException')) {
1956 $this->expectException('UnexpectedValueException');
1957 $this->expectExceptionMessage('Invalid Host');
1959 $this->setExpectedException('UnexpectedValueException', 'Invalid Host');
1962 $request->getHost();
1966 public function getHostValidities()
1970 array('a..', false),
1972 array("\xE9", false),
1973 array('[::1]', true),
1974 array('[::1]:80', true, '[::1]', 80),
1975 array(str_repeat('.', 101), false),
1979 public function getLongHostNames()
1982 array('a'.str_repeat('.a', 40000)),
1983 array(str_repeat(':', 101)),
1988 * @dataProvider methodSafeProvider
1990 public function testMethodSafe($method, $safe)
1992 $request = new Request();
1993 $request->setMethod($method);
1994 $this->assertEquals($safe, $request->isMethodSafe(false));
1997 public function methodSafeProvider()
2000 array('HEAD', true),
2002 array('POST', false),
2003 array('PUT', false),
2004 array('PATCH', false),
2005 array('DELETE', false),
2006 array('PURGE', false),
2007 array('OPTIONS', true),
2008 array('TRACE', true),
2009 array('CONNECT', false),
2013 public function testMethodSafeChecksCacheable()
2015 $request = new Request();
2016 $request->setMethod('OPTIONS');
2017 $this->assertFalse($request->isMethodSafe());
2021 * @dataProvider methodCacheableProvider
2023 public function testMethodCacheable($method, $chacheable)
2025 $request = new Request();
2026 $request->setMethod($method);
2027 $this->assertEquals($chacheable, $request->isMethodCacheable());
2030 public function methodCacheableProvider()
2033 array('HEAD', true),
2035 array('POST', false),
2036 array('PUT', false),
2037 array('PATCH', false),
2038 array('DELETE', false),
2039 array('PURGE', false),
2040 array('OPTIONS', false),
2041 array('TRACE', false),
2042 array('CONNECT', false),
2046 public function nonstandardRequestsData()
2049 array('', '', '/', 'http://host:8080/', ''),
2050 array('/', '', '/', 'http://host:8080/', ''),
2052 array('hello/app.php/x', '', '/x', 'http://host:8080/hello/app.php/x', '/hello', '/hello/app.php'),
2053 array('/hello/app.php/x', '', '/x', 'http://host:8080/hello/app.php/x', '/hello', '/hello/app.php'),
2055 array('', 'a=b', '/', 'http://host:8080/?a=b'),
2056 array('?a=b', 'a=b', '/', 'http://host:8080/?a=b'),
2057 array('/?a=b', 'a=b', '/', 'http://host:8080/?a=b'),
2059 array('x', 'a=b', '/x', 'http://host:8080/x?a=b'),
2060 array('x?a=b', 'a=b', '/x', 'http://host:8080/x?a=b'),
2061 array('/x?a=b', 'a=b', '/x', 'http://host:8080/x?a=b'),
2063 array('hello/x', '', '/x', 'http://host:8080/hello/x', '/hello'),
2064 array('/hello/x', '', '/x', 'http://host:8080/hello/x', '/hello'),
2066 array('hello/app.php/x', 'a=b', '/x', 'http://host:8080/hello/app.php/x?a=b', '/hello', '/hello/app.php'),
2067 array('hello/app.php/x?a=b', 'a=b', '/x', 'http://host:8080/hello/app.php/x?a=b', '/hello', '/hello/app.php'),
2068 array('/hello/app.php/x?a=b', 'a=b', '/x', 'http://host:8080/hello/app.php/x?a=b', '/hello', '/hello/app.php'),
2073 * @dataProvider nonstandardRequestsData
2075 public function testNonstandardRequests($requestUri, $queryString, $expectedPathInfo, $expectedUri, $expectedBasePath = '', $expectedBaseUrl = null)
2077 if (null === $expectedBaseUrl) {
2078 $expectedBaseUrl = $expectedBasePath;
2082 'HTTP_HOST' => 'host:8080',
2083 'SERVER_PORT' => '8080',
2084 'QUERY_STRING' => $queryString,
2085 'PHP_SELF' => '/hello/app.php',
2086 'SCRIPT_FILENAME' => '/some/path/app.php',
2087 'REQUEST_URI' => $requestUri,
2090 $request = new Request(array(), array(), array(), array(), array(), $server);
2092 $this->assertEquals($expectedPathInfo, $request->getPathInfo());
2093 $this->assertEquals($expectedUri, $request->getUri());
2094 $this->assertEquals($queryString, $request->getQueryString());
2095 $this->assertEquals(8080, $request->getPort());
2096 $this->assertEquals('host:8080', $request->getHttpHost());
2097 $this->assertEquals($expectedBaseUrl, $request->getBaseUrl());
2098 $this->assertEquals($expectedBasePath, $request->getBasePath());
2102 class RequestContentProxy extends Request
2104 public function getContent($asResource = false)
2106 return http_build_query(array('_method' => 'PUT', 'content' => 'mycontent'));
2110 class NewRequest extends Request
2112 public function getFoo()