Subversion Repositories php-qbpwcf

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 liveuser 1
<?php
2
 
3
/*
4
 * This file is part of the Symfony package.
5
 *
6
 * (c) Fabien Potencier <fabien@symfony.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
 
12
namespace Symfony\Component\HttpFoundation\Tests;
13
 
14
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
15
use Symfony\Component\HttpFoundation\Session\Session;
16
use Symfony\Component\HttpFoundation\Request;
17
 
18
class RequestTest extends \PHPUnit_Framework_TestCase
19
{
20
    public function testInitialize()
21
    {
22
        $request = new Request();
23
 
24
        $request->initialize(array('foo' => 'bar'));
25
        $this->assertEquals('bar', $request->query->get('foo'), '->initialize() takes an array of query parameters as its first argument');
26
 
27
        $request->initialize(array(), array('foo' => 'bar'));
28
        $this->assertEquals('bar', $request->request->get('foo'), '->initialize() takes an array of request parameters as its second argument');
29
 
30
        $request->initialize(array(), array(), array('foo' => 'bar'));
31
        $this->assertEquals('bar', $request->attributes->get('foo'), '->initialize() takes an array of attributes as its third argument');
32
 
33
        $request->initialize(array(), array(), array(), array(), array(), array('HTTP_FOO' => 'bar'));
34
        $this->assertEquals('bar', $request->headers->get('FOO'), '->initialize() takes an array of HTTP headers as its sixth argument');
35
    }
36
 
37
    public function testGetLocale()
38
    {
39
        $request = new Request();
40
        $request->setLocale('pl');
41
        $locale = $request->getLocale();
42
        $this->assertEquals('pl', $locale);
43
    }
44
 
45
    public function testGetUser()
46
    {
47
        $request = Request::create('http://user_test:password_test@test.com/');
48
        $user = $request->getUser();
49
 
50
        $this->assertEquals('user_test', $user);
51
    }
52
 
53
    public function testGetPassword()
54
    {
55
        $request = Request::create('http://user_test:password_test@test.com/');
56
        $password = $request->getPassword();
57
 
58
        $this->assertEquals('password_test', $password);
59
    }
60
 
61
    public function testIsNoCache()
62
    {
63
        $request = new Request();
64
        $isNoCache = $request->isNoCache();
65
 
66
        $this->assertFalse($isNoCache);
67
    }
68
 
69
    public function testGetContentType()
70
    {
71
        $request = new Request();
72
        $contentType = $request->getContentType();
73
 
74
        $this->assertNull($contentType);
75
    }
76
 
77
    public function testSetDefaultLocale()
78
    {
79
        $request = new Request();
80
        $request->setDefaultLocale('pl');
81
        $locale = $request->getLocale();
82
 
83
        $this->assertEquals('pl', $locale);
84
    }
85
 
86
    public function testCreate()
87
    {
88
        $request = Request::create('http://test.com/foo?bar=baz');
89
        $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
90
        $this->assertEquals('/foo', $request->getPathInfo());
91
        $this->assertEquals('bar=baz', $request->getQueryString());
92
        $this->assertEquals(80, $request->getPort());
93
        $this->assertEquals('test.com', $request->getHttpHost());
94
        $this->assertFalse($request->isSecure());
95
 
96
        $request = Request::create('http://test.com/foo', 'GET', array('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());
103
 
104
        $request = Request::create('http://test.com/foo?bar=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());
111
 
112
        $request = Request::create('https://test.com/foo?bar=baz');
113
        $this->assertEquals('https://test.com/foo?bar=baz', $request->getUri());
114
        $this->assertEquals('/foo', $request->getPathInfo());
115
        $this->assertEquals('bar=baz', $request->getQueryString());
116
        $this->assertEquals(443, $request->getPort());
117
        $this->assertEquals('test.com', $request->getHttpHost());
118
        $this->assertTrue($request->isSecure());
119
 
120
        $request = Request::create('test.com:90/foo');
121
        $this->assertEquals('http://test.com:90/foo', $request->getUri());
122
        $this->assertEquals('/foo', $request->getPathInfo());
123
        $this->assertEquals('test.com', $request->getHost());
124
        $this->assertEquals('test.com:90', $request->getHttpHost());
125
        $this->assertEquals(90, $request->getPort());
126
        $this->assertFalse($request->isSecure());
127
 
128
        $request = Request::create('https://test.com:90/foo');
129
        $this->assertEquals('https://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->assertTrue($request->isSecure());
135
 
136
        $request = Request::create('https://127.0.0.1:90/foo');
137
        $this->assertEquals('https://127.0.0.1:90/foo', $request->getUri());
138
        $this->assertEquals('/foo', $request->getPathInfo());
139
        $this->assertEquals('127.0.0.1', $request->getHost());
140
        $this->assertEquals('127.0.0.1:90', $request->getHttpHost());
141
        $this->assertEquals(90, $request->getPort());
142
        $this->assertTrue($request->isSecure());
143
 
144
        $request = Request::create('https://[::1]:90/foo');
145
        $this->assertEquals('https://[::1]:90/foo', $request->getUri());
146
        $this->assertEquals('/foo', $request->getPathInfo());
147
        $this->assertEquals('[::1]', $request->getHost());
148
        $this->assertEquals('[::1]:90', $request->getHttpHost());
149
        $this->assertEquals(90, $request->getPort());
150
        $this->assertTrue($request->isSecure());
151
 
152
        $request = Request::create('https://[::1]/foo');
153
        $this->assertEquals('https://[::1]/foo', $request->getUri());
154
        $this->assertEquals('/foo', $request->getPathInfo());
155
        $this->assertEquals('[::1]', $request->getHost());
156
        $this->assertEquals('[::1]', $request->getHttpHost());
157
        $this->assertEquals(443, $request->getPort());
158
        $this->assertTrue($request->isSecure());
159
 
160
        $json = '{"jsonrpc":"2.0","method":"echo","id":7,"params":["Hello World"]}';
161
        $request = Request::create('http://example.com/jsonrpc', 'POST', array(), array(), array(), array(), $json);
162
        $this->assertEquals($json, $request->getContent());
163
        $this->assertFalse($request->isSecure());
164
 
165
        $request = Request::create('http://test.com');
166
        $this->assertEquals('http://test.com/', $request->getUri());
167
        $this->assertEquals('/', $request->getPathInfo());
168
        $this->assertEquals('', $request->getQueryString());
169
        $this->assertEquals(80, $request->getPort());
170
        $this->assertEquals('test.com', $request->getHttpHost());
171
        $this->assertFalse($request->isSecure());
172
 
173
        $request = Request::create('http://test.com?test=1');
174
        $this->assertEquals('http://test.com/?test=1', $request->getUri());
175
        $this->assertEquals('/', $request->getPathInfo());
176
        $this->assertEquals('test=1', $request->getQueryString());
177
        $this->assertEquals(80, $request->getPort());
178
        $this->assertEquals('test.com', $request->getHttpHost());
179
        $this->assertFalse($request->isSecure());
180
 
181
        $request = Request::create('http://test.com:90/?test=1');
182
        $this->assertEquals('http://test.com:90/?test=1', $request->getUri());
183
        $this->assertEquals('/', $request->getPathInfo());
184
        $this->assertEquals('test=1', $request->getQueryString());
185
        $this->assertEquals(90, $request->getPort());
186
        $this->assertEquals('test.com:90', $request->getHttpHost());
187
        $this->assertFalse($request->isSecure());
188
 
189
        $request = Request::create('http://username:password@test.com');
190
        $this->assertEquals('http://test.com/', $request->getUri());
191
        $this->assertEquals('/', $request->getPathInfo());
192
        $this->assertEquals('', $request->getQueryString());
193
        $this->assertEquals(80, $request->getPort());
194
        $this->assertEquals('test.com', $request->getHttpHost());
195
        $this->assertEquals('username', $request->getUser());
196
        $this->assertEquals('password', $request->getPassword());
197
        $this->assertFalse($request->isSecure());
198
 
199
        $request = Request::create('http://username@test.com');
200
        $this->assertEquals('http://test.com/', $request->getUri());
201
        $this->assertEquals('/', $request->getPathInfo());
202
        $this->assertEquals('', $request->getQueryString());
203
        $this->assertEquals(80, $request->getPort());
204
        $this->assertEquals('test.com', $request->getHttpHost());
205
        $this->assertEquals('username', $request->getUser());
206
        $this->assertSame('', $request->getPassword());
207
        $this->assertFalse($request->isSecure());
208
 
209
        $request = Request::create('http://test.com/?foo');
210
        $this->assertEquals('/?foo', $request->getRequestUri());
211
        $this->assertEquals(array('foo' => ''), $request->query->all());
212
 
213
        // assume rewrite rule: (.*) --> app/app.php; app/ is a symlink to a symfony web/ directory
214
        $request = Request::create('http://test.com/apparthotel-1234', 'GET', array(), array(), array(),
215
            array(
216
                'DOCUMENT_ROOT' => '/var/www/www.test.com',
217
                'SCRIPT_FILENAME' => '/var/www/www.test.com/app/app.php',
218
                'SCRIPT_NAME' => '/app/app.php',
219
                'PHP_SELF' => '/app/app.php/apparthotel-1234',
220
            ));
221
        $this->assertEquals('http://test.com/apparthotel-1234', $request->getUri());
222
        $this->assertEquals('/apparthotel-1234', $request->getPathInfo());
223
        $this->assertEquals('', $request->getQueryString());
224
        $this->assertEquals(80, $request->getPort());
225
        $this->assertEquals('test.com', $request->getHttpHost());
226
        $this->assertFalse($request->isSecure());
227
    }
228
 
229
    public function testCreateCheckPrecedence()
230
    {
231
        // server is used by default
232
        $request = Request::create('/', 'DELETE', array(), array(), array(), array(
233
            'HTTP_HOST' => 'example.com',
234
            'HTTPS' => 'on',
235
            'SERVER_PORT' => 443,
236
            'PHP_AUTH_USER' => 'fabien',
237
            'PHP_AUTH_PW' => 'pa$$',
238
            'QUERY_STRING' => 'foo=bar',
239
            'CONTENT_TYPE' => 'application/json',
240
        ));
241
        $this->assertEquals('example.com', $request->getHost());
242
        $this->assertEquals(443, $request->getPort());
243
        $this->assertTrue($request->isSecure());
244
        $this->assertEquals('fabien', $request->getUser());
245
        $this->assertEquals('pa$$', $request->getPassword());
246
        $this->assertEquals('', $request->getQueryString());
247
        $this->assertEquals('application/json', $request->headers->get('CONTENT_TYPE'));
248
 
249
        // URI has precedence over server
250
        $request = Request::create('http://thomas:pokemon@example.net:8080/?foo=bar', 'GET', array(), array(), array(), array(
251
            'HTTP_HOST' => 'example.com',
252
            'HTTPS' => 'on',
253
            'SERVER_PORT' => 443,
254
        ));
255
        $this->assertEquals('example.net', $request->getHost());
256
        $this->assertEquals(8080, $request->getPort());
257
        $this->assertFalse($request->isSecure());
258
        $this->assertEquals('thomas', $request->getUser());
259
        $this->assertEquals('pokemon', $request->getPassword());
260
        $this->assertEquals('foo=bar', $request->getQueryString());
261
    }
262
 
263
    public function testDuplicate()
264
    {
265
        $request = new Request(array('foo' => 'bar'), array('foo' => 'bar'), array('foo' => 'bar'), array(), array(), array('HTTP_FOO' => 'bar'));
266
        $dup = $request->duplicate();
267
 
268
        $this->assertEquals($request->query->all(), $dup->query->all(), '->duplicate() duplicates a request an copy the current query parameters');
269
        $this->assertEquals($request->request->all(), $dup->request->all(), '->duplicate() duplicates a request an copy the current request parameters');
270
        $this->assertEquals($request->attributes->all(), $dup->attributes->all(), '->duplicate() duplicates a request an copy the current attributes');
271
        $this->assertEquals($request->headers->all(), $dup->headers->all(), '->duplicate() duplicates a request an copy the current HTTP headers');
272
 
273
        $dup = $request->duplicate(array('foo' => 'foobar'), array('foo' => 'foobar'), array('foo' => 'foobar'), array(), array(), array('HTTP_FOO' => 'foobar'));
274
 
275
        $this->assertEquals(array('foo' => 'foobar'), $dup->query->all(), '->duplicate() overrides the query parameters if provided');
276
        $this->assertEquals(array('foo' => 'foobar'), $dup->request->all(), '->duplicate() overrides the request parameters if provided');
277
        $this->assertEquals(array('foo' => 'foobar'), $dup->attributes->all(), '->duplicate() overrides the attributes if provided');
278
        $this->assertEquals(array('foo' => array('foobar')), $dup->headers->all(), '->duplicate() overrides the HTTP header if provided');
279
    }
280
 
281
    public function testDuplicateWithFormat()
282
    {
283
        $request = new Request(array(), array(), array('_format' => 'json'));
284
        $dup = $request->duplicate();
285
 
286
        $this->assertEquals('json', $dup->getRequestFormat());
287
        $this->assertEquals('json', $dup->attributes->get('_format'));
288
 
289
        $request = new Request();
290
        $request->setRequestFormat('xml');
291
        $dup = $request->duplicate();
292
 
293
        $this->assertEquals('xml', $dup->getRequestFormat());
294
    }
295
 
296
    /**
297
     * @dataProvider getFormatToMimeTypeMapProvider
298
     */
299
    public function testGetFormatFromMimeType($format, $mimeTypes)
300
    {
301
        $request = new Request();
302
        foreach ($mimeTypes as $mime) {
303
            $this->assertEquals($format, $request->getFormat($mime));
304
        }
305
        $request->setFormat($format, $mimeTypes);
306
        foreach ($mimeTypes as $mime) {
307
            $this->assertEquals($format, $request->getFormat($mime));
308
        }
309
    }
310
 
311
    public function testGetFormatFromMimeTypeWithParameters()
312
    {
313
        $request = new Request();
314
        $this->assertEquals('json', $request->getFormat('application/json; charset=utf-8'));
315
    }
316
 
317
    /**
318
     * @dataProvider getFormatToMimeTypeMapProvider
319
     */
320
    public function testGetMimeTypeFromFormat($format, $mimeTypes)
321
    {
322
        if (null !== $format) {
323
            $request = new Request();
324
            $this->assertEquals($mimeTypes[0], $request->getMimeType($format));
325
        }
326
    }
327
 
328
    /**
329
     * @dataProvider getFormatToMimeTypeMapProvider
330
     */
331
    public function testGetMimeTypesFromFormat($format, $mimeTypes)
332
    {
333
        if (null !== $format) {
334
            $this->assertEquals($mimeTypes, Request::getMimeTypes($format));
335
        }
336
    }
337
 
338
    public function testGetMimeTypesFromInexistentFormat()
339
    {
340
        $request = new Request();
341
        $this->assertNull($request->getMimeType('foo'));
342
        $this->assertEquals(array(), Request::getMimeTypes('foo'));
343
    }
344
 
345
    public function testGetFormatWithCustomMimeType()
346
    {
347
        $request = new Request();
348
        $request->setFormat('custom', 'application/vnd.foo.api;myversion=2.3');
349
        $this->assertEquals('custom', $request->getFormat('application/vnd.foo.api;myversion=2.3'));
350
    }
351
 
352
    public function getFormatToMimeTypeMapProvider()
353
    {
354
        return array(
355
            array(null, array(null, 'unexistent-mime-type')),
356
            array('txt', array('text/plain')),
357
            array('js', array('application/javascript', 'application/x-javascript', 'text/javascript')),
358
            array('css', array('text/css')),
359
            array('json', array('application/json', 'application/x-json')),
360
            array('xml', array('text/xml', 'application/xml', 'application/x-xml')),
361
            array('rdf', array('application/rdf+xml')),
362
            array('atom', array('application/atom+xml')),
363
        );
364
    }
365
 
366
    public function testGetUri()
367
    {
368
        $server = array();
369
 
370
        // Standard Request on non default PORT
371
        // http://host:8080/index.php/path/info?query=string
372
 
373
        $server['HTTP_HOST'] = 'host:8080';
374
        $server['SERVER_NAME'] = 'servername';
375
        $server['SERVER_PORT'] = '8080';
376
 
377
        $server['QUERY_STRING'] = 'query=string';
378
        $server['REQUEST_URI'] = '/index.php/path/info?query=string';
379
        $server['SCRIPT_NAME'] = '/index.php';
380
        $server['PATH_INFO'] = '/path/info';
381
        $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
382
        $server['PHP_SELF'] = '/index_dev.php/path/info';
383
        $server['SCRIPT_FILENAME'] = '/some/where/index.php';
384
 
385
        $request = new Request();
386
 
387
        $request->initialize(array(), array(), array(), array(), array(), $server);
388
 
389
        $this->assertEquals('http://host:8080/index.php/path/info?query=string', $request->getUri(), '->getUri() with non default port');
390
 
391
        // Use std port number
392
        $server['HTTP_HOST'] = 'host';
393
        $server['SERVER_NAME'] = 'servername';
394
        $server['SERVER_PORT'] = '80';
395
 
396
        $request->initialize(array(), array(), array(), array(), array(), $server);
397
 
398
        $this->assertEquals('http://host/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port');
399
 
400
        // Without HOST HEADER
401
        unset($server['HTTP_HOST']);
402
        $server['SERVER_NAME'] = 'servername';
403
        $server['SERVER_PORT'] = '80';
404
 
405
        $request->initialize(array(), array(), array(), array(), array(), $server);
406
 
407
        $this->assertEquals('http://servername/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port without HOST_HEADER');
408
 
409
        // Request with URL REWRITING (hide index.php)
410
        //   RewriteCond %{REQUEST_FILENAME} !-f
411
        //   RewriteRule ^(.*)$ index.php [QSA,L]
412
        // http://host:8080/path/info?query=string
413
        $server = array();
414
        $server['HTTP_HOST'] = 'host:8080';
415
        $server['SERVER_NAME'] = 'servername';
416
        $server['SERVER_PORT'] = '8080';
417
 
418
        $server['REDIRECT_QUERY_STRING'] = 'query=string';
419
        $server['REDIRECT_URL'] = '/path/info';
420
        $server['SCRIPT_NAME'] = '/index.php';
421
        $server['QUERY_STRING'] = 'query=string';
422
        $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
423
        $server['SCRIPT_NAME'] = '/index.php';
424
        $server['PHP_SELF'] = '/index.php';
425
        $server['SCRIPT_FILENAME'] = '/some/where/index.php';
426
 
427
        $request->initialize(array(), array(), array(), array(), array(), $server);
428
        $this->assertEquals('http://host:8080/path/info?query=string', $request->getUri(), '->getUri() with rewrite');
429
 
430
        // Use std port number
431
        //  http://host/path/info?query=string
432
        $server['HTTP_HOST'] = 'host';
433
        $server['SERVER_NAME'] = 'servername';
434
        $server['SERVER_PORT'] = '80';
435
 
436
        $request->initialize(array(), array(), array(), array(), array(), $server);
437
 
438
        $this->assertEquals('http://host/path/info?query=string', $request->getUri(), '->getUri() with rewrite and default port');
439
 
440
        // Without HOST HEADER
441
        unset($server['HTTP_HOST']);
442
        $server['SERVER_NAME'] = 'servername';
443
        $server['SERVER_PORT'] = '80';
444
 
445
        $request->initialize(array(), array(), array(), array(), array(), $server);
446
 
447
        $this->assertEquals('http://servername/path/info?query=string', $request->getUri(), '->getUri() with rewrite, default port without HOST_HEADER');
448
 
449
        // With encoded characters
450
 
451
        $server = array(
452
            'HTTP_HOST' => 'host:8080',
453
            'SERVER_NAME' => 'servername',
454
            'SERVER_PORT' => '8080',
455
            'QUERY_STRING' => 'query=string',
456
            'REQUEST_URI' => '/ba%20se/index_dev.php/foo%20bar/in+fo?query=string',
457
            'SCRIPT_NAME' => '/ba se/index_dev.php',
458
            'PATH_TRANSLATED' => 'redirect:/index.php/foo bar/in+fo',
459
            'PHP_SELF' => '/ba se/index_dev.php/path/info',
460
            'SCRIPT_FILENAME' => '/some/where/ba se/index_dev.php',
461
        );
462
 
463
        $request->initialize(array(), array(), array(), array(), array(), $server);
464
 
465
        $this->assertEquals(
466
            'http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string',
467
            $request->getUri()
468
        );
469
 
470
        // with user info
471
 
472
        $server['PHP_AUTH_USER'] = 'fabien';
473
        $request->initialize(array(), array(), array(), array(), array(), $server);
474
        $this->assertEquals('http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri());
475
 
476
        $server['PHP_AUTH_PW'] = 'symfony';
477
        $request->initialize(array(), array(), array(), array(), array(), $server);
478
        $this->assertEquals('http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri());
479
    }
480
 
481
    public function testGetUriForPath()
482
    {
483
        $request = Request::create('http://test.com/foo?bar=baz');
484
        $this->assertEquals('http://test.com/some/path', $request->getUriForPath('/some/path'));
485
 
486
        $request = Request::create('http://test.com:90/foo?bar=baz');
487
        $this->assertEquals('http://test.com:90/some/path', $request->getUriForPath('/some/path'));
488
 
489
        $request = Request::create('https://test.com/foo?bar=baz');
490
        $this->assertEquals('https://test.com/some/path', $request->getUriForPath('/some/path'));
491
 
492
        $request = Request::create('https://test.com:90/foo?bar=baz');
493
        $this->assertEquals('https://test.com:90/some/path', $request->getUriForPath('/some/path'));
494
 
495
        $server = array();
496
 
497
        // Standard Request on non default PORT
498
        // http://host:8080/index.php/path/info?query=string
499
 
500
        $server['HTTP_HOST'] = 'host:8080';
501
        $server['SERVER_NAME'] = 'servername';
502
        $server['SERVER_PORT'] = '8080';
503
 
504
        $server['QUERY_STRING'] = 'query=string';
505
        $server['REQUEST_URI'] = '/index.php/path/info?query=string';
506
        $server['SCRIPT_NAME'] = '/index.php';
507
        $server['PATH_INFO'] = '/path/info';
508
        $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
509
        $server['PHP_SELF'] = '/index_dev.php/path/info';
510
        $server['SCRIPT_FILENAME'] = '/some/where/index.php';
511
 
512
        $request = new Request();
513
 
514
        $request->initialize(array(), array(), array(), array(), array(), $server);
515
 
516
        $this->assertEquals('http://host:8080/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with non default port');
517
 
518
        // Use std port number
519
        $server['HTTP_HOST'] = 'host';
520
        $server['SERVER_NAME'] = 'servername';
521
        $server['SERVER_PORT'] = '80';
522
 
523
        $request->initialize(array(), array(), array(), array(), array(), $server);
524
 
525
        $this->assertEquals('http://host/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port');
526
 
527
        // Without HOST HEADER
528
        unset($server['HTTP_HOST']);
529
        $server['SERVER_NAME'] = 'servername';
530
        $server['SERVER_PORT'] = '80';
531
 
532
        $request->initialize(array(), array(), array(), array(), array(), $server);
533
 
534
        $this->assertEquals('http://servername/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port without HOST_HEADER');
535
 
536
        // Request with URL REWRITING (hide index.php)
537
        //   RewriteCond %{REQUEST_FILENAME} !-f
538
        //   RewriteRule ^(.*)$ index.php [QSA,L]
539
        // http://host:8080/path/info?query=string
540
        $server = array();
541
        $server['HTTP_HOST'] = 'host:8080';
542
        $server['SERVER_NAME'] = 'servername';
543
        $server['SERVER_PORT'] = '8080';
544
 
545
        $server['REDIRECT_QUERY_STRING'] = 'query=string';
546
        $server['REDIRECT_URL'] = '/path/info';
547
        $server['SCRIPT_NAME'] = '/index.php';
548
        $server['QUERY_STRING'] = 'query=string';
549
        $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
550
        $server['SCRIPT_NAME'] = '/index.php';
551
        $server['PHP_SELF'] = '/index.php';
552
        $server['SCRIPT_FILENAME'] = '/some/where/index.php';
553
 
554
        $request->initialize(array(), array(), array(), array(), array(), $server);
555
        $this->assertEquals('http://host:8080/some/path', $request->getUriForPath('/some/path'), '->getUri() with rewrite');
556
 
557
        // Use std port number
558
        //  http://host/path/info?query=string
559
        $server['HTTP_HOST'] = 'host';
560
        $server['SERVER_NAME'] = 'servername';
561
        $server['SERVER_PORT'] = '80';
562
 
563
        $request->initialize(array(), array(), array(), array(), array(), $server);
564
 
565
        $this->assertEquals('http://host/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite and default port');
566
 
567
        // Without HOST HEADER
568
        unset($server['HTTP_HOST']);
569
        $server['SERVER_NAME'] = 'servername';
570
        $server['SERVER_PORT'] = '80';
571
 
572
        $request->initialize(array(), array(), array(), array(), array(), $server);
573
 
574
        $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite, default port without HOST_HEADER');
575
        $this->assertEquals('servername', $request->getHttpHost());
576
 
577
        // with user info
578
 
579
        $server['PHP_AUTH_USER'] = 'fabien';
580
        $request->initialize(array(), array(), array(), array(), array(), $server);
581
        $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'));
582
 
583
        $server['PHP_AUTH_PW'] = 'symfony';
584
        $request->initialize(array(), array(), array(), array(), array(), $server);
585
        $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'));
586
    }
587
 
588
    /**
589
     * @dataProvider getRelativeUriForPathData()
590
     */
591
    public function testGetRelativeUriForPath($expected, $pathinfo, $path)
592
    {
593
        $this->assertEquals($expected, Request::create($pathinfo)->getRelativeUriForPath($path));
594
    }
595
 
596
    public function getRelativeUriForPathData()
597
    {
598
        return array(
599
            array('me.png', '/foo', '/me.png'),
600
            array('../me.png', '/foo/bar', '/me.png'),
601
            array('me.png', '/foo/bar', '/foo/me.png'),
602
            array('../baz/me.png', '/foo/bar/b', '/foo/baz/me.png'),
603
            array('../../fooz/baz/me.png', '/foo/bar/b', '/fooz/baz/me.png'),
604
            array('baz/me.png', '/foo/bar/b', 'baz/me.png'),
605
        );
606
    }
607
 
608
    public function testGetUserInfo()
609
    {
610
        $request = new Request();
611
 
612
        $server = array('PHP_AUTH_USER' => 'fabien');
613
        $request->initialize(array(), array(), array(), array(), array(), $server);
614
        $this->assertEquals('fabien', $request->getUserInfo());
615
 
616
        $server['PHP_AUTH_USER'] = '0';
617
        $request->initialize(array(), array(), array(), array(), array(), $server);
618
        $this->assertEquals('0', $request->getUserInfo());
619
 
620
        $server['PHP_AUTH_PW'] = '0';
621
        $request->initialize(array(), array(), array(), array(), array(), $server);
622
        $this->assertEquals('0:0', $request->getUserInfo());
623
    }
624
 
625
    public function testGetSchemeAndHttpHost()
626
    {
627
        $request = new Request();
628
 
629
        $server = array();
630
        $server['SERVER_NAME'] = 'servername';
631
        $server['SERVER_PORT'] = '90';
632
        $request->initialize(array(), array(), array(), array(), array(), $server);
633
        $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
634
 
635
        $server['PHP_AUTH_USER'] = 'fabien';
636
        $request->initialize(array(), array(), array(), array(), array(), $server);
637
        $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
638
 
639
        $server['PHP_AUTH_USER'] = '0';
640
        $request->initialize(array(), array(), array(), array(), array(), $server);
641
        $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
642
 
643
        $server['PHP_AUTH_PW'] = '0';
644
        $request->initialize(array(), array(), array(), array(), array(), $server);
645
        $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
646
    }
647
 
648
    /**
649
     * @dataProvider getQueryStringNormalizationData
650
     */
651
    public function testGetQueryString($query, $expectedQuery, $msg)
652
    {
653
        $request = new Request();
654
 
655
        $request->server->set('QUERY_STRING', $query);
656
        $this->assertSame($expectedQuery, $request->getQueryString(), $msg);
657
    }
658
 
659
    public function getQueryStringNormalizationData()
660
    {
661
        return array(
662
            array('foo', 'foo', 'works with valueless parameters'),
663
            array('foo=', 'foo=', 'includes a dangling equal sign'),
664
            array('bar=&foo=bar', 'bar=&foo=bar', '->works with empty parameters'),
665
            array('foo=bar&bar=', 'bar=&foo=bar', 'sorts keys alphabetically'),
666
 
667
            // GET parameters, that are submitted from a HTML form, encode spaces as "+" by default (as defined in enctype application/x-www-form-urlencoded).
668
            // PHP also converts "+" to spaces when filling the global _GET or when using the function parse_str.
669
            array('him=John%20Doe&her=Jane+Doe', 'her=Jane%20Doe&him=John%20Doe', 'normalizes spaces in both encodings "%20" and "+"'),
670
 
671
            array('foo[]=1&foo[]=2', 'foo%5B%5D=1&foo%5B%5D=2', 'allows array notation'),
672
            array('foo=1&foo=2', 'foo=1&foo=2', 'allows repeated parameters'),
673
            array('pa%3Dram=foo%26bar%3Dbaz&test=test', 'pa%3Dram=foo%26bar%3Dbaz&test=test', 'works with encoded delimiters'),
674
            array('0', '0', 'allows "0"'),
675
            array('Jane Doe&John%20Doe', 'Jane%20Doe&John%20Doe', 'normalizes encoding in keys'),
676
            array('her=Jane Doe&him=John%20Doe', 'her=Jane%20Doe&him=John%20Doe', 'normalizes encoding in values'),
677
            array('foo=bar&&&test&&', 'foo=bar&test', 'removes unneeded delimiters'),
678
            array('formula=e=m*c^2', 'formula=e%3Dm%2Ac%5E2', 'correctly treats only the first "=" as delimiter and the next as value'),
679
 
680
            // Ignore pairs with empty key, even if there was a value, e.g. "=value", as such nameless values cannot be retrieved anyway.
681
            // PHP also does not include them when building _GET.
682
            array('foo=bar&=a=b&=x=y', 'foo=bar', 'removes params with empty key'),
683
        );
684
    }
685
 
686
    public function testGetQueryStringReturnsNull()
687
    {
688
        $request = new Request();
689
 
690
        $this->assertNull($request->getQueryString(), '->getQueryString() returns null for non-existent query string');
691
 
692
        $request->server->set('QUERY_STRING', '');
693
        $this->assertNull($request->getQueryString(), '->getQueryString() returns null for empty query string');
694
    }
695
 
696
    public function testGetHost()
697
    {
698
        $request = new Request();
699
 
700
        $request->initialize(array('foo' => 'bar'));
701
        $this->assertEquals('', $request->getHost(), '->getHost() return empty string if not initialized');
702
 
703
        $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.example.com'));
704
        $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from Host Header');
705
 
706
        // Host header with port number
707
        $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.example.com:8080'));
708
        $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from Host Header with port number');
709
 
710
        // Server values
711
        $request->initialize(array(), array(), array(), array(), array(), array('SERVER_NAME' => 'www.example.com'));
712
        $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from server name');
713
 
714
        $request->initialize(array(), array(), array(), array(), array(), array('SERVER_NAME' => 'www.example.com', 'HTTP_HOST' => 'www.host.com'));
715
        $this->assertEquals('www.host.com', $request->getHost(), '->getHost() value from Host header has priority over SERVER_NAME ');
716
    }
717
 
718
    public function testGetPort()
719
    {
720
        $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
721
            'HTTP_X_FORWARDED_PROTO' => 'https',
722
            'HTTP_X_FORWARDED_PORT' => '443',
723
        ));
724
        $port = $request->getPort();
725
 
726
        $this->assertEquals(80, $port, 'Without trusted proxies FORWARDED_PROTO and FORWARDED_PORT are ignored.');
727
 
728
        Request::setTrustedProxies(array('1.1.1.1'));
729
        $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
730
            'HTTP_X_FORWARDED_PROTO' => 'https',
731
            'HTTP_X_FORWARDED_PORT' => '8443',
732
        ));
733
        $this->assertEquals(80, $request->getPort(), 'With PROTO and PORT on untrusted connection server value takes precedence.');
734
        $request->server->set('REMOTE_ADDR', '1.1.1.1');
735
        $this->assertEquals(8443, $request->getPort(), 'With PROTO and PORT set PORT takes precedence.');
736
 
737
        $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
738
            'HTTP_X_FORWARDED_PROTO' => 'https',
739
        ));
740
        $this->assertEquals(80, $request->getPort(), 'With only PROTO set getPort() ignores trusted headers on untrusted connection.');
741
        $request->server->set('REMOTE_ADDR', '1.1.1.1');
742
        $this->assertEquals(443, $request->getPort(), 'With only PROTO set getPort() defaults to 443.');
743
 
744
        $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
745
            'HTTP_X_FORWARDED_PROTO' => 'http',
746
        ));
747
        $this->assertEquals(80, $request->getPort(), 'If X_FORWARDED_PROTO is set to HTTP getPort() ignores trusted headers on untrusted connection.');
748
        $request->server->set('REMOTE_ADDR', '1.1.1.1');
749
        $this->assertEquals(80, $request->getPort(), 'If X_FORWARDED_PROTO is set to HTTP getPort() returns port of the original request.');
750
 
751
        $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
752
            'HTTP_X_FORWARDED_PROTO' => 'On',
753
        ));
754
        $this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is On, getPort() ignores trusted headers on untrusted connection.');
755
        $request->server->set('REMOTE_ADDR', '1.1.1.1');
756
        $this->assertEquals(443, $request->getPort(), 'With only PROTO set and value is On, getPort() defaults to 443.');
757
 
758
        $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
759
            'HTTP_X_FORWARDED_PROTO' => '1',
760
        ));
761
        $this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is 1, getPort() ignores trusted headers on untrusted connection.');
762
        $request->server->set('REMOTE_ADDR', '1.1.1.1');
763
        $this->assertEquals(443, $request->getPort(), 'With only PROTO set and value is 1, getPort() defaults to 443.');
764
 
765
        $request = Request::create('http://example.com', 'GET', array(), array(), array(), array(
766
            'HTTP_X_FORWARDED_PROTO' => 'something-else',
767
        ));
768
        $port = $request->getPort();
769
        $this->assertEquals(80, $port, 'With only PROTO set and value is not recognized, getPort() defaults to 80.');
770
 
771
        Request::setTrustedProxies(array());
772
    }
773
 
774
    /**
775
     * @expectedException \RuntimeException
776
     */
777
    public function testGetHostWithFakeHttpHostValue()
778
    {
779
        $request = new Request();
780
        $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.host.com?query=string'));
781
        $request->getHost();
782
    }
783
 
784
    public function testGetSetMethod()
785
    {
786
        $request = new Request();
787
 
788
        $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns GET if no method is defined');
789
 
790
        $request->setMethod('get');
791
        $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns an uppercased string');
792
 
793
        $request->setMethod('PURGE');
794
        $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method even if it is not a standard one');
795
 
796
        $request->setMethod('POST');
797
        $this->assertEquals('POST', $request->getMethod(), '->getMethod() returns the method POST if no _method is defined');
798
 
799
        $request->setMethod('POST');
800
        $request->request->set('_method', 'purge');
801
        $this->assertEquals('POST', $request->getMethod(), '->getMethod() does not return the method from _method if defined and POST but support not enabled');
802
 
803
        $request = new Request();
804
        $request->setMethod('POST');
805
        $request->request->set('_method', 'purge');
806
 
807
        $this->assertFalse(Request::getHttpMethodParameterOverride(), 'httpMethodParameterOverride should be disabled by default');
808
 
809
        Request::enableHttpMethodParameterOverride();
810
 
811
        $this->assertTrue(Request::getHttpMethodParameterOverride(), 'httpMethodParameterOverride should be enabled now but it is not');
812
 
813
        $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method from _method if defined and POST');
814
        $this->disableHttpMethodParameterOverride();
815
 
816
        $request = new Request();
817
        $request->setMethod('POST');
818
        $request->query->set('_method', 'purge');
819
        $this->assertEquals('POST', $request->getMethod(), '->getMethod() does not return the method from _method if defined and POST but support not enabled');
820
 
821
        $request = new Request();
822
        $request->setMethod('POST');
823
        $request->query->set('_method', 'purge');
824
        Request::enableHttpMethodParameterOverride();
825
        $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method from _method if defined and POST');
826
        $this->disableHttpMethodParameterOverride();
827
 
828
        $request = new Request();
829
        $request->setMethod('POST');
830
        $request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete');
831
        $this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override even though _method is set if defined and POST');
832
 
833
        $request = new Request();
834
        $request->setMethod('POST');
835
        $request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete');
836
        $this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override if defined and POST');
837
    }
838
 
839
    /**
840
     * @dataProvider testGetClientIpsProvider
841
     */
842
    public function testGetClientIp($expected, $remoteAddr, $httpForwardedFor, $trustedProxies)
843
    {
844
        $request = $this->getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies);
845
 
846
        $this->assertEquals($expected[0], $request->getClientIp());
847
 
848
        Request::setTrustedProxies(array());
849
    }
850
 
851
    /**
852
     * @dataProvider testGetClientIpsProvider
853
     */
854
    public function testGetClientIps($expected, $remoteAddr, $httpForwardedFor, $trustedProxies)
855
    {
856
        $request = $this->getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies);
857
 
858
        $this->assertEquals($expected, $request->getClientIps());
859
 
860
        Request::setTrustedProxies(array());
861
    }
862
 
863
    /**
864
     * @dataProvider testGetClientIpsForwardedProvider
865
     */
866
    public function testGetClientIpsForwarded($expected, $remoteAddr, $httpForwarded, $trustedProxies)
867
    {
868
        $request = $this->getRequestInstanceForClientIpsForwardedTests($remoteAddr, $httpForwarded, $trustedProxies);
869
 
870
        $this->assertEquals($expected, $request->getClientIps());
871
 
872
        Request::setTrustedProxies(array());
873
    }
874
 
875
    public function testGetClientIpsForwardedProvider()
876
    {
877
        //              $expected                                  $remoteAddr  $httpForwarded                                       $trustedProxies
878
        return array(
879
            array(array('127.0.0.1'),                              '127.0.0.1', 'for="_gazonk"',                                      null),
880
            array(array('127.0.0.1'),                              '127.0.0.1', 'for="_gazonk"',                                      array('127.0.0.1')),
881
            array(array('88.88.88.88'),                            '127.0.0.1', 'for="88.88.88.88:80"',                               array('127.0.0.1')),
882
            array(array('192.0.2.60'),                             '::1',       'for=192.0.2.60;proto=http;by=203.0.113.43',          array('::1')),
883
            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')),
884
            array(array('2001:db8:cafe::17'),                      '::1',       'for="[2001:db8:cafe::17]:4711',                      array('::1')),
885
        );
886
    }
887
 
888
    public function testGetClientIpsProvider()
889
    {
890
        //        $expected                   $remoteAddr                $httpForwardedFor            $trustedProxies
891
        return array(
892
            // simple IPv4
893
            array(array('88.88.88.88'),              '88.88.88.88',              null,                        null),
894
            // trust the IPv4 remote addr
895
            array(array('88.88.88.88'),              '88.88.88.88',              null,                        array('88.88.88.88')),
896
 
897
            // simple IPv6
898
            array(array('::1'),                      '::1',                      null,                        null),
899
            // trust the IPv6 remote addr
900
            array(array('::1'),                      '::1',                      null,                        array('::1')),
901
 
902
            // forwarded for with remote IPv4 addr not trusted
903
            array(array('127.0.0.1'),                '127.0.0.1',                '88.88.88.88',               null),
904
            // forwarded for with remote IPv4 addr trusted
905
            array(array('88.88.88.88'),              '127.0.0.1',                '88.88.88.88',               array('127.0.0.1')),
906
            // forwarded for with remote IPv4 and all FF addrs trusted
907
            array(array('88.88.88.88'),              '127.0.0.1',                '88.88.88.88',               array('127.0.0.1', '88.88.88.88')),
908
            // forwarded for with remote IPv4 range trusted
909
            array(array('88.88.88.88'),              '123.45.67.89',             '88.88.88.88',               array('123.45.67.0/24')),
910
 
911
            // forwarded for with remote IPv6 addr not trusted
912
            array(array('1620:0:1cfe:face:b00c::3'), '1620:0:1cfe:face:b00c::3', '2620:0:1cfe:face:b00c::3',  null),
913
            // forwarded for with remote IPv6 addr trusted
914
            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')),
915
            // forwarded for with remote IPv6 range trusted
916
            array(array('88.88.88.88'),              '2a01:198:603:0:396e:4789:8e99:890f', '88.88.88.88',     array('2a01:198:603:0::/65')),
917
 
918
            // multiple forwarded for with remote IPv4 addr trusted
919
            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')),
920
            // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted
921
            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')),
922
            // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted but in the middle
923
            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')),
924
            // multiple forwarded for with remote IPv4 addr and all reverse proxies trusted
925
            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')),
926
 
927
            // multiple forwarded for with remote IPv6 addr trusted
928
            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')),
929
            // multiple forwarded for with remote IPv6 addr and some reverse proxies trusted
930
            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')),
931
            // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted but in the middle
932
            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')),
933
 
934
            // client IP with port
935
            array(array('88.88.88.88'), '127.0.0.1', '88.88.88.88:12345, 127.0.0.1', array('127.0.0.1')),
936
 
937
            // invalid forwarded IP is ignored
938
            array(array('88.88.88.88'), '127.0.0.1', 'unknown,88.88.88.88', array('127.0.0.1')),
939
            array(array('88.88.88.88'), '127.0.0.1', '}__test|O:21:&quot;JDatabaseDriverMysqli&quot;:3:{s:2,88.88.88.88', array('127.0.0.1')),
940
        );
941
    }
942
 
943
    /**
944
     * @expectedException \Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException
945
     * @dataProvider testGetClientIpsWithConflictingHeadersProvider
946
     */
947
    public function testGetClientIpsWithConflictingHeaders($httpForwarded, $httpXForwardedFor)
948
    {
949
        $request = new Request();
950
 
951
        $server = array(
952
            'REMOTE_ADDR' => '88.88.88.88',
953
            'HTTP_FORWARDED' => $httpForwarded,
954
            'HTTP_X_FORWARDED_FOR' => $httpXForwardedFor,
955
        );
956
 
957
        Request::setTrustedProxies(array('88.88.88.88'));
958
 
959
        $request->initialize(array(), array(), array(), array(), array(), $server);
960
 
961
        $request->getClientIps();
962
    }
963
 
964
    public function testGetClientIpsWithConflictingHeadersProvider()
965
    {
966
        //        $httpForwarded                   $httpXForwardedFor
967
        return array(
968
            array('for=87.65.43.21',                 '192.0.2.60'),
969
            array('for=87.65.43.21, for=192.0.2.60', '192.0.2.60'),
970
            array('for=192.0.2.60',                  '192.0.2.60,87.65.43.21'),
971
            array('for="::face", for=192.0.2.60',    '192.0.2.60,192.0.2.43'),
972
            array('for=87.65.43.21, for=192.0.2.60', '192.0.2.60,87.65.43.21'),
973
        );
974
    }
975
 
976
    /**
977
     * @dataProvider testGetClientIpsWithAgreeingHeadersProvider
978
     */
979
    public function testGetClientIpsWithAgreeingHeaders($httpForwarded, $httpXForwardedFor)
980
    {
981
        $request = new Request();
982
 
983
        $server = array(
984
            'REMOTE_ADDR' => '88.88.88.88',
985
            'HTTP_FORWARDED' => $httpForwarded,
986
            'HTTP_X_FORWARDED_FOR' => $httpXForwardedFor,
987
        );
988
 
989
        Request::setTrustedProxies(array('88.88.88.88'));
990
 
991
        $request->initialize(array(), array(), array(), array(), array(), $server);
992
 
993
        $request->getClientIps();
994
 
995
        Request::setTrustedProxies(array());
996
    }
997
 
998
    public function testGetClientIpsWithAgreeingHeadersProvider()
999
    {
1000
        //        $httpForwarded                               $httpXForwardedFor
1001
        return array(
1002
            array('for="192.0.2.60"',                          '192.0.2.60'),
1003
            array('for=192.0.2.60, for=87.65.43.21',           '192.0.2.60,87.65.43.21'),
1004
            array('for="[::face]", for=192.0.2.60',            '::face,192.0.2.60'),
1005
            array('for="192.0.2.60:80"',                       '192.0.2.60'),
1006
            array('for=192.0.2.60;proto=http;by=203.0.113.43', '192.0.2.60'),
1007
            array('for="[2001:db8:cafe::17]:4711"',            '2001:db8:cafe::17'),
1008
        );
1009
    }
1010
 
1011
    public function testGetContentWorksTwiceInDefaultMode()
1012
    {
1013
        $req = new Request();
1014
        $this->assertEquals('', $req->getContent());
1015
        $this->assertEquals('', $req->getContent());
1016
    }
1017
 
1018
    public function testGetContentReturnsResource()
1019
    {
1020
        $req = new Request();
1021
        $retval = $req->getContent(true);
1022
        $this->assertInternalType('resource', $retval);
1023
        $this->assertEquals('', fread($retval, 1));
1024
        $this->assertTrue(feof($retval));
1025
    }
1026
 
1027
    public function testGetContentReturnsResourceWhenContentSetInConstructor()
1028
    {
1029
        $req = new Request(array(), array(), array(), array(), array(), array(), 'MyContent');
1030
        $resource = $req->getContent(true);
1031
 
1032
        $this->assertTrue(is_resource($resource));
1033
        $this->assertEquals('MyContent', stream_get_contents($resource));
1034
    }
1035
 
1036
    public function testContentAsResource()
1037
    {
1038
        $resource = fopen('php://memory', 'r+');
1039
        fwrite($resource, 'My other content');
1040
        rewind($resource);
1041
 
1042
        $req = new Request(array(), array(), array(), array(), array(), array(), $resource);
1043
        $this->assertEquals('My other content', stream_get_contents($req->getContent(true)));
1044
        $this->assertEquals('My other content', $req->getContent());
1045
    }
1046
 
1047
    /**
1048
     * @expectedException \LogicException
1049
     * @dataProvider getContentCantBeCalledTwiceWithResourcesProvider
1050
     */
1051
    public function testGetContentCantBeCalledTwiceWithResources($first, $second)
1052
    {
1053
        if (PHP_VERSION_ID >= 50600) {
1054
            $this->markTestSkipped('PHP >= 5.6 allows to open php://input several times.');
1055
        }
1056
 
1057
        $req = new Request();
1058
        $req->getContent($first);
1059
        $req->getContent($second);
1060
    }
1061
 
1062
    /**
1063
     * @dataProvider getContentCantBeCalledTwiceWithResourcesProvider
1064
     * @requires PHP 5.6
1065
     */
1066
    public function testGetContentCanBeCalledTwiceWithResources($first, $second)
1067
    {
1068
        $req = new Request();
1069
        $a = $req->getContent($first);
1070
        $b = $req->getContent($second);
1071
 
1072
        if ($first) {
1073
            $a = stream_get_contents($a);
1074
        }
1075
 
1076
        if ($second) {
1077
            $b = stream_get_contents($b);
1078
        }
1079
 
1080
        $this->assertEquals($a, $b);
1081
    }
1082
 
1083
    public function getContentCantBeCalledTwiceWithResourcesProvider()
1084
    {
1085
        return array(
1086
            'Resource then fetch' => array(true, false),
1087
            'Resource then resource' => array(true, true),
1088
        );
1089
    }
1090
 
1091
    public function provideOverloadedMethods()
1092
    {
1093
        return array(
1094
            array('PUT'),
1095
            array('DELETE'),
1096
            array('PATCH'),
1097
            array('put'),
1098
            array('delete'),
1099
            array('patch'),
1100
 
1101
        );
1102
    }
1103
 
1104
    /**
1105
     * @dataProvider provideOverloadedMethods
1106
     */
1107
    public function testCreateFromGlobals($method)
1108
    {
1109
        $normalizedMethod = strtoupper($method);
1110
 
1111
        $_GET['foo1'] = 'bar1';
1112
        $_POST['foo2'] = 'bar2';
1113
        $_COOKIE['foo3'] = 'bar3';
1114
        $_FILES['foo4'] = array('bar4');
1115
        $_SERVER['foo5'] = 'bar5';
1116
 
1117
        $request = Request::createFromGlobals();
1118
        $this->assertEquals('bar1', $request->query->get('foo1'), '::fromGlobals() uses values from $_GET');
1119
        $this->assertEquals('bar2', $request->request->get('foo2'), '::fromGlobals() uses values from $_POST');
1120
        $this->assertEquals('bar3', $request->cookies->get('foo3'), '::fromGlobals() uses values from $_COOKIE');
1121
        $this->assertEquals(array('bar4'), $request->files->get('foo4'), '::fromGlobals() uses values from $_FILES');
1122
        $this->assertEquals('bar5', $request->server->get('foo5'), '::fromGlobals() uses values from $_SERVER');
1123
 
1124
        unset($_GET['foo1'], $_POST['foo2'], $_COOKIE['foo3'], $_FILES['foo4'], $_SERVER['foo5']);
1125
 
1126
        $_SERVER['REQUEST_METHOD'] = $method;
1127
        $_SERVER['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
1128
        $request = RequestContentProxy::createFromGlobals();
1129
        $this->assertEquals($normalizedMethod, $request->getMethod());
1130
        $this->assertEquals('mycontent', $request->request->get('content'));
1131
 
1132
        unset($_SERVER['REQUEST_METHOD'], $_SERVER['CONTENT_TYPE']);
1133
 
1134
        Request::createFromGlobals();
1135
        Request::enableHttpMethodParameterOverride();
1136
        $_POST['_method'] = $method;
1137
        $_POST['foo6'] = 'bar6';
1138
        $_SERVER['REQUEST_METHOD'] = 'PoSt';
1139
        $request = Request::createFromGlobals();
1140
        $this->assertEquals($normalizedMethod, $request->getMethod());
1141
        $this->assertEquals('POST', $request->getRealMethod());
1142
        $this->assertEquals('bar6', $request->request->get('foo6'));
1143
 
1144
        unset($_POST['_method'], $_POST['foo6'], $_SERVER['REQUEST_METHOD']);
1145
        $this->disableHttpMethodParameterOverride();
1146
    }
1147
 
1148
    public function testOverrideGlobals()
1149
    {
1150
        $request = new Request();
1151
        $request->initialize(array('foo' => 'bar'));
1152
 
1153
        // as the Request::overrideGlobals really work, it erase $_SERVER, so we must backup it
1154
        $server = $_SERVER;
1155
 
1156
        $request->overrideGlobals();
1157
 
1158
        $this->assertEquals(array('foo' => 'bar'), $_GET);
1159
 
1160
        $request->initialize(array(), array('foo' => 'bar'));
1161
        $request->overrideGlobals();
1162
 
1163
        $this->assertEquals(array('foo' => 'bar'), $_POST);
1164
 
1165
        $this->assertArrayNotHasKey('HTTP_X_FORWARDED_PROTO', $_SERVER);
1166
 
1167
        $request->headers->set('X_FORWARDED_PROTO', 'https');
1168
 
1169
        Request::setTrustedProxies(array('1.1.1.1'));
1170
        $this->assertFalse($request->isSecure());
1171
        $request->server->set('REMOTE_ADDR', '1.1.1.1');
1172
        $this->assertTrue($request->isSecure());
1173
        Request::setTrustedProxies(array());
1174
 
1175
        $request->overrideGlobals();
1176
 
1177
        $this->assertArrayHasKey('HTTP_X_FORWARDED_PROTO', $_SERVER);
1178
 
1179
        $request->headers->set('CONTENT_TYPE', 'multipart/form-data');
1180
        $request->headers->set('CONTENT_LENGTH', 12345);
1181
 
1182
        $request->overrideGlobals();
1183
 
1184
        $this->assertArrayHasKey('CONTENT_TYPE', $_SERVER);
1185
        $this->assertArrayHasKey('CONTENT_LENGTH', $_SERVER);
1186
 
1187
        $request->initialize(array('foo' => 'bar', 'baz' => 'foo'));
1188
        $request->query->remove('baz');
1189
 
1190
        $request->overrideGlobals();
1191
 
1192
        $this->assertEquals(array('foo' => 'bar'), $_GET);
1193
        $this->assertEquals('foo=bar', $_SERVER['QUERY_STRING']);
1194
        $this->assertEquals('foo=bar', $request->server->get('QUERY_STRING'));
1195
 
1196
        // restore initial $_SERVER array
1197
        $_SERVER = $server;
1198
    }
1199
 
1200
    public function testGetScriptName()
1201
    {
1202
        $request = new Request();
1203
        $this->assertEquals('', $request->getScriptName());
1204
 
1205
        $server = array();
1206
        $server['SCRIPT_NAME'] = '/index.php';
1207
 
1208
        $request->initialize(array(), array(), array(), array(), array(), $server);
1209
 
1210
        $this->assertEquals('/index.php', $request->getScriptName());
1211
 
1212
        $server = array();
1213
        $server['ORIG_SCRIPT_NAME'] = '/frontend.php';
1214
        $request->initialize(array(), array(), array(), array(), array(), $server);
1215
 
1216
        $this->assertEquals('/frontend.php', $request->getScriptName());
1217
 
1218
        $server = array();
1219
        $server['SCRIPT_NAME'] = '/index.php';
1220
        $server['ORIG_SCRIPT_NAME'] = '/frontend.php';
1221
        $request->initialize(array(), array(), array(), array(), array(), $server);
1222
 
1223
        $this->assertEquals('/index.php', $request->getScriptName());
1224
    }
1225
 
1226
    public function testGetBasePath()
1227
    {
1228
        $request = new Request();
1229
        $this->assertEquals('', $request->getBasePath());
1230
 
1231
        $server = array();
1232
        $server['SCRIPT_FILENAME'] = '/some/where/index.php';
1233
        $request->initialize(array(), array(), array(), array(), array(), $server);
1234
        $this->assertEquals('', $request->getBasePath());
1235
 
1236
        $server = array();
1237
        $server['SCRIPT_FILENAME'] = '/some/where/index.php';
1238
        $server['SCRIPT_NAME'] = '/index.php';
1239
        $request->initialize(array(), array(), array(), array(), array(), $server);
1240
 
1241
        $this->assertEquals('', $request->getBasePath());
1242
 
1243
        $server = array();
1244
        $server['SCRIPT_FILENAME'] = '/some/where/index.php';
1245
        $server['PHP_SELF'] = '/index.php';
1246
        $request->initialize(array(), array(), array(), array(), array(), $server);
1247
 
1248
        $this->assertEquals('', $request->getBasePath());
1249
 
1250
        $server = array();
1251
        $server['SCRIPT_FILENAME'] = '/some/where/index.php';
1252
        $server['ORIG_SCRIPT_NAME'] = '/index.php';
1253
        $request->initialize(array(), array(), array(), array(), array(), $server);
1254
 
1255
        $this->assertEquals('', $request->getBasePath());
1256
    }
1257
 
1258
    public function testGetPathInfo()
1259
    {
1260
        $request = new Request();
1261
        $this->assertEquals('/', $request->getPathInfo());
1262
 
1263
        $server = array();
1264
        $server['REQUEST_URI'] = '/path/info';
1265
        $request->initialize(array(), array(), array(), array(), array(), $server);
1266
 
1267
        $this->assertEquals('/path/info', $request->getPathInfo());
1268
 
1269
        $server = array();
1270
        $server['REQUEST_URI'] = '/path%20test/info';
1271
        $request->initialize(array(), array(), array(), array(), array(), $server);
1272
 
1273
        $this->assertEquals('/path%20test/info', $request->getPathInfo());
1274
    }
1275
 
1276
    public function testGetParameterPrecedence()
1277
    {
1278
        $request = new Request();
1279
        $request->attributes->set('foo', 'attr');
1280
        $request->query->set('foo', 'query');
1281
        $request->request->set('foo', 'body');
1282
 
1283
        $this->assertSame('attr', $request->get('foo'));
1284
 
1285
        $request->attributes->remove('foo');
1286
        $this->assertSame('query', $request->get('foo'));
1287
 
1288
        $request->query->remove('foo');
1289
        $this->assertSame('body', $request->get('foo'));
1290
 
1291
        $request->request->remove('foo');
1292
        $this->assertNull($request->get('foo'));
1293
    }
1294
 
1295
    public function testGetPreferredLanguage()
1296
    {
1297
        $request = new Request();
1298
        $this->assertNull($request->getPreferredLanguage());
1299
        $this->assertNull($request->getPreferredLanguage(array()));
1300
        $this->assertEquals('fr', $request->getPreferredLanguage(array('fr')));
1301
        $this->assertEquals('fr', $request->getPreferredLanguage(array('fr', 'en')));
1302
        $this->assertEquals('en', $request->getPreferredLanguage(array('en', 'fr')));
1303
        $this->assertEquals('fr-ch', $request->getPreferredLanguage(array('fr-ch', 'fr-fr')));
1304
 
1305
        $request = new Request();
1306
        $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
1307
        $this->assertEquals('en', $request->getPreferredLanguage(array('en', 'en-us')));
1308
 
1309
        $request = new Request();
1310
        $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
1311
        $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));
1312
 
1313
        $request = new Request();
1314
        $request->headers->set('Accept-language', 'zh, en-us; q=0.8');
1315
        $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));
1316
 
1317
        $request = new Request();
1318
        $request->headers->set('Accept-language', 'zh, en-us; q=0.8, fr-fr; q=0.6, fr; q=0.5');
1319
        $this->assertEquals('en', $request->getPreferredLanguage(array('fr', 'en')));
1320
    }
1321
 
1322
    public function testIsXmlHttpRequest()
1323
    {
1324
        $request = new Request();
1325
        $this->assertFalse($request->isXmlHttpRequest());
1326
 
1327
        $request->headers->set('X-Requested-With', 'XMLHttpRequest');
1328
        $this->assertTrue($request->isXmlHttpRequest());
1329
 
1330
        $request->headers->remove('X-Requested-With');
1331
        $this->assertFalse($request->isXmlHttpRequest());
1332
    }
1333
 
1334
    /**
1335
     * @requires extension intl
1336
     */
1337
    public function testIntlLocale()
1338
    {
1339
        $request = new Request();
1340
 
1341
        $request->setDefaultLocale('fr');
1342
        $this->assertEquals('fr', $request->getLocale());
1343
        $this->assertEquals('fr', \Locale::getDefault());
1344
 
1345
        $request->setLocale('en');
1346
        $this->assertEquals('en', $request->getLocale());
1347
        $this->assertEquals('en', \Locale::getDefault());
1348
 
1349
        $request->setDefaultLocale('de');
1350
        $this->assertEquals('en', $request->getLocale());
1351
        $this->assertEquals('en', \Locale::getDefault());
1352
    }
1353
 
1354
    public function testGetCharsets()
1355
    {
1356
        $request = new Request();
1357
        $this->assertEquals(array(), $request->getCharsets());
1358
        $request->headers->set('Accept-Charset', 'ISO-8859-1, US-ASCII, UTF-8; q=0.8, ISO-10646-UCS-2; q=0.6');
1359
        $this->assertEquals(array(), $request->getCharsets()); // testing caching
1360
 
1361
        $request = new Request();
1362
        $request->headers->set('Accept-Charset', 'ISO-8859-1, US-ASCII, UTF-8; q=0.8, ISO-10646-UCS-2; q=0.6');
1363
        $this->assertEquals(array('ISO-8859-1', 'US-ASCII', 'UTF-8', 'ISO-10646-UCS-2'), $request->getCharsets());
1364
 
1365
        $request = new Request();
1366
        $request->headers->set('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7');
1367
        $this->assertEquals(array('ISO-8859-1', 'utf-8', '*'), $request->getCharsets());
1368
    }
1369
 
1370
    public function testGetEncodings()
1371
    {
1372
        $request = new Request();
1373
        $this->assertEquals(array(), $request->getEncodings());
1374
        $request->headers->set('Accept-Encoding', 'gzip,deflate,sdch');
1375
        $this->assertEquals(array(), $request->getEncodings()); // testing caching
1376
 
1377
        $request = new Request();
1378
        $request->headers->set('Accept-Encoding', 'gzip,deflate,sdch');
1379
        $this->assertEquals(array('gzip', 'deflate', 'sdch'), $request->getEncodings());
1380
 
1381
        $request = new Request();
1382
        $request->headers->set('Accept-Encoding', 'gzip;q=0.4,deflate;q=0.9,compress;q=0.7');
1383
        $this->assertEquals(array('deflate', 'compress', 'gzip'), $request->getEncodings());
1384
    }
1385
 
1386
    public function testGetAcceptableContentTypes()
1387
    {
1388
        $request = new Request();
1389
        $this->assertEquals(array(), $request->getAcceptableContentTypes());
1390
        $request->headers->set('Accept', 'application/vnd.wap.wmlscriptc, text/vnd.wap.wml, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html, multipart/mixed, */*');
1391
        $this->assertEquals(array(), $request->getAcceptableContentTypes()); // testing caching
1392
 
1393
        $request = new Request();
1394
        $request->headers->set('Accept', 'application/vnd.wap.wmlscriptc, text/vnd.wap.wml, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html, multipart/mixed, */*');
1395
        $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());
1396
    }
1397
 
1398
    public function testGetLanguages()
1399
    {
1400
        $request = new Request();
1401
        $this->assertEquals(array(), $request->getLanguages());
1402
 
1403
        $request = new Request();
1404
        $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
1405
        $this->assertEquals(array('zh', 'en_US', 'en'), $request->getLanguages());
1406
        $this->assertEquals(array('zh', 'en_US', 'en'), $request->getLanguages());
1407
 
1408
        $request = new Request();
1409
        $request->headers->set('Accept-language', 'zh, en-us; q=0.6, en; q=0.8');
1410
        $this->assertEquals(array('zh', 'en', 'en_US'), $request->getLanguages()); // Test out of order qvalues
1411
 
1412
        $request = new Request();
1413
        $request->headers->set('Accept-language', 'zh, en, en-us');
1414
        $this->assertEquals(array('zh', 'en', 'en_US'), $request->getLanguages()); // Test equal weighting without qvalues
1415
 
1416
        $request = new Request();
1417
        $request->headers->set('Accept-language', 'zh; q=0.6, en, en-us; q=0.6');
1418
        $this->assertEquals(array('en', 'zh', 'en_US'), $request->getLanguages()); // Test equal weighting with qvalues
1419
 
1420
        $request = new Request();
1421
        $request->headers->set('Accept-language', 'zh, i-cherokee; q=0.6');
1422
        $this->assertEquals(array('zh', 'cherokee'), $request->getLanguages());
1423
    }
1424
 
1425
    public function testGetRequestFormat()
1426
    {
1427
        $request = new Request();
1428
        $this->assertEquals('html', $request->getRequestFormat());
1429
 
1430
        $request = new Request();
1431
        $this->assertNull($request->getRequestFormat(null));
1432
 
1433
        $request = new Request();
1434
        $this->assertNull($request->setRequestFormat('foo'));
1435
        $this->assertEquals('foo', $request->getRequestFormat(null));
1436
 
1437
        $request = new Request(array('_format' => 'foo'));
1438
        $this->assertEquals('html', $request->getRequestFormat());
1439
    }
1440
 
1441
    public function testHasSession()
1442
    {
1443
        $request = new Request();
1444
 
1445
        $this->assertFalse($request->hasSession());
1446
        $request->setSession(new Session(new MockArraySessionStorage()));
1447
        $this->assertTrue($request->hasSession());
1448
    }
1449
 
1450
    public function testGetSession()
1451
    {
1452
        $request = new Request();
1453
 
1454
        $request->setSession(new Session(new MockArraySessionStorage()));
1455
        $this->assertTrue($request->hasSession());
1456
 
1457
        $session = $request->getSession();
1458
        $this->assertObjectHasAttribute('storage', $session);
1459
        $this->assertObjectHasAttribute('flashName', $session);
1460
        $this->assertObjectHasAttribute('attributeName', $session);
1461
    }
1462
 
1463
    public function testHasPreviousSession()
1464
    {
1465
        $request = new Request();
1466
 
1467
        $this->assertFalse($request->hasPreviousSession());
1468
        $request->cookies->set('MOCKSESSID', 'foo');
1469
        $this->assertFalse($request->hasPreviousSession());
1470
        $request->setSession(new Session(new MockArraySessionStorage()));
1471
        $this->assertTrue($request->hasPreviousSession());
1472
    }
1473
 
1474
    public function testToString()
1475
    {
1476
        $request = new Request();
1477
 
1478
        $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
1479
 
1480
        $this->assertContains('Accept-Language: zh, en-us; q=0.8, en; q=0.6', $request->__toString());
1481
    }
1482
 
1483
    public function testIsMethod()
1484
    {
1485
        $request = new Request();
1486
        $request->setMethod('POST');
1487
        $this->assertTrue($request->isMethod('POST'));
1488
        $this->assertTrue($request->isMethod('post'));
1489
        $this->assertFalse($request->isMethod('GET'));
1490
        $this->assertFalse($request->isMethod('get'));
1491
 
1492
        $request->setMethod('GET');
1493
        $this->assertTrue($request->isMethod('GET'));
1494
        $this->assertTrue($request->isMethod('get'));
1495
        $this->assertFalse($request->isMethod('POST'));
1496
        $this->assertFalse($request->isMethod('post'));
1497
    }
1498
 
1499
    /**
1500
     * @dataProvider getBaseUrlData
1501
     */
1502
    public function testGetBaseUrl($uri, $server, $expectedBaseUrl, $expectedPathInfo)
1503
    {
1504
        $request = Request::create($uri, 'GET', array(), array(), array(), $server);
1505
 
1506
        $this->assertSame($expectedBaseUrl, $request->getBaseUrl(), 'baseUrl');
1507
        $this->assertSame($expectedPathInfo, $request->getPathInfo(), 'pathInfo');
1508
    }
1509
 
1510
    public function getBaseUrlData()
1511
    {
1512
        return array(
1513
            array(
1514
                '/fruit/strawberry/1234index.php/blah',
1515
                array(
1516
                    'SCRIPT_FILENAME' => 'E:/Sites/cc-new/public_html/fruit/index.php',
1517
                    'SCRIPT_NAME' => '/fruit/index.php',
1518
                    'PHP_SELF' => '/fruit/index.php',
1519
                ),
1520
                '/fruit',
1521
                '/strawberry/1234index.php/blah',
1522
            ),
1523
            array(
1524
                '/fruit/strawberry/1234index.php/blah',
1525
                array(
1526
                    'SCRIPT_FILENAME' => 'E:/Sites/cc-new/public_html/index.php',
1527
                    'SCRIPT_NAME' => '/index.php',
1528
                    'PHP_SELF' => '/index.php',
1529
                ),
1530
                '',
1531
                '/fruit/strawberry/1234index.php/blah',
1532
            ),
1533
            array(
1534
                '/foo%20bar/',
1535
                array(
1536
                    'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
1537
                    'SCRIPT_NAME' => '/foo bar/app.php',
1538
                    'PHP_SELF' => '/foo bar/app.php',
1539
                ),
1540
                '/foo%20bar',
1541
                '/',
1542
            ),
1543
            array(
1544
                '/foo%20bar/home',
1545
                array(
1546
                    'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
1547
                    'SCRIPT_NAME' => '/foo bar/app.php',
1548
                    'PHP_SELF' => '/foo bar/app.php',
1549
                ),
1550
                '/foo%20bar',
1551
                '/home',
1552
            ),
1553
            array(
1554
                '/foo%20bar/app.php/home',
1555
                array(
1556
                    'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
1557
                    'SCRIPT_NAME' => '/foo bar/app.php',
1558
                    'PHP_SELF' => '/foo bar/app.php',
1559
                ),
1560
                '/foo%20bar/app.php',
1561
                '/home',
1562
            ),
1563
            array(
1564
                '/foo%20bar/app.php/home%3Dbaz',
1565
                array(
1566
                    'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
1567
                    'SCRIPT_NAME' => '/foo bar/app.php',
1568
                    'PHP_SELF' => '/foo bar/app.php',
1569
                ),
1570
                '/foo%20bar/app.php',
1571
                '/home%3Dbaz',
1572
            ),
1573
            array(
1574
                '/foo/bar+baz',
1575
                array(
1576
                    'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo/app.php',
1577
                    'SCRIPT_NAME' => '/foo/app.php',
1578
                    'PHP_SELF' => '/foo/app.php',
1579
                ),
1580
                '/foo',
1581
                '/bar+baz',
1582
            ),
1583
        );
1584
    }
1585
 
1586
    /**
1587
     * @dataProvider urlencodedStringPrefixData
1588
     */
1589
    public function testUrlencodedStringPrefix($string, $prefix, $expect)
1590
    {
1591
        $request = new Request();
1592
 
1593
        $me = new \ReflectionMethod($request, 'getUrlencodedPrefix');
1594
        $me->setAccessible(true);
1595
 
1596
        $this->assertSame($expect, $me->invoke($request, $string, $prefix));
1597
    }
1598
 
1599
    public function urlencodedStringPrefixData()
1600
    {
1601
        return array(
1602
            array('foo', 'foo', 'foo'),
1603
            array('fo%6f', 'foo', 'fo%6f'),
1604
            array('foo/bar', 'foo', 'foo'),
1605
            array('fo%6f/bar', 'foo', 'fo%6f'),
1606
            array('f%6f%6f/bar', 'foo', 'f%6f%6f'),
1607
            array('%66%6F%6F/bar', 'foo', '%66%6F%6F'),
1608
            array('fo+o/bar', 'fo+o', 'fo+o'),
1609
            array('fo%2Bo/bar', 'fo+o', 'fo%2Bo'),
1610
        );
1611
    }
1612
 
1613
    private function disableHttpMethodParameterOverride()
1614
    {
1615
        $class = new \ReflectionClass('Symfony\\Component\\HttpFoundation\\Request');
1616
        $property = $class->getProperty('httpMethodParameterOverride');
1617
        $property->setAccessible(true);
1618
        $property->setValue(false);
1619
    }
1620
 
1621
    private function getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies)
1622
    {
1623
        $request = new Request();
1624
 
1625
        $server = array('REMOTE_ADDR' => $remoteAddr);
1626
        if (null !== $httpForwardedFor) {
1627
            $server['HTTP_X_FORWARDED_FOR'] = $httpForwardedFor;
1628
        }
1629
 
1630
        if ($trustedProxies) {
1631
            Request::setTrustedProxies($trustedProxies);
1632
        }
1633
 
1634
        $request->initialize(array(), array(), array(), array(), array(), $server);
1635
 
1636
        return $request;
1637
    }
1638
 
1639
    private function getRequestInstanceForClientIpsForwardedTests($remoteAddr, $httpForwarded, $trustedProxies)
1640
    {
1641
        $request = new Request();
1642
 
1643
        $server = array('REMOTE_ADDR' => $remoteAddr);
1644
 
1645
        if (null !== $httpForwarded) {
1646
            $server['HTTP_FORWARDED'] = $httpForwarded;
1647
        }
1648
 
1649
        if ($trustedProxies) {
1650
            Request::setTrustedProxies($trustedProxies);
1651
        }
1652
 
1653
        $request->initialize(array(), array(), array(), array(), array(), $server);
1654
 
1655
        return $request;
1656
    }
1657
 
1658
    public function testTrustedProxies()
1659
    {
1660
        $request = Request::create('http://example.com/');
1661
        $request->server->set('REMOTE_ADDR', '3.3.3.3');
1662
        $request->headers->set('X_FORWARDED_FOR', '1.1.1.1, 2.2.2.2');
1663
        $request->headers->set('X_FORWARDED_HOST', 'foo.example.com, real.example.com:8080');
1664
        $request->headers->set('X_FORWARDED_PROTO', 'https');
1665
        $request->headers->set('X_FORWARDED_PORT', 443);
1666
        $request->headers->set('X_MY_FOR', '3.3.3.3, 4.4.4.4');
1667
        $request->headers->set('X_MY_HOST', 'my.example.com');
1668
        $request->headers->set('X_MY_PROTO', 'http');
1669
        $request->headers->set('X_MY_PORT', 81);
1670
 
1671
        // no trusted proxies
1672
        $this->assertEquals('3.3.3.3', $request->getClientIp());
1673
        $this->assertEquals('example.com', $request->getHost());
1674
        $this->assertEquals(80, $request->getPort());
1675
        $this->assertFalse($request->isSecure());
1676
 
1677
        // disabling proxy trusting
1678
        Request::setTrustedProxies(array());
1679
        $this->assertEquals('3.3.3.3', $request->getClientIp());
1680
        $this->assertEquals('example.com', $request->getHost());
1681
        $this->assertEquals(80, $request->getPort());
1682
        $this->assertFalse($request->isSecure());
1683
 
1684
        // request is forwarded by a non-trusted proxy
1685
        Request::setTrustedProxies(array('2.2.2.2'));
1686
        $this->assertEquals('3.3.3.3', $request->getClientIp());
1687
        $this->assertEquals('example.com', $request->getHost());
1688
        $this->assertEquals(80, $request->getPort());
1689
        $this->assertFalse($request->isSecure());
1690
 
1691
        // trusted proxy via setTrustedProxies()
1692
        Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'));
1693
        $this->assertEquals('1.1.1.1', $request->getClientIp());
1694
        $this->assertEquals('real.example.com', $request->getHost());
1695
        $this->assertEquals(443, $request->getPort());
1696
        $this->assertTrue($request->isSecure());
1697
 
1698
        // trusted proxy via setTrustedProxies()
1699
        Request::setTrustedProxies(array('3.3.3.4', '2.2.2.2'));
1700
        $this->assertEquals('3.3.3.3', $request->getClientIp());
1701
        $this->assertEquals('example.com', $request->getHost());
1702
        $this->assertEquals(80, $request->getPort());
1703
        $this->assertFalse($request->isSecure());
1704
 
1705
        // check various X_FORWARDED_PROTO header values
1706
        Request::setTrustedProxies(array('3.3.3.3', '2.2.2.2'));
1707
        $request->headers->set('X_FORWARDED_PROTO', 'ssl');
1708
        $this->assertTrue($request->isSecure());
1709
 
1710
        $request->headers->set('X_FORWARDED_PROTO', 'https, http');
1711
        $this->assertTrue($request->isSecure());
1712
 
1713
        // custom header names
1714
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_MY_FOR');
1715
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_MY_HOST');
1716
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_MY_PORT');
1717
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_MY_PROTO');
1718
        $this->assertEquals('4.4.4.4', $request->getClientIp());
1719
        $this->assertEquals('my.example.com', $request->getHost());
1720
        $this->assertEquals(81, $request->getPort());
1721
        $this->assertFalse($request->isSecure());
1722
 
1723
        // disabling via empty header names
1724
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, null);
1725
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, null);
1726
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, null);
1727
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, null);
1728
        $this->assertEquals('3.3.3.3', $request->getClientIp());
1729
        $this->assertEquals('example.com', $request->getHost());
1730
        $this->assertEquals(80, $request->getPort());
1731
        $this->assertFalse($request->isSecure());
1732
 
1733
        // reset
1734
        Request::setTrustedProxies(array());
1735
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_FORWARDED_FOR');
1736
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_FORWARDED_HOST');
1737
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_FORWARDED_PORT');
1738
        Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_FORWARDED_PROTO');
1739
    }
1740
 
1741
    /**
1742
     * @expectedException \InvalidArgumentException
1743
     */
1744
    public function testSetTrustedProxiesInvalidHeaderName()
1745
    {
1746
        Request::create('http://example.com/');
1747
        Request::setTrustedHeaderName('bogus name', 'X_MY_FOR');
1748
    }
1749
 
1750
    /**
1751
     * @expectedException \InvalidArgumentException
1752
     */
1753
    public function testGetTrustedProxiesInvalidHeaderName()
1754
    {
1755
        Request::create('http://example.com/');
1756
        Request::getTrustedHeaderName('bogus name');
1757
    }
1758
 
1759
    /**
1760
     * @dataProvider iisRequestUriProvider
1761
     */
1762
    public function testIISRequestUri($headers, $server, $expectedRequestUri)
1763
    {
1764
        $request = new Request();
1765
        $request->headers->replace($headers);
1766
        $request->server->replace($server);
1767
 
1768
        $this->assertEquals($expectedRequestUri, $request->getRequestUri(), '->getRequestUri() is correct');
1769
 
1770
        $subRequestUri = '/bar/foo';
1771
        $subRequest = Request::create($subRequestUri, 'get', array(), array(), array(), $request->server->all());
1772
        $this->assertEquals($subRequestUri, $subRequest->getRequestUri(), '->getRequestUri() is correct in sub request');
1773
    }
1774
 
1775
    public function iisRequestUriProvider()
1776
    {
1777
        return array(
1778
            array(
1779
                array(
1780
                    'X_ORIGINAL_URL' => '/foo/bar',
1781
                ),
1782
                array(),
1783
                '/foo/bar',
1784
            ),
1785
            array(
1786
                array(
1787
                    'X_REWRITE_URL' => '/foo/bar',
1788
                ),
1789
                array(),
1790
                '/foo/bar',
1791
            ),
1792
            array(
1793
                array(),
1794
                array(
1795
                    'IIS_WasUrlRewritten' => '1',
1796
                    'UNENCODED_URL' => '/foo/bar',
1797
                ),
1798
                '/foo/bar',
1799
            ),
1800
            array(
1801
                array(
1802
                    'X_ORIGINAL_URL' => '/foo/bar',
1803
                ),
1804
                array(
1805
                    'HTTP_X_ORIGINAL_URL' => '/foo/bar',
1806
                ),
1807
                '/foo/bar',
1808
            ),
1809
            array(
1810
                array(
1811
                    'X_ORIGINAL_URL' => '/foo/bar',
1812
                ),
1813
                array(
1814
                    'IIS_WasUrlRewritten' => '1',
1815
                    'UNENCODED_URL' => '/foo/bar',
1816
                ),
1817
                '/foo/bar',
1818
            ),
1819
            array(
1820
                array(
1821
                    'X_ORIGINAL_URL' => '/foo/bar',
1822
                ),
1823
                array(
1824
                    'HTTP_X_ORIGINAL_URL' => '/foo/bar',
1825
                    'IIS_WasUrlRewritten' => '1',
1826
                    'UNENCODED_URL' => '/foo/bar',
1827
                ),
1828
                '/foo/bar',
1829
            ),
1830
            array(
1831
                array(),
1832
                array(
1833
                    'ORIG_PATH_INFO' => '/foo/bar',
1834
                ),
1835
                '/foo/bar',
1836
            ),
1837
            array(
1838
                array(),
1839
                array(
1840
                    'ORIG_PATH_INFO' => '/foo/bar',
1841
                    'QUERY_STRING' => 'foo=bar',
1842
                ),
1843
                '/foo/bar?foo=bar',
1844
            ),
1845
        );
1846
    }
1847
 
1848
    public function testTrustedHosts()
1849
    {
1850
        // create a request
1851
        $request = Request::create('/');
1852
 
1853
        // no trusted host set -> no host check
1854
        $request->headers->set('host', 'evil.com');
1855
        $this->assertEquals('evil.com', $request->getHost());
1856
 
1857
        // add a trusted domain and all its subdomains
1858
        Request::setTrustedHosts(array('^([a-z]{9}\.)?trusted\.com$'));
1859
 
1860
        // untrusted host
1861
        $request->headers->set('host', 'evil.com');
1862
        try {
1863
            $request->getHost();
1864
            $this->fail('Request::getHost() should throw an exception when host is not trusted.');
1865
        } catch (\UnexpectedValueException $e) {
1866
            $this->assertEquals('Untrusted Host "evil.com"', $e->getMessage());
1867
        }
1868
 
1869
        // trusted hosts
1870
        $request->headers->set('host', 'trusted.com');
1871
        $this->assertEquals('trusted.com', $request->getHost());
1872
        $this->assertEquals(80, $request->getPort());
1873
 
1874
        $request->server->set('HTTPS', true);
1875
        $request->headers->set('host', 'trusted.com');
1876
        $this->assertEquals('trusted.com', $request->getHost());
1877
        $this->assertEquals(443, $request->getPort());
1878
        $request->server->set('HTTPS', false);
1879
 
1880
        $request->headers->set('host', 'trusted.com:8000');
1881
        $this->assertEquals('trusted.com', $request->getHost());
1882
        $this->assertEquals(8000, $request->getPort());
1883
 
1884
        $request->headers->set('host', 'subdomain.trusted.com');
1885
        $this->assertEquals('subdomain.trusted.com', $request->getHost());
1886
 
1887
        // reset request for following tests
1888
        Request::setTrustedHosts(array());
1889
    }
1890
 
1891
    public function testFactory()
1892
    {
1893
        Request::setFactory(function (array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) {
1894
            return new NewRequest();
1895
        });
1896
 
1897
        $this->assertEquals('foo', Request::create('/')->getFoo());
1898
 
1899
        Request::setFactory(null);
1900
    }
1901
 
1902
    /**
1903
     * @dataProvider getLongHostNames
1904
     */
1905
    public function testVeryLongHosts($host)
1906
    {
1907
        $start = microtime(true);
1908
 
1909
        $request = Request::create('/');
1910
        $request->headers->set('host', $host);
1911
        $this->assertEquals($host, $request->getHost());
1912
        $this->assertLessThan(5, microtime(true) - $start);
1913
    }
1914
 
1915
    /**
1916
     * @dataProvider getHostValidities
1917
     */
1918
    public function testHostValidity($host, $isValid, $expectedHost = null, $expectedPort = null)
1919
    {
1920
        $request = Request::create('/');
1921
        $request->headers->set('host', $host);
1922
 
1923
        if ($isValid) {
1924
            $this->assertSame($expectedHost ?: $host, $request->getHost());
1925
            if ($expectedPort) {
1926
                $this->assertSame($expectedPort, $request->getPort());
1927
            }
1928
        } else {
1929
            $this->setExpectedException('UnexpectedValueException', 'Invalid Host');
1930
            $request->getHost();
1931
        }
1932
    }
1933
 
1934
    public function getHostValidities()
1935
    {
1936
        return array(
1937
            array('.a', false),
1938
            array('a..', false),
1939
            array('a.', true),
1940
            array("\xE9", false),
1941
            array('[::1]', true),
1942
            array('[::1]:80', true, '[::1]', 80),
1943
            array(str_repeat('.', 101), false),
1944
        );
1945
    }
1946
 
1947
    public function getLongHostNames()
1948
    {
1949
        return array(
1950
            array('a'.str_repeat('.a', 40000)),
1951
            array(str_repeat(':', 101)),
1952
        );
1953
    }
1954
}
1955
 
1956
class RequestContentProxy extends Request
1957
{
1958
    public function getContent($asResource = false)
1959
    {
1960
        return http_build_query(array('_method' => 'PUT', 'content' => 'mycontent'));
1961
    }
1962
}
1963
 
1964
class NewRequest extends Request
1965
{
1966
    public function getFoo()
1967
    {
1968
        return 'foo';
1969
    }
1970
}