PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 3.3.1
GiveWP – Donation Plugin and Fundraising Platform v3.3.1
4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / vendor / vendor-prefixed / symfony / http-foundation / Tests / RequestTest.php
give / vendor / vendor-prefixed / symfony / http-foundation / Tests Last commit date
File 2 years ago Fixtures 2 years ago Session 2 years ago schema 2 years ago AcceptHeaderItemTest.php 2 years ago AcceptHeaderTest.php 2 years ago ApacheRequestTest.php 2 years ago BinaryFileResponseTest.php 2 years ago CookieTest.php 2 years ago ExpressionRequestMatcherTest.php 2 years ago FileBagTest.php 2 years ago HeaderBagTest.php 2 years ago IpUtilsTest.php 2 years ago JsonResponseTest.php 2 years ago ParameterBagTest.php 2 years ago RedirectResponseTest.php 2 years ago RequestMatcherTest.php 2 years ago RequestStackTest.php 2 years ago RequestTest.php 2 years ago ResponseFunctionalTest.php 2 years ago ResponseHeaderBagTest.php 2 years ago ResponseTest.php 2 years ago ResponseTestCase.php 2 years ago ServerBagTest.php 2 years ago StreamedResponseTest.php 2 years ago
RequestTest.php
2455 lines
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 * Modified by impress-org on 23-January-2024 using Strauss.
12 * @see https://github.com/BrianHenryIE/strauss
13 */
14
15 namespace Give\Vendors\Symfony\Component\HttpFoundation\Tests;
16
17 use PHPUnit\Framework\TestCase;
18 use Give\Vendors\Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
19 use Give\Vendors\Symfony\Component\HttpFoundation\Request;
20 use Give\Vendors\Symfony\Component\HttpFoundation\Session\Session;
21 use Give\Vendors\Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
22
23 class RequestTest extends TestCase
24 {
25 protected function tearDown()
26 {
27 Request::setTrustedProxies([], -1);
28 Request::setTrustedHosts([]);
29 }
30
31 public function testInitialize()
32 {
33 $request = new Request();
34
35 $request->initialize(['foo' => 'bar']);
36 $this->assertEquals('bar', $request->query->get('foo'), '->initialize() takes an array of query parameters as its first argument');
37
38 $request->initialize([], ['foo' => 'bar']);
39 $this->assertEquals('bar', $request->request->get('foo'), '->initialize() takes an array of request parameters as its second argument');
40
41 $request->initialize([], [], ['foo' => 'bar']);
42 $this->assertEquals('bar', $request->attributes->get('foo'), '->initialize() takes an array of attributes as its third argument');
43
44 $request->initialize([], [], [], [], [], ['HTTP_FOO' => 'bar']);
45 $this->assertEquals('bar', $request->headers->get('FOO'), '->initialize() takes an array of HTTP headers as its sixth argument');
46 }
47
48 public function testGetLocale()
49 {
50 $request = new Request();
51 $request->setLocale('pl');
52 $locale = $request->getLocale();
53 $this->assertEquals('pl', $locale);
54 }
55
56 public function testGetUser()
57 {
58 $request = Request::create('http://user:password@test.com');
59 $user = $request->getUser();
60
61 $this->assertEquals('user', $user);
62 }
63
64 public function testGetPassword()
65 {
66 $request = Request::create('http://user:password@test.com');
67 $password = $request->getPassword();
68
69 $this->assertEquals('password', $password);
70 }
71
72 public function testIsNoCache()
73 {
74 $request = new Request();
75 $isNoCache = $request->isNoCache();
76
77 $this->assertFalse($isNoCache);
78 }
79
80 public function testGetContentType()
81 {
82 $request = new Request();
83 $contentType = $request->getContentType();
84
85 $this->assertNull($contentType);
86 }
87
88 public function testSetDefaultLocale()
89 {
90 $request = new Request();
91 $request->setDefaultLocale('pl');
92 $locale = $request->getLocale();
93
94 $this->assertEquals('pl', $locale);
95 }
96
97 public function testCreate()
98 {
99 $request = Request::create('http://test.com/foo?bar=baz');
100 $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
101 $this->assertEquals('/foo', $request->getPathInfo());
102 $this->assertEquals('bar=baz', $request->getQueryString());
103 $this->assertEquals(80, $request->getPort());
104 $this->assertEquals('test.com', $request->getHttpHost());
105 $this->assertFalse($request->isSecure());
106
107 $request = Request::create('http://test.com/foo', 'GET', ['bar' => 'baz']);
108 $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
109 $this->assertEquals('/foo', $request->getPathInfo());
110 $this->assertEquals('bar=baz', $request->getQueryString());
111 $this->assertEquals(80, $request->getPort());
112 $this->assertEquals('test.com', $request->getHttpHost());
113 $this->assertFalse($request->isSecure());
114
115 $request = Request::create('http://test.com/foo?bar=foo', 'GET', ['bar' => 'baz']);
116 $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
117 $this->assertEquals('/foo', $request->getPathInfo());
118 $this->assertEquals('bar=baz', $request->getQueryString());
119 $this->assertEquals(80, $request->getPort());
120 $this->assertEquals('test.com', $request->getHttpHost());
121 $this->assertFalse($request->isSecure());
122
123 $request = Request::create('https://test.com/foo?bar=baz');
124 $this->assertEquals('https://test.com/foo?bar=baz', $request->getUri());
125 $this->assertEquals('/foo', $request->getPathInfo());
126 $this->assertEquals('bar=baz', $request->getQueryString());
127 $this->assertEquals(443, $request->getPort());
128 $this->assertEquals('test.com', $request->getHttpHost());
129 $this->assertTrue($request->isSecure());
130
131 $request = Request::create('test.com:90/foo');
132 $this->assertEquals('http://test.com:90/foo', $request->getUri());
133 $this->assertEquals('/foo', $request->getPathInfo());
134 $this->assertEquals('test.com', $request->getHost());
135 $this->assertEquals('test.com:90', $request->getHttpHost());
136 $this->assertEquals(90, $request->getPort());
137 $this->assertFalse($request->isSecure());
138
139 $request = Request::create('https://test.com:90/foo');
140 $this->assertEquals('https://test.com:90/foo', $request->getUri());
141 $this->assertEquals('/foo', $request->getPathInfo());
142 $this->assertEquals('test.com', $request->getHost());
143 $this->assertEquals('test.com:90', $request->getHttpHost());
144 $this->assertEquals(90, $request->getPort());
145 $this->assertTrue($request->isSecure());
146
147 $request = Request::create('https://127.0.0.1:90/foo');
148 $this->assertEquals('https://127.0.0.1:90/foo', $request->getUri());
149 $this->assertEquals('/foo', $request->getPathInfo());
150 $this->assertEquals('127.0.0.1', $request->getHost());
151 $this->assertEquals('127.0.0.1:90', $request->getHttpHost());
152 $this->assertEquals(90, $request->getPort());
153 $this->assertTrue($request->isSecure());
154
155 $request = Request::create('https://[::1]:90/foo');
156 $this->assertEquals('https://[::1]:90/foo', $request->getUri());
157 $this->assertEquals('/foo', $request->getPathInfo());
158 $this->assertEquals('[::1]', $request->getHost());
159 $this->assertEquals('[::1]:90', $request->getHttpHost());
160 $this->assertEquals(90, $request->getPort());
161 $this->assertTrue($request->isSecure());
162
163 $request = Request::create('https://[::1]/foo');
164 $this->assertEquals('https://[::1]/foo', $request->getUri());
165 $this->assertEquals('/foo', $request->getPathInfo());
166 $this->assertEquals('[::1]', $request->getHost());
167 $this->assertEquals('[::1]', $request->getHttpHost());
168 $this->assertEquals(443, $request->getPort());
169 $this->assertTrue($request->isSecure());
170
171 $json = '{"jsonrpc":"2.0","method":"echo","id":7,"params":["Hello World"]}';
172 $request = Request::create('http://example.com/jsonrpc', 'POST', [], [], [], [], $json);
173 $this->assertEquals($json, $request->getContent());
174 $this->assertFalse($request->isSecure());
175
176 $request = Request::create('http://test.com');
177 $this->assertEquals('http://test.com/', $request->getUri());
178 $this->assertEquals('/', $request->getPathInfo());
179 $this->assertEquals('', $request->getQueryString());
180 $this->assertEquals(80, $request->getPort());
181 $this->assertEquals('test.com', $request->getHttpHost());
182 $this->assertFalse($request->isSecure());
183
184 $request = Request::create('http://test.com?test=1');
185 $this->assertEquals('http://test.com/?test=1', $request->getUri());
186 $this->assertEquals('/', $request->getPathInfo());
187 $this->assertEquals('test=1', $request->getQueryString());
188 $this->assertEquals(80, $request->getPort());
189 $this->assertEquals('test.com', $request->getHttpHost());
190 $this->assertFalse($request->isSecure());
191
192 $request = Request::create('http://test.com:90/?test=1');
193 $this->assertEquals('http://test.com:90/?test=1', $request->getUri());
194 $this->assertEquals('/', $request->getPathInfo());
195 $this->assertEquals('test=1', $request->getQueryString());
196 $this->assertEquals(90, $request->getPort());
197 $this->assertEquals('test.com:90', $request->getHttpHost());
198 $this->assertFalse($request->isSecure());
199
200 $request = Request::create('http://username:password@test.com');
201 $this->assertEquals('http://test.com/', $request->getUri());
202 $this->assertEquals('/', $request->getPathInfo());
203 $this->assertEquals('', $request->getQueryString());
204 $this->assertEquals(80, $request->getPort());
205 $this->assertEquals('test.com', $request->getHttpHost());
206 $this->assertEquals('username', $request->getUser());
207 $this->assertEquals('password', $request->getPassword());
208 $this->assertFalse($request->isSecure());
209
210 $request = Request::create('http://username@test.com');
211 $this->assertEquals('http://test.com/', $request->getUri());
212 $this->assertEquals('/', $request->getPathInfo());
213 $this->assertEquals('', $request->getQueryString());
214 $this->assertEquals(80, $request->getPort());
215 $this->assertEquals('test.com', $request->getHttpHost());
216 $this->assertEquals('username', $request->getUser());
217 $this->assertSame('', $request->getPassword());
218 $this->assertFalse($request->isSecure());
219
220 $request = Request::create('http://test.com/?foo');
221 $this->assertEquals('/?foo', $request->getRequestUri());
222 $this->assertEquals(['foo' => ''], $request->query->all());
223
224 // assume rewrite rule: (.*) --> app/app.php; app/ is a symlink to a symfony web/ directory
225 $request = Request::create('http://test.com/apparthotel-1234', 'GET', [], [], [],
226 [
227 'DOCUMENT_ROOT' => '/var/www/www.test.com',
228 'SCRIPT_FILENAME' => '/var/www/www.test.com/app/app.php',
229 'SCRIPT_NAME' => '/app/app.php',
230 'PHP_SELF' => '/app/app.php/apparthotel-1234',
231 ]);
232 $this->assertEquals('http://test.com/apparthotel-1234', $request->getUri());
233 $this->assertEquals('/apparthotel-1234', $request->getPathInfo());
234 $this->assertEquals('', $request->getQueryString());
235 $this->assertEquals(80, $request->getPort());
236 $this->assertEquals('test.com', $request->getHttpHost());
237 $this->assertFalse($request->isSecure());
238
239 // Fragment should not be included in the URI
240 $request = Request::create('http://test.com/foo#bar');
241 $this->assertEquals('http://test.com/foo', $request->getUri());
242 }
243
244 public function testCreateWithRequestUri()
245 {
246 $request = Request::create('http://test.com:80/foo');
247 $request->server->set('REQUEST_URI', 'http://test.com:80/foo');
248 $this->assertEquals('http://test.com/foo', $request->getUri());
249 $this->assertEquals('/foo', $request->getPathInfo());
250 $this->assertEquals('test.com', $request->getHost());
251 $this->assertEquals('test.com', $request->getHttpHost());
252 $this->assertEquals(80, $request->getPort());
253 $this->assertFalse($request->isSecure());
254
255 $request = Request::create('http://test.com:8080/foo');
256 $request->server->set('REQUEST_URI', 'http://test.com:8080/foo');
257 $this->assertEquals('http://test.com:8080/foo', $request->getUri());
258 $this->assertEquals('/foo', $request->getPathInfo());
259 $this->assertEquals('test.com', $request->getHost());
260 $this->assertEquals('test.com:8080', $request->getHttpHost());
261 $this->assertEquals(8080, $request->getPort());
262 $this->assertFalse($request->isSecure());
263
264 $request = Request::create('http://test.com/foo?bar=foo', 'GET', ['bar' => 'baz']);
265 $request->server->set('REQUEST_URI', 'http://test.com/foo?bar=foo');
266 $this->assertEquals('http://test.com/foo?bar=baz', $request->getUri());
267 $this->assertEquals('/foo', $request->getPathInfo());
268 $this->assertEquals('bar=baz', $request->getQueryString());
269 $this->assertEquals('test.com', $request->getHost());
270 $this->assertEquals('test.com', $request->getHttpHost());
271 $this->assertEquals(80, $request->getPort());
272 $this->assertFalse($request->isSecure());
273
274 $request = Request::create('https://test.com:443/foo');
275 $request->server->set('REQUEST_URI', 'https://test.com:443/foo');
276 $this->assertEquals('https://test.com/foo', $request->getUri());
277 $this->assertEquals('/foo', $request->getPathInfo());
278 $this->assertEquals('test.com', $request->getHost());
279 $this->assertEquals('test.com', $request->getHttpHost());
280 $this->assertEquals(443, $request->getPort());
281 $this->assertTrue($request->isSecure());
282
283 // Fragment should not be included in the URI
284 $request = Request::create('http://test.com/foo#bar');
285 $request->server->set('REQUEST_URI', 'http://test.com/foo#bar');
286 $this->assertEquals('http://test.com/foo', $request->getUri());
287 }
288
289 /**
290 * @dataProvider getRequestUriData
291 */
292 public function testGetRequestUri($serverRequestUri, $expected, $message)
293 {
294 $request = new Request();
295 $request->server->add([
296 'REQUEST_URI' => $serverRequestUri,
297
298 // For having http://test.com
299 'SERVER_NAME' => 'test.com',
300 'SERVER_PORT' => 80,
301 ]);
302
303 $this->assertSame($expected, $request->getRequestUri(), $message);
304 $this->assertSame($expected, $request->server->get('REQUEST_URI'), 'Normalize the request URI.');
305 }
306
307 public function getRequestUriData()
308 {
309 $message = 'Do not modify the path.';
310 yield ['/foo', '/foo', $message];
311 yield ['//bar/foo', '//bar/foo', $message];
312 yield ['///bar/foo', '///bar/foo', $message];
313
314 $message = 'Handle when the scheme, host are on REQUEST_URI.';
315 yield ['http://test.com/foo?bar=baz', '/foo?bar=baz', $message];
316
317 $message = 'Handle when the scheme, host and port are on REQUEST_URI.';
318 yield ['http://test.com:80/foo', '/foo', $message];
319 yield ['https://test.com:8080/foo', '/foo', $message];
320 yield ['https://test.com:443/foo', '/foo', $message];
321
322 $message = 'Fragment should not be included in the URI';
323 yield ['http://test.com/foo#bar', '/foo', $message];
324 yield ['/foo#bar', '/foo', $message];
325 }
326
327 public function testGetRequestUriWithoutRequiredHeader()
328 {
329 $expected = '';
330
331 $request = new Request();
332
333 $message = 'Fallback to empty URI when headers are missing.';
334 $this->assertSame($expected, $request->getRequestUri(), $message);
335 $this->assertSame($expected, $request->server->get('REQUEST_URI'), 'Normalize the request URI.');
336 }
337
338 public function testCreateCheckPrecedence()
339 {
340 // server is used by default
341 $request = Request::create('/', 'DELETE', [], [], [], [
342 'HTTP_HOST' => 'example.com',
343 'HTTPS' => 'on',
344 'SERVER_PORT' => 443,
345 'PHP_AUTH_USER' => 'fabien',
346 'PHP_AUTH_PW' => 'pa$$',
347 'QUERY_STRING' => 'foo=bar',
348 'CONTENT_TYPE' => 'application/json',
349 ]);
350 $this->assertEquals('example.com', $request->getHost());
351 $this->assertEquals(443, $request->getPort());
352 $this->assertTrue($request->isSecure());
353 $this->assertEquals('fabien', $request->getUser());
354 $this->assertEquals('pa$$', $request->getPassword());
355 $this->assertEquals('', $request->getQueryString());
356 $this->assertEquals('application/json', $request->headers->get('CONTENT_TYPE'));
357
358 // URI has precedence over server
359 $request = Request::create('http://thomas:pokemon@example.net:8080/?foo=bar', 'GET', [], [], [], [
360 'HTTP_HOST' => 'example.com',
361 'HTTPS' => 'on',
362 'SERVER_PORT' => 443,
363 ]);
364 $this->assertEquals('example.net', $request->getHost());
365 $this->assertEquals(8080, $request->getPort());
366 $this->assertFalse($request->isSecure());
367 $this->assertEquals('thomas', $request->getUser());
368 $this->assertEquals('pokemon', $request->getPassword());
369 $this->assertEquals('foo=bar', $request->getQueryString());
370 }
371
372 public function testDuplicate()
373 {
374 $request = new Request(['foo' => 'bar'], ['foo' => 'bar'], ['foo' => 'bar'], [], [], ['HTTP_FOO' => 'bar']);
375 $dup = $request->duplicate();
376
377 $this->assertEquals($request->query->all(), $dup->query->all(), '->duplicate() duplicates a request an copy the current query parameters');
378 $this->assertEquals($request->request->all(), $dup->request->all(), '->duplicate() duplicates a request an copy the current request parameters');
379 $this->assertEquals($request->attributes->all(), $dup->attributes->all(), '->duplicate() duplicates a request an copy the current attributes');
380 $this->assertEquals($request->headers->all(), $dup->headers->all(), '->duplicate() duplicates a request an copy the current HTTP headers');
381
382 $dup = $request->duplicate(['foo' => 'foobar'], ['foo' => 'foobar'], ['foo' => 'foobar'], [], [], ['HTTP_FOO' => 'foobar']);
383
384 $this->assertEquals(['foo' => 'foobar'], $dup->query->all(), '->duplicate() overrides the query parameters if provided');
385 $this->assertEquals(['foo' => 'foobar'], $dup->request->all(), '->duplicate() overrides the request parameters if provided');
386 $this->assertEquals(['foo' => 'foobar'], $dup->attributes->all(), '->duplicate() overrides the attributes if provided');
387 $this->assertEquals(['foo' => ['foobar']], $dup->headers->all(), '->duplicate() overrides the HTTP header if provided');
388 }
389
390 public function testDuplicateWithFormat()
391 {
392 $request = new Request([], [], ['_format' => 'json']);
393 $dup = $request->duplicate();
394
395 $this->assertEquals('json', $dup->getRequestFormat());
396 $this->assertEquals('json', $dup->attributes->get('_format'));
397
398 $request = new Request();
399 $request->setRequestFormat('xml');
400 $dup = $request->duplicate();
401
402 $this->assertEquals('xml', $dup->getRequestFormat());
403 }
404
405 /**
406 * @dataProvider getFormatToMimeTypeMapProviderWithAdditionalNullFormat
407 */
408 public function testGetFormatFromMimeType($format, $mimeTypes)
409 {
410 $request = new Request();
411 foreach ($mimeTypes as $mime) {
412 $this->assertEquals($format, $request->getFormat($mime));
413 }
414 $request->setFormat($format, $mimeTypes);
415 foreach ($mimeTypes as $mime) {
416 $this->assertEquals($format, $request->getFormat($mime));
417
418 if (null !== $format) {
419 $this->assertEquals($mimeTypes[0], $request->getMimeType($format));
420 }
421 }
422 }
423
424 public function getFormatToMimeTypeMapProviderWithAdditionalNullFormat()
425 {
426 return array_merge(
427 [[null, [null, 'unexistent-mime-type']]],
428 $this->getFormatToMimeTypeMapProvider()
429 );
430 }
431
432 public function testGetFormatFromMimeTypeWithParameters()
433 {
434 $request = new Request();
435 $this->assertEquals('json', $request->getFormat('application/json; charset=utf-8'));
436 $this->assertEquals('json', $request->getFormat('application/json;charset=utf-8'));
437 $this->assertEquals('json', $request->getFormat('application/json ; charset=utf-8'));
438 $this->assertEquals('json', $request->getFormat('application/json ;charset=utf-8'));
439 }
440
441 /**
442 * @dataProvider getFormatToMimeTypeMapProvider
443 */
444 public function testGetMimeTypeFromFormat($format, $mimeTypes)
445 {
446 $request = new Request();
447 $this->assertEquals($mimeTypes[0], $request->getMimeType($format));
448 }
449
450 /**
451 * @dataProvider getFormatToMimeTypeMapProvider
452 */
453 public function testGetMimeTypesFromFormat($format, $mimeTypes)
454 {
455 $this->assertEquals($mimeTypes, Request::getMimeTypes($format));
456 }
457
458 public function testGetMimeTypesFromInexistentFormat()
459 {
460 $request = new Request();
461 $this->assertNull($request->getMimeType('foo'));
462 $this->assertEquals([], Request::getMimeTypes('foo'));
463 }
464
465 public function testGetFormatWithCustomMimeType()
466 {
467 $request = new Request();
468 $request->setFormat('custom', 'application/vnd.foo.api;myversion=2.3');
469 $this->assertEquals('custom', $request->getFormat('application/vnd.foo.api;myversion=2.3'));
470 }
471
472 public function getFormatToMimeTypeMapProvider()
473 {
474 return [
475 ['txt', ['text/plain']],
476 ['js', ['application/javascript', 'application/x-javascript', 'text/javascript']],
477 ['css', ['text/css']],
478 ['json', ['application/json', 'application/x-json']],
479 ['jsonld', ['application/ld+json']],
480 ['xml', ['text/xml', 'application/xml', 'application/x-xml']],
481 ['rdf', ['application/rdf+xml']],
482 ['atom', ['application/atom+xml']],
483 ];
484 }
485
486 public function testGetUri()
487 {
488 $server = [];
489
490 // Standard Request on non default PORT
491 // http://host:8080/index.php/path/info?query=string
492
493 $server['HTTP_HOST'] = 'host:8080';
494 $server['SERVER_NAME'] = 'servername';
495 $server['SERVER_PORT'] = '8080';
496
497 $server['QUERY_STRING'] = 'query=string';
498 $server['REQUEST_URI'] = '/index.php/path/info?query=string';
499 $server['SCRIPT_NAME'] = '/index.php';
500 $server['PATH_INFO'] = '/path/info';
501 $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
502 $server['PHP_SELF'] = '/index_dev.php/path/info';
503 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
504
505 $request = new Request();
506
507 $request->initialize([], [], [], [], [], $server);
508
509 $this->assertEquals('http://host:8080/index.php/path/info?query=string', $request->getUri(), '->getUri() with non default port');
510
511 // Use std port number
512 $server['HTTP_HOST'] = 'host';
513 $server['SERVER_NAME'] = 'servername';
514 $server['SERVER_PORT'] = '80';
515
516 $request->initialize([], [], [], [], [], $server);
517
518 $this->assertEquals('http://host/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port');
519
520 // Without HOST HEADER
521 unset($server['HTTP_HOST']);
522 $server['SERVER_NAME'] = 'servername';
523 $server['SERVER_PORT'] = '80';
524
525 $request->initialize([], [], [], [], [], $server);
526
527 $this->assertEquals('http://servername/index.php/path/info?query=string', $request->getUri(), '->getUri() with default port without HOST_HEADER');
528
529 // Request with URL REWRITING (hide index.php)
530 // RewriteCond %{REQUEST_FILENAME} !-f
531 // RewriteRule ^(.*)$ index.php [QSA,L]
532 // http://host:8080/path/info?query=string
533 $server = [];
534 $server['HTTP_HOST'] = 'host:8080';
535 $server['SERVER_NAME'] = 'servername';
536 $server['SERVER_PORT'] = '8080';
537
538 $server['REDIRECT_QUERY_STRING'] = 'query=string';
539 $server['REDIRECT_URL'] = '/path/info';
540 $server['SCRIPT_NAME'] = '/index.php';
541 $server['QUERY_STRING'] = 'query=string';
542 $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
543 $server['SCRIPT_NAME'] = '/index.php';
544 $server['PHP_SELF'] = '/index.php';
545 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
546
547 $request->initialize([], [], [], [], [], $server);
548 $this->assertEquals('http://host:8080/path/info?query=string', $request->getUri(), '->getUri() with rewrite');
549
550 // Use std port number
551 // http://host/path/info?query=string
552 $server['HTTP_HOST'] = 'host';
553 $server['SERVER_NAME'] = 'servername';
554 $server['SERVER_PORT'] = '80';
555
556 $request->initialize([], [], [], [], [], $server);
557
558 $this->assertEquals('http://host/path/info?query=string', $request->getUri(), '->getUri() with rewrite and default port');
559
560 // Without HOST HEADER
561 unset($server['HTTP_HOST']);
562 $server['SERVER_NAME'] = 'servername';
563 $server['SERVER_PORT'] = '80';
564
565 $request->initialize([], [], [], [], [], $server);
566
567 $this->assertEquals('http://servername/path/info?query=string', $request->getUri(), '->getUri() with rewrite, default port without HOST_HEADER');
568
569 // With encoded characters
570
571 $server = [
572 'HTTP_HOST' => 'host:8080',
573 'SERVER_NAME' => 'servername',
574 'SERVER_PORT' => '8080',
575 'QUERY_STRING' => 'query=string',
576 'REQUEST_URI' => '/ba%20se/index_dev.php/foo%20bar/in+fo?query=string',
577 'SCRIPT_NAME' => '/ba se/index_dev.php',
578 'PATH_TRANSLATED' => 'redirect:/index.php/foo bar/in+fo',
579 'PHP_SELF' => '/ba se/index_dev.php/path/info',
580 'SCRIPT_FILENAME' => '/some/where/ba se/index_dev.php',
581 ];
582
583 $request->initialize([], [], [], [], [], $server);
584
585 $this->assertEquals(
586 'http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string',
587 $request->getUri()
588 );
589
590 // with user info
591
592 $server['PHP_AUTH_USER'] = 'fabien';
593 $request->initialize([], [], [], [], [], $server);
594 $this->assertEquals('http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri());
595
596 $server['PHP_AUTH_PW'] = 'symfony';
597 $request->initialize([], [], [], [], [], $server);
598 $this->assertEquals('http://host:8080/ba%20se/index_dev.php/foo%20bar/in+fo?query=string', $request->getUri());
599 }
600
601 public function testGetUriForPath()
602 {
603 $request = Request::create('http://test.com/foo?bar=baz');
604 $this->assertEquals('http://test.com/some/path', $request->getUriForPath('/some/path'));
605
606 $request = Request::create('http://test.com:90/foo?bar=baz');
607 $this->assertEquals('http://test.com:90/some/path', $request->getUriForPath('/some/path'));
608
609 $request = Request::create('https://test.com/foo?bar=baz');
610 $this->assertEquals('https://test.com/some/path', $request->getUriForPath('/some/path'));
611
612 $request = Request::create('https://test.com:90/foo?bar=baz');
613 $this->assertEquals('https://test.com:90/some/path', $request->getUriForPath('/some/path'));
614
615 $server = [];
616
617 // Standard Request on non default PORT
618 // http://host:8080/index.php/path/info?query=string
619
620 $server['HTTP_HOST'] = 'host:8080';
621 $server['SERVER_NAME'] = 'servername';
622 $server['SERVER_PORT'] = '8080';
623
624 $server['QUERY_STRING'] = 'query=string';
625 $server['REQUEST_URI'] = '/index.php/path/info?query=string';
626 $server['SCRIPT_NAME'] = '/index.php';
627 $server['PATH_INFO'] = '/path/info';
628 $server['PATH_TRANSLATED'] = 'redirect:/index.php/path/info';
629 $server['PHP_SELF'] = '/index_dev.php/path/info';
630 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
631
632 $request = new Request();
633
634 $request->initialize([], [], [], [], [], $server);
635
636 $this->assertEquals('http://host:8080/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with non default port');
637
638 // Use std port number
639 $server['HTTP_HOST'] = 'host';
640 $server['SERVER_NAME'] = 'servername';
641 $server['SERVER_PORT'] = '80';
642
643 $request->initialize([], [], [], [], [], $server);
644
645 $this->assertEquals('http://host/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port');
646
647 // Without HOST HEADER
648 unset($server['HTTP_HOST']);
649 $server['SERVER_NAME'] = 'servername';
650 $server['SERVER_PORT'] = '80';
651
652 $request->initialize([], [], [], [], [], $server);
653
654 $this->assertEquals('http://servername/index.php/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with default port without HOST_HEADER');
655
656 // Request with URL REWRITING (hide index.php)
657 // RewriteCond %{REQUEST_FILENAME} !-f
658 // RewriteRule ^(.*)$ index.php [QSA,L]
659 // http://host:8080/path/info?query=string
660 $server = [];
661 $server['HTTP_HOST'] = 'host:8080';
662 $server['SERVER_NAME'] = 'servername';
663 $server['SERVER_PORT'] = '8080';
664
665 $server['REDIRECT_QUERY_STRING'] = 'query=string';
666 $server['REDIRECT_URL'] = '/path/info';
667 $server['SCRIPT_NAME'] = '/index.php';
668 $server['QUERY_STRING'] = 'query=string';
669 $server['REQUEST_URI'] = '/path/info?toto=test&1=1';
670 $server['SCRIPT_NAME'] = '/index.php';
671 $server['PHP_SELF'] = '/index.php';
672 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
673
674 $request->initialize([], [], [], [], [], $server);
675 $this->assertEquals('http://host:8080/some/path', $request->getUriForPath('/some/path'), '->getUri() with rewrite');
676
677 // Use std port number
678 // http://host/path/info?query=string
679 $server['HTTP_HOST'] = 'host';
680 $server['SERVER_NAME'] = 'servername';
681 $server['SERVER_PORT'] = '80';
682
683 $request->initialize([], [], [], [], [], $server);
684
685 $this->assertEquals('http://host/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite and default port');
686
687 // Without HOST HEADER
688 unset($server['HTTP_HOST']);
689 $server['SERVER_NAME'] = 'servername';
690 $server['SERVER_PORT'] = '80';
691
692 $request->initialize([], [], [], [], [], $server);
693
694 $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'), '->getUriForPath() with rewrite, default port without HOST_HEADER');
695 $this->assertEquals('servername', $request->getHttpHost());
696
697 // with user info
698
699 $server['PHP_AUTH_USER'] = 'fabien';
700 $request->initialize([], [], [], [], [], $server);
701 $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'));
702
703 $server['PHP_AUTH_PW'] = 'symfony';
704 $request->initialize([], [], [], [], [], $server);
705 $this->assertEquals('http://servername/some/path', $request->getUriForPath('/some/path'));
706 }
707
708 /**
709 * @dataProvider getRelativeUriForPathData()
710 */
711 public function testGetRelativeUriForPath($expected, $pathinfo, $path)
712 {
713 $this->assertEquals($expected, Request::create($pathinfo)->getRelativeUriForPath($path));
714 }
715
716 public function getRelativeUriForPathData()
717 {
718 return [
719 ['me.png', '/foo', '/me.png'],
720 ['../me.png', '/foo/bar', '/me.png'],
721 ['me.png', '/foo/bar', '/foo/me.png'],
722 ['../baz/me.png', '/foo/bar/b', '/foo/baz/me.png'],
723 ['../../fooz/baz/me.png', '/foo/bar/b', '/fooz/baz/me.png'],
724 ['baz/me.png', '/foo/bar/b', 'baz/me.png'],
725 ];
726 }
727
728 public function testGetUserInfo()
729 {
730 $request = new Request();
731
732 $server = ['PHP_AUTH_USER' => 'fabien'];
733 $request->initialize([], [], [], [], [], $server);
734 $this->assertEquals('fabien', $request->getUserInfo());
735
736 $server['PHP_AUTH_USER'] = '0';
737 $request->initialize([], [], [], [], [], $server);
738 $this->assertEquals('0', $request->getUserInfo());
739
740 $server['PHP_AUTH_PW'] = '0';
741 $request->initialize([], [], [], [], [], $server);
742 $this->assertEquals('0:0', $request->getUserInfo());
743 }
744
745 public function testGetSchemeAndHttpHost()
746 {
747 $request = new Request();
748
749 $server = [];
750 $server['SERVER_NAME'] = 'servername';
751 $server['SERVER_PORT'] = '90';
752 $request->initialize([], [], [], [], [], $server);
753 $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
754
755 $server['PHP_AUTH_USER'] = 'fabien';
756 $request->initialize([], [], [], [], [], $server);
757 $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
758
759 $server['PHP_AUTH_USER'] = '0';
760 $request->initialize([], [], [], [], [], $server);
761 $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
762
763 $server['PHP_AUTH_PW'] = '0';
764 $request->initialize([], [], [], [], [], $server);
765 $this->assertEquals('http://servername:90', $request->getSchemeAndHttpHost());
766 }
767
768 /**
769 * @dataProvider getQueryStringNormalizationData
770 */
771 public function testGetQueryString($query, $expectedQuery, $msg)
772 {
773 $request = new Request();
774
775 $request->server->set('QUERY_STRING', $query);
776 $this->assertSame($expectedQuery, $request->getQueryString(), $msg);
777 }
778
779 public function getQueryStringNormalizationData()
780 {
781 return [
782 ['foo', 'foo', 'works with valueless parameters'],
783 ['foo=', 'foo=', 'includes a dangling equal sign'],
784 ['bar=&foo=bar', 'bar=&foo=bar', '->works with empty parameters'],
785 ['foo=bar&bar=', 'bar=&foo=bar', 'sorts keys alphabetically'],
786
787 // GET parameters, that are submitted from a HTML form, encode spaces as "+" by default (as defined in enctype application/x-www-form-urlencoded).
788 // PHP also converts "+" to spaces when filling the global _GET or when using the function parse_str.
789 ['baz=Foo%20Baz&bar=Foo+Bar', 'bar=Foo%20Bar&baz=Foo%20Baz', 'normalizes spaces in both encodings "%20" and "+"'],
790
791 ['foo[]=1&foo[]=2', 'foo%5B%5D=1&foo%5B%5D=2', 'allows array notation'],
792 ['foo=1&foo=2', 'foo=1&foo=2', 'allows repeated parameters'],
793 ['pa%3Dram=foo%26bar%3Dbaz&test=test', 'pa%3Dram=foo%26bar%3Dbaz&test=test', 'works with encoded delimiters'],
794 ['0', '0', 'allows "0"'],
795 ['Foo Bar&Foo%20Baz', 'Foo%20Bar&Foo%20Baz', 'normalizes encoding in keys'],
796 ['bar=Foo Bar&baz=Foo%20Baz', 'bar=Foo%20Bar&baz=Foo%20Baz', 'normalizes encoding in values'],
797 ['foo=bar&&&test&&', 'foo=bar&test', 'removes unneeded delimiters'],
798 ['formula=e=m*c^2', 'formula=e%3Dm%2Ac%5E2', 'correctly treats only the first "=" as delimiter and the next as value'],
799
800 // Ignore pairs with empty key, even if there was a value, e.g. "=value", as such nameless values cannot be retrieved anyway.
801 // PHP also does not include them when building _GET.
802 ['foo=bar&=a=b&=x=y', 'foo=bar', 'removes params with empty key'],
803 ];
804 }
805
806 public function testGetQueryStringReturnsNull()
807 {
808 $request = new Request();
809
810 $this->assertNull($request->getQueryString(), '->getQueryString() returns null for non-existent query string');
811
812 $request->server->set('QUERY_STRING', '');
813 $this->assertNull($request->getQueryString(), '->getQueryString() returns null for empty query string');
814 }
815
816 public function testGetHost()
817 {
818 $request = new Request();
819
820 $request->initialize(['foo' => 'bar']);
821 $this->assertEquals('', $request->getHost(), '->getHost() return empty string if not initialized');
822
823 $request->initialize([], [], [], [], [], ['HTTP_HOST' => 'www.example.com']);
824 $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from Host Header');
825
826 // Host header with port number
827 $request->initialize([], [], [], [], [], ['HTTP_HOST' => 'www.example.com:8080']);
828 $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from Host Header with port number');
829
830 // Server values
831 $request->initialize([], [], [], [], [], ['SERVER_NAME' => 'www.example.com']);
832 $this->assertEquals('www.example.com', $request->getHost(), '->getHost() from server name');
833
834 $request->initialize([], [], [], [], [], ['SERVER_NAME' => 'www.example.com', 'HTTP_HOST' => 'www.host.com']);
835 $this->assertEquals('www.host.com', $request->getHost(), '->getHost() value from Host header has priority over SERVER_NAME ');
836 }
837
838 public function testGetPort()
839 {
840 $request = Request::create('http://example.com', 'GET', [], [], [], [
841 'HTTP_X_FORWARDED_PROTO' => 'https',
842 'HTTP_X_FORWARDED_PORT' => '443',
843 ]);
844 $port = $request->getPort();
845
846 $this->assertEquals(80, $port, 'Without trusted proxies FORWARDED_PROTO and FORWARDED_PORT are ignored.');
847
848 Request::setTrustedProxies(['1.1.1.1'], Request::HEADER_X_FORWARDED_ALL);
849 $request = Request::create('http://example.com', 'GET', [], [], [], [
850 'HTTP_X_FORWARDED_PROTO' => 'https',
851 'HTTP_X_FORWARDED_PORT' => '8443',
852 ]);
853 $this->assertEquals(80, $request->getPort(), 'With PROTO and PORT on untrusted connection server value takes precedence.');
854 $request->server->set('REMOTE_ADDR', '1.1.1.1');
855 $this->assertEquals(8443, $request->getPort(), 'With PROTO and PORT set PORT takes precedence.');
856
857 $request = Request::create('http://example.com', 'GET', [], [], [], [
858 'HTTP_X_FORWARDED_PROTO' => 'https',
859 ]);
860 $this->assertEquals(80, $request->getPort(), 'With only PROTO set getPort() ignores trusted headers on untrusted connection.');
861 $request->server->set('REMOTE_ADDR', '1.1.1.1');
862 $this->assertEquals(443, $request->getPort(), 'With only PROTO set getPort() defaults to 443.');
863
864 $request = Request::create('http://example.com', 'GET', [], [], [], [
865 'HTTP_X_FORWARDED_PROTO' => 'http',
866 ]);
867 $this->assertEquals(80, $request->getPort(), 'If X_FORWARDED_PROTO is set to HTTP getPort() ignores trusted headers on untrusted connection.');
868 $request->server->set('REMOTE_ADDR', '1.1.1.1');
869 $this->assertEquals(80, $request->getPort(), 'If X_FORWARDED_PROTO is set to HTTP getPort() returns port of the original request.');
870
871 $request = Request::create('http://example.com', 'GET', [], [], [], [
872 'HTTP_X_FORWARDED_PROTO' => 'On',
873 ]);
874 $this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is On, getPort() ignores trusted headers on untrusted connection.');
875 $request->server->set('REMOTE_ADDR', '1.1.1.1');
876 $this->assertEquals(443, $request->getPort(), 'With only PROTO set and value is On, getPort() defaults to 443.');
877
878 $request = Request::create('http://example.com', 'GET', [], [], [], [
879 'HTTP_X_FORWARDED_PROTO' => '1',
880 ]);
881 $this->assertEquals(80, $request->getPort(), 'With only PROTO set and value is 1, getPort() ignores trusted headers on untrusted connection.');
882 $request->server->set('REMOTE_ADDR', '1.1.1.1');
883 $this->assertEquals(443, $request->getPort(), 'With only PROTO set and value is 1, getPort() defaults to 443.');
884
885 $request = Request::create('http://example.com', 'GET', [], [], [], [
886 'HTTP_X_FORWARDED_PROTO' => 'something-else',
887 ]);
888 $port = $request->getPort();
889 $this->assertEquals(80, $port, 'With only PROTO set and value is not recognized, getPort() defaults to 80.');
890 }
891
892 public function testGetHostWithFakeHttpHostValue()
893 {
894 $this->expectException('RuntimeException');
895 $request = new Request();
896 $request->initialize([], [], [], [], [], ['HTTP_HOST' => 'www.host.com?query=string']);
897 $request->getHost();
898 }
899
900 public function testGetSetMethod()
901 {
902 $request = new Request();
903
904 $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns GET if no method is defined');
905
906 $request->setMethod('get');
907 $this->assertEquals('GET', $request->getMethod(), '->getMethod() returns an uppercased string');
908
909 $request->setMethod('PURGE');
910 $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method even if it is not a standard one');
911
912 $request->setMethod('POST');
913 $this->assertEquals('POST', $request->getMethod(), '->getMethod() returns the method POST if no _method is defined');
914
915 $request->setMethod('POST');
916 $request->request->set('_method', 'purge');
917 $this->assertEquals('POST', $request->getMethod(), '->getMethod() does not return the method from _method if defined and POST but support not enabled');
918
919 $request = new Request();
920 $request->setMethod('POST');
921 $request->request->set('_method', 'purge');
922
923 $this->assertFalse(Request::getHttpMethodParameterOverride(), 'httpMethodParameterOverride should be disabled by default');
924
925 Request::enableHttpMethodParameterOverride();
926
927 $this->assertTrue(Request::getHttpMethodParameterOverride(), 'httpMethodParameterOverride should be enabled now but it is not');
928
929 $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method from _method if defined and POST');
930 $this->disableHttpMethodParameterOverride();
931
932 $request = new Request();
933 $request->setMethod('POST');
934 $request->query->set('_method', 'purge');
935 $this->assertEquals('POST', $request->getMethod(), '->getMethod() does not return the method from _method if defined and POST but support not enabled');
936
937 $request = new Request();
938 $request->setMethod('POST');
939 $request->query->set('_method', 'purge');
940 Request::enableHttpMethodParameterOverride();
941 $this->assertEquals('PURGE', $request->getMethod(), '->getMethod() returns the method from _method if defined and POST');
942 $this->disableHttpMethodParameterOverride();
943
944 $request = new Request();
945 $request->setMethod('POST');
946 $request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete');
947 $this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override even though _method is set if defined and POST');
948
949 $request = new Request();
950 $request->setMethod('POST');
951 $request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete');
952 $this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override if defined and POST');
953
954 $request = new Request();
955 $request->setMethod('POST');
956 $request->query->set('_method', ['delete', 'patch']);
957 $this->assertSame('POST', $request->getMethod(), '->getMethod() returns the request method if invalid type is defined in query');
958 }
959
960 /**
961 * @dataProvider getClientIpsProvider
962 */
963 public function testGetClientIp($expected, $remoteAddr, $httpForwardedFor, $trustedProxies)
964 {
965 $request = $this->getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies);
966
967 $this->assertEquals($expected[0], $request->getClientIp());
968 }
969
970 /**
971 * @dataProvider getClientIpsProvider
972 */
973 public function testGetClientIps($expected, $remoteAddr, $httpForwardedFor, $trustedProxies)
974 {
975 $request = $this->getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies);
976
977 $this->assertEquals($expected, $request->getClientIps());
978 }
979
980 /**
981 * @dataProvider getClientIpsForwardedProvider
982 */
983 public function testGetClientIpsForwarded($expected, $remoteAddr, $httpForwarded, $trustedProxies)
984 {
985 $request = $this->getRequestInstanceForClientIpsForwardedTests($remoteAddr, $httpForwarded, $trustedProxies);
986
987 $this->assertEquals($expected, $request->getClientIps());
988 }
989
990 public function getClientIpsForwardedProvider()
991 {
992 // $expected $remoteAddr $httpForwarded $trustedProxies
993 return [
994 [['127.0.0.1'], '127.0.0.1', 'for="_gazonk"', null],
995 [['127.0.0.1'], '127.0.0.1', 'for="_gazonk"', ['127.0.0.1']],
996 [['88.88.88.88'], '127.0.0.1', 'for="88.88.88.88:80"', ['127.0.0.1']],
997 [['192.0.2.60'], '::1', 'for=192.0.2.60;proto=http;by=203.0.113.43', ['::1']],
998 [['2620:0:1cfe:face:b00c::3', '192.0.2.43'], '::1', 'for=192.0.2.43, for=2620:0:1cfe:face:b00c::3', ['::1']],
999 [['2001:db8:cafe::17'], '::1', 'for="[2001:db8:cafe::17]:4711', ['::1']],
1000 ];
1001 }
1002
1003 public function getClientIpsProvider()
1004 {
1005 // $expected $remoteAddr $httpForwardedFor $trustedProxies
1006 return [
1007 // simple IPv4
1008 [['88.88.88.88'], '88.88.88.88', null, null],
1009 // trust the IPv4 remote addr
1010 [['88.88.88.88'], '88.88.88.88', null, ['88.88.88.88']],
1011
1012 // simple IPv6
1013 [['::1'], '::1', null, null],
1014 // trust the IPv6 remote addr
1015 [['::1'], '::1', null, ['::1']],
1016
1017 // forwarded for with remote IPv4 addr not trusted
1018 [['127.0.0.1'], '127.0.0.1', '88.88.88.88', null],
1019 // forwarded for with remote IPv4 addr trusted + comma
1020 [['88.88.88.88'], '127.0.0.1', '88.88.88.88,', ['127.0.0.1']],
1021 // forwarded for with remote IPv4 and all FF addrs trusted
1022 [['88.88.88.88'], '127.0.0.1', '88.88.88.88', ['127.0.0.1', '88.88.88.88']],
1023 // forwarded for with remote IPv4 range trusted
1024 [['88.88.88.88'], '123.45.67.89', '88.88.88.88', ['123.45.67.0/24']],
1025
1026 // forwarded for with remote IPv6 addr not trusted
1027 [['1620:0:1cfe:face:b00c::3'], '1620:0:1cfe:face:b00c::3', '2620:0:1cfe:face:b00c::3', null],
1028 // forwarded for with remote IPv6 addr trusted
1029 [['2620:0:1cfe:face:b00c::3'], '1620:0:1cfe:face:b00c::3', '2620:0:1cfe:face:b00c::3', ['1620:0:1cfe:face:b00c::3']],
1030 // forwarded for with remote IPv6 range trusted
1031 [['88.88.88.88'], '2a01:198:603:0:396e:4789:8e99:890f', '88.88.88.88', ['2a01:198:603:0::/65']],
1032
1033 // multiple forwarded for with remote IPv4 addr trusted
1034 [['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', ['123.45.67.89']],
1035 // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted
1036 [['87.65.43.21', '127.0.0.1'], '123.45.67.89', '127.0.0.1, 87.65.43.21, 88.88.88.88', ['123.45.67.89', '88.88.88.88']],
1037 // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted but in the middle
1038 [['88.88.88.88', '127.0.0.1'], '123.45.67.89', '127.0.0.1, 87.65.43.21, 88.88.88.88', ['123.45.67.89', '87.65.43.21']],
1039 // multiple forwarded for with remote IPv4 addr and all reverse proxies trusted
1040 [['127.0.0.1'], '123.45.67.89', '127.0.0.1, 87.65.43.21, 88.88.88.88', ['123.45.67.89', '87.65.43.21', '88.88.88.88', '127.0.0.1']],
1041
1042 // multiple forwarded for with remote IPv6 addr trusted
1043 [['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', ['1620:0:1cfe:face:b00c::3']],
1044 // multiple forwarded for with remote IPv6 addr and some reverse proxies trusted
1045 [['3620:0:1cfe:face:b00c::3'], '1620:0:1cfe:face:b00c::3', '3620:0:1cfe:face:b00c::3,2620:0:1cfe:face:b00c::3', ['1620:0:1cfe:face:b00c::3', '2620:0:1cfe:face:b00c::3']],
1046 // multiple forwarded for with remote IPv4 addr and some reverse proxies trusted but in the middle
1047 [['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', ['1620:0:1cfe:face:b00c::3', '3620:0:1cfe:face:b00c::3']],
1048
1049 // client IP with port
1050 [['88.88.88.88'], '127.0.0.1', '88.88.88.88:12345, 127.0.0.1', ['127.0.0.1']],
1051
1052 // invalid forwarded IP is ignored
1053 [['88.88.88.88'], '127.0.0.1', 'unknown,88.88.88.88', ['127.0.0.1']],
1054 [['88.88.88.88'], '127.0.0.1', '}__test|O:21:&quot;JDatabaseDriverMysqli&quot;:3:{s:2,88.88.88.88', ['127.0.0.1']],
1055 ];
1056 }
1057
1058 /**
1059 * @dataProvider getClientIpsWithConflictingHeadersProvider
1060 */
1061 public function testGetClientIpsWithConflictingHeaders($httpForwarded, $httpXForwardedFor)
1062 {
1063 $this->expectException('Give\Vendors\Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException');
1064 $request = new Request();
1065
1066 $server = [
1067 'REMOTE_ADDR' => '88.88.88.88',
1068 'HTTP_FORWARDED' => $httpForwarded,
1069 'HTTP_X_FORWARDED_FOR' => $httpXForwardedFor,
1070 ];
1071
1072 Request::setTrustedProxies(['88.88.88.88'], Request::HEADER_X_FORWARDED_ALL | Request::HEADER_FORWARDED);
1073
1074 $request->initialize([], [], [], [], [], $server);
1075
1076 $request->getClientIps();
1077 }
1078
1079 /**
1080 * @dataProvider getClientIpsWithConflictingHeadersProvider
1081 */
1082 public function testGetClientIpsOnlyXHttpForwardedForTrusted($httpForwarded, $httpXForwardedFor)
1083 {
1084 $request = new Request();
1085
1086 $server = [
1087 'REMOTE_ADDR' => '88.88.88.88',
1088 'HTTP_FORWARDED' => $httpForwarded,
1089 'HTTP_X_FORWARDED_FOR' => $httpXForwardedFor,
1090 ];
1091
1092 Request::setTrustedProxies(['88.88.88.88'], Request::HEADER_X_FORWARDED_FOR);
1093
1094 $request->initialize([], [], [], [], [], $server);
1095
1096 $this->assertSame(array_reverse(explode(',', $httpXForwardedFor)), $request->getClientIps());
1097 }
1098
1099 public function getClientIpsWithConflictingHeadersProvider()
1100 {
1101 // $httpForwarded $httpXForwardedFor
1102 return [
1103 ['for=87.65.43.21', '192.0.2.60'],
1104 ['for=87.65.43.21, for=192.0.2.60', '192.0.2.60'],
1105 ['for=192.0.2.60', '192.0.2.60,87.65.43.21'],
1106 ['for="::face", for=192.0.2.60', '192.0.2.60,192.0.2.43'],
1107 ['for=87.65.43.21, for=192.0.2.60', '192.0.2.60,87.65.43.21'],
1108 ];
1109 }
1110
1111 /**
1112 * @dataProvider getClientIpsWithAgreeingHeadersProvider
1113 */
1114 public function testGetClientIpsWithAgreeingHeaders($httpForwarded, $httpXForwardedFor, $expectedIps)
1115 {
1116 $request = new Request();
1117
1118 $server = [
1119 'REMOTE_ADDR' => '88.88.88.88',
1120 'HTTP_FORWARDED' => $httpForwarded,
1121 'HTTP_X_FORWARDED_FOR' => $httpXForwardedFor,
1122 ];
1123
1124 Request::setTrustedProxies(['88.88.88.88'], -1);
1125
1126 $request->initialize([], [], [], [], [], $server);
1127
1128 $clientIps = $request->getClientIps();
1129
1130 $this->assertSame($expectedIps, $clientIps);
1131 }
1132
1133 public function getClientIpsWithAgreeingHeadersProvider()
1134 {
1135 // $httpForwarded $httpXForwardedFor
1136 return [
1137 ['for="192.0.2.60"', '192.0.2.60', ['192.0.2.60']],
1138 ['for=192.0.2.60, for=87.65.43.21', '192.0.2.60,87.65.43.21', ['87.65.43.21', '192.0.2.60']],
1139 ['for="[::face]", for=192.0.2.60', '::face,192.0.2.60', ['192.0.2.60', '::face']],
1140 ['for="192.0.2.60:80"', '192.0.2.60', ['192.0.2.60']],
1141 ['for=192.0.2.60;proto=http;by=203.0.113.43', '192.0.2.60', ['192.0.2.60']],
1142 ['for="[2001:db8:cafe::17]:4711"', '2001:db8:cafe::17', ['2001:db8:cafe::17']],
1143 ];
1144 }
1145
1146 public function testGetContentWorksTwiceInDefaultMode()
1147 {
1148 $req = new Request();
1149 $this->assertEquals('', $req->getContent());
1150 $this->assertEquals('', $req->getContent());
1151 }
1152
1153 public function testGetContentReturnsResource()
1154 {
1155 $req = new Request();
1156 $retval = $req->getContent(true);
1157 $this->assertIsResource($retval);
1158 $this->assertEquals('', fread($retval, 1));
1159 $this->assertTrue(feof($retval));
1160 }
1161
1162 public function testGetContentReturnsResourceWhenContentSetInConstructor()
1163 {
1164 $req = new Request([], [], [], [], [], [], 'MyContent');
1165 $resource = $req->getContent(true);
1166
1167 $this->assertIsResource($resource);
1168 $this->assertEquals('MyContent', stream_get_contents($resource));
1169 }
1170
1171 public function testContentAsResource()
1172 {
1173 $resource = fopen('php://memory', 'r+');
1174 fwrite($resource, 'My other content');
1175 rewind($resource);
1176
1177 $req = new Request([], [], [], [], [], [], $resource);
1178 $this->assertEquals('My other content', stream_get_contents($req->getContent(true)));
1179 $this->assertEquals('My other content', $req->getContent());
1180 }
1181
1182 /**
1183 * @dataProvider getContentCantBeCalledTwiceWithResourcesProvider
1184 */
1185 public function testGetContentCantBeCalledTwiceWithResources($first, $second)
1186 {
1187 $this->expectException('LogicException');
1188 if (\PHP_VERSION_ID >= 50600) {
1189 $this->markTestSkipped('PHP >= 5.6 allows to open php://input several times.');
1190 }
1191
1192 $req = new Request();
1193 $req->getContent($first);
1194 $req->getContent($second);
1195 }
1196
1197 public function getContentCantBeCalledTwiceWithResourcesProvider()
1198 {
1199 return [
1200 'Resource then fetch' => [true, false],
1201 'Resource then resource' => [true, true],
1202 ];
1203 }
1204
1205 /**
1206 * @dataProvider getContentCanBeCalledTwiceWithResourcesProvider
1207 * @requires PHP 5.6
1208 */
1209 public function testGetContentCanBeCalledTwiceWithResources($first, $second)
1210 {
1211 $req = new Request();
1212 $a = $req->getContent($first);
1213 $b = $req->getContent($second);
1214
1215 if ($first) {
1216 $a = stream_get_contents($a);
1217 }
1218
1219 if ($second) {
1220 $b = stream_get_contents($b);
1221 }
1222
1223 $this->assertSame($a, $b);
1224 }
1225
1226 public function getContentCanBeCalledTwiceWithResourcesProvider()
1227 {
1228 return [
1229 'Fetch then fetch' => [false, false],
1230 'Fetch then resource' => [false, true],
1231 'Resource then fetch' => [true, false],
1232 'Resource then resource' => [true, true],
1233 ];
1234 }
1235
1236 public function provideOverloadedMethods()
1237 {
1238 return [
1239 ['PUT'],
1240 ['DELETE'],
1241 ['PATCH'],
1242 ['put'],
1243 ['delete'],
1244 ['patch'],
1245 ];
1246 }
1247
1248 /**
1249 * @dataProvider provideOverloadedMethods
1250 */
1251 public function testCreateFromGlobals($method)
1252 {
1253 $normalizedMethod = strtoupper($method);
1254
1255 $_GET['foo1'] = 'bar1';
1256 $_POST['foo2'] = 'bar2';
1257 $_COOKIE['foo3'] = 'bar3';
1258 $_FILES['foo4'] = ['bar4'];
1259 $_SERVER['foo5'] = 'bar5';
1260
1261 $request = Request::createFromGlobals();
1262 $this->assertEquals('bar1', $request->query->get('foo1'), '::fromGlobals() uses values from $_GET');
1263 $this->assertEquals('bar2', $request->request->get('foo2'), '::fromGlobals() uses values from $_POST');
1264 $this->assertEquals('bar3', $request->cookies->get('foo3'), '::fromGlobals() uses values from $_COOKIE');
1265 $this->assertEquals(['bar4'], $request->files->get('foo4'), '::fromGlobals() uses values from $_FILES');
1266 $this->assertEquals('bar5', $request->server->get('foo5'), '::fromGlobals() uses values from $_SERVER');
1267
1268 unset($_GET['foo1'], $_POST['foo2'], $_COOKIE['foo3'], $_FILES['foo4'], $_SERVER['foo5']);
1269
1270 $_SERVER['REQUEST_METHOD'] = $method;
1271 $_SERVER['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
1272 $request = RequestContentProxy::createFromGlobals();
1273 $this->assertEquals($normalizedMethod, $request->getMethod());
1274 $this->assertEquals('mycontent', $request->request->get('content'));
1275
1276 unset($_SERVER['REQUEST_METHOD'], $_SERVER['CONTENT_TYPE']);
1277
1278 Request::createFromGlobals();
1279 Request::enableHttpMethodParameterOverride();
1280 $_POST['_method'] = $method;
1281 $_POST['foo6'] = 'bar6';
1282 $_SERVER['REQUEST_METHOD'] = 'PoSt';
1283 $request = Request::createFromGlobals();
1284 $this->assertEquals($normalizedMethod, $request->getMethod());
1285 $this->assertEquals('POST', $request->getRealMethod());
1286 $this->assertEquals('bar6', $request->request->get('foo6'));
1287
1288 unset($_POST['_method'], $_POST['foo6'], $_SERVER['REQUEST_METHOD']);
1289 $this->disableHttpMethodParameterOverride();
1290 }
1291
1292 public function testOverrideGlobals()
1293 {
1294 $request = new Request();
1295 $request->initialize(['foo' => 'bar']);
1296
1297 // as the Request::overrideGlobals really work, it erase $_SERVER, so we must backup it
1298 $server = $_SERVER;
1299
1300 $request->overrideGlobals();
1301
1302 $this->assertEquals(['foo' => 'bar'], $_GET);
1303
1304 $request->initialize([], ['foo' => 'bar']);
1305 $request->overrideGlobals();
1306
1307 $this->assertEquals(['foo' => 'bar'], $_POST);
1308
1309 $this->assertArrayNotHasKey('HTTP_X_FORWARDED_PROTO', $_SERVER);
1310
1311 $request->headers->set('X_FORWARDED_PROTO', 'https');
1312
1313 Request::setTrustedProxies(['1.1.1.1'], Request::HEADER_X_FORWARDED_ALL);
1314 $this->assertFalse($request->isSecure());
1315 $request->server->set('REMOTE_ADDR', '1.1.1.1');
1316 $this->assertTrue($request->isSecure());
1317
1318 $request->overrideGlobals();
1319
1320 $this->assertArrayHasKey('HTTP_X_FORWARDED_PROTO', $_SERVER);
1321
1322 $request->headers->set('CONTENT_TYPE', 'multipart/form-data');
1323 $request->headers->set('CONTENT_LENGTH', 12345);
1324
1325 $request->overrideGlobals();
1326
1327 $this->assertArrayHasKey('CONTENT_TYPE', $_SERVER);
1328 $this->assertArrayHasKey('CONTENT_LENGTH', $_SERVER);
1329
1330 $request->initialize(['foo' => 'bar', 'baz' => 'foo']);
1331 $request->query->remove('baz');
1332
1333 $request->overrideGlobals();
1334
1335 $this->assertEquals(['foo' => 'bar'], $_GET);
1336 $this->assertEquals('foo=bar', $_SERVER['QUERY_STRING']);
1337 $this->assertEquals('foo=bar', $request->server->get('QUERY_STRING'));
1338
1339 // restore initial $_SERVER array
1340 $_SERVER = $server;
1341 }
1342
1343 public function testGetScriptName()
1344 {
1345 $request = new Request();
1346 $this->assertEquals('', $request->getScriptName());
1347
1348 $server = [];
1349 $server['SCRIPT_NAME'] = '/index.php';
1350
1351 $request->initialize([], [], [], [], [], $server);
1352
1353 $this->assertEquals('/index.php', $request->getScriptName());
1354
1355 $server = [];
1356 $server['ORIG_SCRIPT_NAME'] = '/frontend.php';
1357 $request->initialize([], [], [], [], [], $server);
1358
1359 $this->assertEquals('/frontend.php', $request->getScriptName());
1360
1361 $server = [];
1362 $server['SCRIPT_NAME'] = '/index.php';
1363 $server['ORIG_SCRIPT_NAME'] = '/frontend.php';
1364 $request->initialize([], [], [], [], [], $server);
1365
1366 $this->assertEquals('/index.php', $request->getScriptName());
1367 }
1368
1369 public function testGetBasePath()
1370 {
1371 $request = new Request();
1372 $this->assertEquals('', $request->getBasePath());
1373
1374 $server = [];
1375 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
1376 $request->initialize([], [], [], [], [], $server);
1377 $this->assertEquals('', $request->getBasePath());
1378
1379 $server = [];
1380 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
1381 $server['SCRIPT_NAME'] = '/index.php';
1382 $request->initialize([], [], [], [], [], $server);
1383
1384 $this->assertEquals('', $request->getBasePath());
1385
1386 $server = [];
1387 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
1388 $server['PHP_SELF'] = '/index.php';
1389 $request->initialize([], [], [], [], [], $server);
1390
1391 $this->assertEquals('', $request->getBasePath());
1392
1393 $server = [];
1394 $server['SCRIPT_FILENAME'] = '/some/where/index.php';
1395 $server['ORIG_SCRIPT_NAME'] = '/index.php';
1396 $request->initialize([], [], [], [], [], $server);
1397
1398 $this->assertEquals('', $request->getBasePath());
1399 }
1400
1401 public function testGetPathInfo()
1402 {
1403 $request = new Request();
1404 $this->assertEquals('/', $request->getPathInfo());
1405
1406 $server = [];
1407 $server['REQUEST_URI'] = '/path/info';
1408 $request->initialize([], [], [], [], [], $server);
1409
1410 $this->assertEquals('/path/info', $request->getPathInfo());
1411
1412 $server = [];
1413 $server['REQUEST_URI'] = '/path%20test/info';
1414 $request->initialize([], [], [], [], [], $server);
1415
1416 $this->assertEquals('/path%20test/info', $request->getPathInfo());
1417
1418 $server = [];
1419 $server['REQUEST_URI'] = '?a=b';
1420 $request->initialize([], [], [], [], [], $server);
1421
1422 $this->assertEquals('/', $request->getPathInfo());
1423 }
1424
1425 public function testGetParameterPrecedence()
1426 {
1427 $request = new Request();
1428 $request->attributes->set('foo', 'attr');
1429 $request->query->set('foo', 'query');
1430 $request->request->set('foo', 'body');
1431
1432 $this->assertSame('attr', $request->get('foo'));
1433
1434 $request->attributes->remove('foo');
1435 $this->assertSame('query', $request->get('foo'));
1436
1437 $request->query->remove('foo');
1438 $this->assertSame('body', $request->get('foo'));
1439
1440 $request->request->remove('foo');
1441 $this->assertNull($request->get('foo'));
1442 }
1443
1444 public function testGetPreferredLanguage()
1445 {
1446 $request = new Request();
1447 $this->assertNull($request->getPreferredLanguage());
1448 $this->assertNull($request->getPreferredLanguage([]));
1449 $this->assertEquals('fr', $request->getPreferredLanguage(['fr']));
1450 $this->assertEquals('fr', $request->getPreferredLanguage(['fr', 'en']));
1451 $this->assertEquals('en', $request->getPreferredLanguage(['en', 'fr']));
1452 $this->assertEquals('fr-ch', $request->getPreferredLanguage(['fr-ch', 'fr-fr']));
1453
1454 $request = new Request();
1455 $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
1456 $this->assertEquals('en', $request->getPreferredLanguage(['en', 'en-us']));
1457
1458 $request = new Request();
1459 $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
1460 $this->assertEquals('en', $request->getPreferredLanguage(['fr', 'en']));
1461
1462 $request = new Request();
1463 $request->headers->set('Accept-language', 'zh, en-us; q=0.8');
1464 $this->assertEquals('en', $request->getPreferredLanguage(['fr', 'en']));
1465
1466 $request = new Request();
1467 $request->headers->set('Accept-language', 'zh, en-us; q=0.8, fr-fr; q=0.6, fr; q=0.5');
1468 $this->assertEquals('en', $request->getPreferredLanguage(['fr', 'en']));
1469 }
1470
1471 public function testIsXmlHttpRequest()
1472 {
1473 $request = new Request();
1474 $this->assertFalse($request->isXmlHttpRequest());
1475
1476 $request->headers->set('X-Requested-With', 'XMLHttpRequest');
1477 $this->assertTrue($request->isXmlHttpRequest());
1478
1479 $request->headers->remove('X-Requested-With');
1480 $this->assertFalse($request->isXmlHttpRequest());
1481 }
1482
1483 /**
1484 * @requires extension intl
1485 */
1486 public function testIntlLocale()
1487 {
1488 $request = new Request();
1489
1490 $request->setDefaultLocale('fr');
1491 $this->assertEquals('fr', $request->getLocale());
1492 $this->assertEquals('fr', \Locale::getDefault());
1493
1494 $request->setLocale('en');
1495 $this->assertEquals('en', $request->getLocale());
1496 $this->assertEquals('en', \Locale::getDefault());
1497
1498 $request->setDefaultLocale('de');
1499 $this->assertEquals('en', $request->getLocale());
1500 $this->assertEquals('en', \Locale::getDefault());
1501 }
1502
1503 public function testGetCharsets()
1504 {
1505 $request = new Request();
1506 $this->assertEquals([], $request->getCharsets());
1507 $request->headers->set('Accept-Charset', 'ISO-8859-1, US-ASCII, UTF-8; q=0.8, ISO-10646-UCS-2; q=0.6');
1508 $this->assertEquals([], $request->getCharsets()); // testing caching
1509
1510 $request = new Request();
1511 $request->headers->set('Accept-Charset', 'ISO-8859-1, US-ASCII, UTF-8; q=0.8, ISO-10646-UCS-2; q=0.6');
1512 $this->assertEquals(['ISO-8859-1', 'US-ASCII', 'UTF-8', 'ISO-10646-UCS-2'], $request->getCharsets());
1513
1514 $request = new Request();
1515 $request->headers->set('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7');
1516 $this->assertEquals(['ISO-8859-1', 'utf-8', '*'], $request->getCharsets());
1517 }
1518
1519 public function testGetEncodings()
1520 {
1521 $request = new Request();
1522 $this->assertEquals([], $request->getEncodings());
1523 $request->headers->set('Accept-Encoding', 'gzip,deflate,sdch');
1524 $this->assertEquals([], $request->getEncodings()); // testing caching
1525
1526 $request = new Request();
1527 $request->headers->set('Accept-Encoding', 'gzip,deflate,sdch');
1528 $this->assertEquals(['gzip', 'deflate', 'sdch'], $request->getEncodings());
1529
1530 $request = new Request();
1531 $request->headers->set('Accept-Encoding', 'gzip;q=0.4,deflate;q=0.9,compress;q=0.7');
1532 $this->assertEquals(['deflate', 'compress', 'gzip'], $request->getEncodings());
1533 }
1534
1535 public function testGetAcceptableContentTypes()
1536 {
1537 $request = new Request();
1538 $this->assertEquals([], $request->getAcceptableContentTypes());
1539 $request->headers->set('Accept', 'application/vnd.wap.wmlscriptc, text/vnd.wap.wml, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html, multipart/mixed, */*');
1540 $this->assertEquals([], $request->getAcceptableContentTypes()); // testing caching
1541
1542 $request = new Request();
1543 $request->headers->set('Accept', 'application/vnd.wap.wmlscriptc, text/vnd.wap.wml, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html, multipart/mixed, */*');
1544 $this->assertEquals(['application/vnd.wap.wmlscriptc', 'text/vnd.wap.wml', 'application/vnd.wap.xhtml+xml', 'application/xhtml+xml', 'text/html', 'multipart/mixed', '*/*'], $request->getAcceptableContentTypes());
1545 }
1546
1547 public function testGetLanguages()
1548 {
1549 $request = new Request();
1550 $this->assertEquals([], $request->getLanguages());
1551
1552 $request = new Request();
1553 $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
1554 $this->assertEquals(['zh', 'en_US', 'en'], $request->getLanguages());
1555
1556 $request = new Request();
1557 $request->headers->set('Accept-language', 'zh, en-us; q=0.6, en; q=0.8');
1558 $this->assertEquals(['zh', 'en', 'en_US'], $request->getLanguages()); // Test out of order qvalues
1559
1560 $request = new Request();
1561 $request->headers->set('Accept-language', 'zh, en, en-us');
1562 $this->assertEquals(['zh', 'en', 'en_US'], $request->getLanguages()); // Test equal weighting without qvalues
1563
1564 $request = new Request();
1565 $request->headers->set('Accept-language', 'zh; q=0.6, en, en-us; q=0.6');
1566 $this->assertEquals(['en', 'zh', 'en_US'], $request->getLanguages()); // Test equal weighting with qvalues
1567
1568 $request = new Request();
1569 $request->headers->set('Accept-language', 'zh, i-cherokee; q=0.6');
1570 $this->assertEquals(['zh', 'cherokee'], $request->getLanguages());
1571 }
1572
1573 public function testGetRequestFormat()
1574 {
1575 $request = new Request();
1576 $this->assertEquals('html', $request->getRequestFormat());
1577
1578 // Ensure that setting different default values over time is possible,
1579 // aka. setRequestFormat determines the state.
1580 $this->assertEquals('json', $request->getRequestFormat('json'));
1581 $this->assertEquals('html', $request->getRequestFormat('html'));
1582
1583 $request = new Request();
1584 $this->assertNull($request->getRequestFormat(null));
1585
1586 $request = new Request();
1587 $this->assertNull($request->setRequestFormat('foo'));
1588 $this->assertEquals('foo', $request->getRequestFormat(null));
1589
1590 $request = new Request(['_format' => 'foo']);
1591 $this->assertEquals('html', $request->getRequestFormat());
1592 }
1593
1594 public function testHasSession()
1595 {
1596 $request = new Request();
1597
1598 $this->assertFalse($request->hasSession());
1599 $request->setSession(new Session(new MockArraySessionStorage()));
1600 $this->assertTrue($request->hasSession());
1601 }
1602
1603 public function testGetSession()
1604 {
1605 $request = new Request();
1606
1607 $request->setSession(new Session(new MockArraySessionStorage()));
1608 $this->assertTrue($request->hasSession());
1609
1610 $session = $request->getSession();
1611 $this->assertObjectHasAttribute('storage', $session);
1612 $this->assertObjectHasAttribute('flashName', $session);
1613 $this->assertObjectHasAttribute('attributeName', $session);
1614 }
1615
1616 public function testHasPreviousSession()
1617 {
1618 $request = new Request();
1619
1620 $this->assertFalse($request->hasPreviousSession());
1621 $request->cookies->set('MOCKSESSID', 'foo');
1622 $this->assertFalse($request->hasPreviousSession());
1623 $request->setSession(new Session(new MockArraySessionStorage()));
1624 $this->assertTrue($request->hasPreviousSession());
1625 }
1626
1627 public function testToString()
1628 {
1629 $request = new Request();
1630
1631 $request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
1632 $request->cookies->set('Foo', 'Bar');
1633
1634 $asString = (string) $request;
1635
1636 $this->assertStringContainsString('Accept-Language: zh, en-us; q=0.8, en; q=0.6', $asString);
1637 $this->assertStringContainsString('Cookie: Foo=Bar', $asString);
1638
1639 $request->cookies->set('Another', 'Cookie');
1640
1641 $asString = (string) $request;
1642
1643 $this->assertStringContainsString('Cookie: Foo=Bar; Another=Cookie', $asString);
1644 }
1645
1646 public function testIsMethod()
1647 {
1648 $request = new Request();
1649 $request->setMethod('POST');
1650 $this->assertTrue($request->isMethod('POST'));
1651 $this->assertTrue($request->isMethod('post'));
1652 $this->assertFalse($request->isMethod('GET'));
1653 $this->assertFalse($request->isMethod('get'));
1654
1655 $request->setMethod('GET');
1656 $this->assertTrue($request->isMethod('GET'));
1657 $this->assertTrue($request->isMethod('get'));
1658 $this->assertFalse($request->isMethod('POST'));
1659 $this->assertFalse($request->isMethod('post'));
1660 }
1661
1662 /**
1663 * @dataProvider getBaseUrlData
1664 */
1665 public function testGetBaseUrl($uri, $server, $expectedBaseUrl, $expectedPathInfo)
1666 {
1667 $request = Request::create($uri, 'GET', [], [], [], $server);
1668
1669 $this->assertSame($expectedBaseUrl, $request->getBaseUrl(), 'baseUrl');
1670 $this->assertSame($expectedPathInfo, $request->getPathInfo(), 'pathInfo');
1671 }
1672
1673 public function getBaseUrlData()
1674 {
1675 return [
1676 [
1677 '/fruit/strawberry/1234index.php/blah',
1678 [
1679 'SCRIPT_FILENAME' => 'E:/Sites/cc-new/public_html/fruit/index.php',
1680 'SCRIPT_NAME' => '/fruit/index.php',
1681 'PHP_SELF' => '/fruit/index.php',
1682 ],
1683 '/fruit',
1684 '/strawberry/1234index.php/blah',
1685 ],
1686 [
1687 '/fruit/strawberry/1234index.php/blah',
1688 [
1689 'SCRIPT_FILENAME' => 'E:/Sites/cc-new/public_html/index.php',
1690 'SCRIPT_NAME' => '/index.php',
1691 'PHP_SELF' => '/index.php',
1692 ],
1693 '',
1694 '/fruit/strawberry/1234index.php/blah',
1695 ],
1696 [
1697 '/foo%20bar/',
1698 [
1699 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
1700 'SCRIPT_NAME' => '/foo bar/app.php',
1701 'PHP_SELF' => '/foo bar/app.php',
1702 ],
1703 '/foo%20bar',
1704 '/',
1705 ],
1706 [
1707 '/foo%20bar/home',
1708 [
1709 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
1710 'SCRIPT_NAME' => '/foo bar/app.php',
1711 'PHP_SELF' => '/foo bar/app.php',
1712 ],
1713 '/foo%20bar',
1714 '/home',
1715 ],
1716 [
1717 '/foo%20bar/app.php/home',
1718 [
1719 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
1720 'SCRIPT_NAME' => '/foo bar/app.php',
1721 'PHP_SELF' => '/foo bar/app.php',
1722 ],
1723 '/foo%20bar/app.php',
1724 '/home',
1725 ],
1726 [
1727 '/foo%20bar/app.php/home%3Dbaz',
1728 [
1729 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo bar/app.php',
1730 'SCRIPT_NAME' => '/foo bar/app.php',
1731 'PHP_SELF' => '/foo bar/app.php',
1732 ],
1733 '/foo%20bar/app.php',
1734 '/home%3Dbaz',
1735 ],
1736 [
1737 '/foo/bar+baz',
1738 [
1739 'SCRIPT_FILENAME' => '/home/John Doe/public_html/foo/app.php',
1740 'SCRIPT_NAME' => '/foo/app.php',
1741 'PHP_SELF' => '/foo/app.php',
1742 ],
1743 '/foo',
1744 '/bar+baz',
1745 ],
1746 ];
1747 }
1748
1749 /**
1750 * @dataProvider urlencodedStringPrefixData
1751 */
1752 public function testUrlencodedStringPrefix($string, $prefix, $expect)
1753 {
1754 $request = new Request();
1755
1756 $me = new \ReflectionMethod($request, 'getUrlencodedPrefix');
1757 $me->setAccessible(true);
1758
1759 $this->assertSame($expect, $me->invoke($request, $string, $prefix));
1760 }
1761
1762 public function urlencodedStringPrefixData()
1763 {
1764 return [
1765 ['foo', 'foo', 'foo'],
1766 ['fo%6f', 'foo', 'fo%6f'],
1767 ['foo/bar', 'foo', 'foo'],
1768 ['fo%6f/bar', 'foo', 'fo%6f'],
1769 ['f%6f%6f/bar', 'foo', 'f%6f%6f'],
1770 ['%66%6F%6F/bar', 'foo', '%66%6F%6F'],
1771 ['fo+o/bar', 'fo+o', 'fo+o'],
1772 ['fo%2Bo/bar', 'fo+o', 'fo%2Bo'],
1773 ];
1774 }
1775
1776 private function disableHttpMethodParameterOverride()
1777 {
1778 $class = new \ReflectionClass('Give\\Vendors\\Symfony\\Component\\HttpFoundation\\Request');
1779 $property = $class->getProperty('httpMethodParameterOverride');
1780 $property->setAccessible(true);
1781 $property->setValue(false);
1782 }
1783
1784 private function getRequestInstanceForClientIpTests($remoteAddr, $httpForwardedFor, $trustedProxies)
1785 {
1786 $request = new Request();
1787
1788 $server = ['REMOTE_ADDR' => $remoteAddr];
1789 if (null !== $httpForwardedFor) {
1790 $server['HTTP_X_FORWARDED_FOR'] = $httpForwardedFor;
1791 }
1792
1793 if ($trustedProxies) {
1794 Request::setTrustedProxies($trustedProxies, Request::HEADER_X_FORWARDED_ALL);
1795 }
1796
1797 $request->initialize([], [], [], [], [], $server);
1798
1799 return $request;
1800 }
1801
1802 private function getRequestInstanceForClientIpsForwardedTests($remoteAddr, $httpForwarded, $trustedProxies)
1803 {
1804 $request = new Request();
1805
1806 $server = ['REMOTE_ADDR' => $remoteAddr];
1807
1808 if (null !== $httpForwarded) {
1809 $server['HTTP_FORWARDED'] = $httpForwarded;
1810 }
1811
1812 if ($trustedProxies) {
1813 Request::setTrustedProxies($trustedProxies, Request::HEADER_FORWARDED);
1814 }
1815
1816 $request->initialize([], [], [], [], [], $server);
1817
1818 return $request;
1819 }
1820
1821 public function testTrustedProxiesXForwardedFor()
1822 {
1823 $request = Request::create('http://example.com/');
1824 $request->server->set('REMOTE_ADDR', '3.3.3.3');
1825 $request->headers->set('X_FORWARDED_FOR', '1.1.1.1, 2.2.2.2');
1826 $request->headers->set('X_FORWARDED_HOST', 'foo.example.com:1234, real.example.com:8080');
1827 $request->headers->set('X_FORWARDED_PROTO', 'https');
1828 $request->headers->set('X_FORWARDED_PORT', 443);
1829
1830 // no trusted proxies
1831 $this->assertEquals('3.3.3.3', $request->getClientIp());
1832 $this->assertEquals('example.com', $request->getHost());
1833 $this->assertEquals(80, $request->getPort());
1834 $this->assertFalse($request->isSecure());
1835
1836 // disabling proxy trusting
1837 Request::setTrustedProxies([], Request::HEADER_X_FORWARDED_ALL);
1838 $this->assertEquals('3.3.3.3', $request->getClientIp());
1839 $this->assertEquals('example.com', $request->getHost());
1840 $this->assertEquals(80, $request->getPort());
1841 $this->assertFalse($request->isSecure());
1842
1843 // request is forwarded by a non-trusted proxy
1844 Request::setTrustedProxies(['2.2.2.2'], Request::HEADER_X_FORWARDED_ALL);
1845 $this->assertEquals('3.3.3.3', $request->getClientIp());
1846 $this->assertEquals('example.com', $request->getHost());
1847 $this->assertEquals(80, $request->getPort());
1848 $this->assertFalse($request->isSecure());
1849
1850 // trusted proxy via setTrustedProxies()
1851 Request::setTrustedProxies(['3.3.3.3', '2.2.2.2'], Request::HEADER_X_FORWARDED_ALL);
1852 $this->assertEquals('1.1.1.1', $request->getClientIp());
1853 $this->assertEquals('foo.example.com', $request->getHost());
1854 $this->assertEquals(443, $request->getPort());
1855 $this->assertTrue($request->isSecure());
1856
1857 // trusted proxy via setTrustedProxies()
1858 Request::setTrustedProxies(['3.3.3.4', '2.2.2.2'], Request::HEADER_X_FORWARDED_ALL);
1859 $this->assertEquals('3.3.3.3', $request->getClientIp());
1860 $this->assertEquals('example.com', $request->getHost());
1861 $this->assertEquals(80, $request->getPort());
1862 $this->assertFalse($request->isSecure());
1863
1864 // check various X_FORWARDED_PROTO header values
1865 Request::setTrustedProxies(['3.3.3.3', '2.2.2.2'], Request::HEADER_X_FORWARDED_ALL);
1866 $request->headers->set('X_FORWARDED_PROTO', 'ssl');
1867 $this->assertTrue($request->isSecure());
1868
1869 $request->headers->set('X_FORWARDED_PROTO', 'https, http');
1870 $this->assertTrue($request->isSecure());
1871 }
1872
1873 /**
1874 * @group legacy
1875 * @expectedDeprecation The "Give\Vendors\Symfony\Component\HttpFoundation\Request::setTrustedHeaderName()" method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the $trustedHeaderSet argument of the Request::setTrustedProxies() method instead.
1876 */
1877 public function testLegacyTrustedProxies()
1878 {
1879 $request = Request::create('http://example.com/');
1880 $request->server->set('REMOTE_ADDR', '3.3.3.3');
1881 $request->headers->set('X_FORWARDED_FOR', '1.1.1.1, 2.2.2.2');
1882 $request->headers->set('X_FORWARDED_HOST', 'foo.example.com, real.example.com:8080');
1883 $request->headers->set('X_FORWARDED_PROTO', 'https');
1884 $request->headers->set('X_FORWARDED_PORT', 443);
1885 $request->headers->set('X_MY_FOR', '3.3.3.3, 4.4.4.4');
1886 $request->headers->set('X_MY_HOST', 'my.example.com');
1887 $request->headers->set('X_MY_PROTO', 'http');
1888 $request->headers->set('X_MY_PORT', 81);
1889
1890 Request::setTrustedProxies(['3.3.3.3', '2.2.2.2'], Request::HEADER_X_FORWARDED_ALL);
1891
1892 // custom header names
1893 Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_MY_FOR');
1894 Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_MY_HOST');
1895 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_MY_PORT');
1896 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_MY_PROTO');
1897 $this->assertEquals('4.4.4.4', $request->getClientIp());
1898 $this->assertEquals('my.example.com', $request->getHost());
1899 $this->assertEquals(81, $request->getPort());
1900 $this->assertFalse($request->isSecure());
1901
1902 // disabling via empty header names
1903 Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, null);
1904 Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, null);
1905 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, null);
1906 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, null);
1907 $this->assertEquals('3.3.3.3', $request->getClientIp());
1908 $this->assertEquals('example.com', $request->getHost());
1909 $this->assertEquals(80, $request->getPort());
1910 $this->assertFalse($request->isSecure());
1911
1912 //reset
1913 Request::setTrustedHeaderName(Request::HEADER_FORWARDED, 'FORWARDED');
1914 Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_FORWARDED_FOR');
1915 Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_FORWARDED_HOST');
1916 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_FORWARDED_PORT');
1917 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_FORWARDED_PROTO');
1918 }
1919
1920 public function testTrustedProxiesForwarded()
1921 {
1922 $request = Request::create('http://example.com/');
1923 $request->server->set('REMOTE_ADDR', '3.3.3.3');
1924 $request->headers->set('FORWARDED', 'for=1.1.1.1, host=foo.example.com:8080, proto=https, for=2.2.2.2, host=real.example.com:8080');
1925
1926 // no trusted proxies
1927 $this->assertEquals('3.3.3.3', $request->getClientIp());
1928 $this->assertEquals('example.com', $request->getHost());
1929 $this->assertEquals(80, $request->getPort());
1930 $this->assertFalse($request->isSecure());
1931
1932 // disabling proxy trusting
1933 Request::setTrustedProxies([], Request::HEADER_FORWARDED);
1934 $this->assertEquals('3.3.3.3', $request->getClientIp());
1935 $this->assertEquals('example.com', $request->getHost());
1936 $this->assertEquals(80, $request->getPort());
1937 $this->assertFalse($request->isSecure());
1938
1939 // request is forwarded by a non-trusted proxy
1940 Request::setTrustedProxies(['2.2.2.2'], Request::HEADER_FORWARDED);
1941 $this->assertEquals('3.3.3.3', $request->getClientIp());
1942 $this->assertEquals('example.com', $request->getHost());
1943 $this->assertEquals(80, $request->getPort());
1944 $this->assertFalse($request->isSecure());
1945
1946 // trusted proxy via setTrustedProxies()
1947 Request::setTrustedProxies(['3.3.3.3', '2.2.2.2'], Request::HEADER_FORWARDED);
1948 $this->assertEquals('1.1.1.1', $request->getClientIp());
1949 $this->assertEquals('foo.example.com', $request->getHost());
1950 $this->assertEquals(8080, $request->getPort());
1951 $this->assertTrue($request->isSecure());
1952
1953 // trusted proxy via setTrustedProxies()
1954 Request::setTrustedProxies(['3.3.3.4', '2.2.2.2'], Request::HEADER_FORWARDED);
1955 $this->assertEquals('3.3.3.3', $request->getClientIp());
1956 $this->assertEquals('example.com', $request->getHost());
1957 $this->assertEquals(80, $request->getPort());
1958 $this->assertFalse($request->isSecure());
1959
1960 // check various X_FORWARDED_PROTO header values
1961 Request::setTrustedProxies(['3.3.3.3', '2.2.2.2'], Request::HEADER_FORWARDED);
1962 $request->headers->set('FORWARDED', 'proto=ssl');
1963 $this->assertTrue($request->isSecure());
1964
1965 $request->headers->set('FORWARDED', 'proto=https, proto=http');
1966 $this->assertTrue($request->isSecure());
1967 }
1968
1969 /**
1970 * @group legacy
1971 */
1972 public function testSetTrustedProxiesInvalidHeaderName()
1973 {
1974 $this->expectException('InvalidArgumentException');
1975 Request::create('http://example.com/');
1976 Request::setTrustedHeaderName('bogus name', 'X_MY_FOR');
1977 }
1978
1979 /**
1980 * @group legacy
1981 */
1982 public function testGetTrustedProxiesInvalidHeaderName()
1983 {
1984 $this->expectException('InvalidArgumentException');
1985 Request::create('http://example.com/');
1986 Request::getTrustedHeaderName('bogus name');
1987 }
1988
1989 /**
1990 * @dataProvider iisRequestUriProvider
1991 */
1992 public function testIISRequestUri($headers, $server, $expectedRequestUri)
1993 {
1994 $request = new Request();
1995 $request->headers->replace($headers);
1996 $request->server->replace($server);
1997
1998 $this->assertEquals($expectedRequestUri, $request->getRequestUri(), '->getRequestUri() is correct');
1999
2000 $subRequestUri = '/bar/foo';
2001 $subRequest = Request::create($subRequestUri, 'get', [], [], [], $request->server->all());
2002 $this->assertEquals($subRequestUri, $subRequest->getRequestUri(), '->getRequestUri() is correct in sub request');
2003 }
2004
2005 public function iisRequestUriProvider()
2006 {
2007 return [
2008 [
2009 [],
2010 [
2011 'IIS_WasUrlRewritten' => '1',
2012 'UNENCODED_URL' => '/foo/bar',
2013 ],
2014 '/foo/bar',
2015 ],
2016 [
2017 [],
2018 [
2019 'ORIG_PATH_INFO' => '/foo/bar',
2020 ],
2021 '/foo/bar',
2022 ],
2023 [
2024 [],
2025 [
2026 'ORIG_PATH_INFO' => '/foo/bar',
2027 'QUERY_STRING' => 'foo=bar',
2028 ],
2029 '/foo/bar?foo=bar',
2030 ],
2031 ];
2032 }
2033
2034 public function testTrustedHosts()
2035 {
2036 // create a request
2037 $request = Request::create('/');
2038
2039 // no trusted host set -> no host check
2040 $request->headers->set('host', 'evil.com');
2041 $this->assertEquals('evil.com', $request->getHost());
2042
2043 // add a trusted domain and all its subdomains
2044 Request::setTrustedHosts(['^([a-z]{9}\.)?trusted\.com$']);
2045
2046 // untrusted host
2047 $request->headers->set('host', 'evil.com');
2048 try {
2049 $request->getHost();
2050 $this->fail('Request::getHost() should throw an exception when host is not trusted.');
2051 } catch (SuspiciousOperationException $e) {
2052 $this->assertEquals('Untrusted Host "evil.com".', $e->getMessage());
2053 }
2054
2055 // trusted hosts
2056 $request->headers->set('host', 'trusted.com');
2057 $this->assertEquals('trusted.com', $request->getHost());
2058 $this->assertEquals(80, $request->getPort());
2059
2060 $request->server->set('HTTPS', true);
2061 $request->headers->set('host', 'trusted.com');
2062 $this->assertEquals('trusted.com', $request->getHost());
2063 $this->assertEquals(443, $request->getPort());
2064 $request->server->set('HTTPS', false);
2065
2066 $request->headers->set('host', 'trusted.com:8000');
2067 $this->assertEquals('trusted.com', $request->getHost());
2068 $this->assertEquals(8000, $request->getPort());
2069
2070 $request->headers->set('host', 'subdomain.trusted.com');
2071 $this->assertEquals('subdomain.trusted.com', $request->getHost());
2072 }
2073
2074 public function testSetTrustedHostsDoesNotBreakOnSpecialCharacters()
2075 {
2076 Request::setTrustedHosts(['localhost(\.local){0,1}#,example.com', 'localhost']);
2077
2078 $request = Request::create('/');
2079 $request->headers->set('host', 'localhost');
2080 $this->assertSame('localhost', $request->getHost());
2081 }
2082
2083 public function testFactory()
2084 {
2085 Request::setFactory(function (array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null) {
2086 return new NewRequest();
2087 });
2088
2089 $this->assertEquals('foo', Request::create('/')->getFoo());
2090
2091 Request::setFactory(null);
2092 }
2093
2094 /**
2095 * @dataProvider getLongHostNames
2096 */
2097 public function testVeryLongHosts($host)
2098 {
2099 $start = microtime(true);
2100
2101 $request = Request::create('/');
2102 $request->headers->set('host', $host);
2103 $this->assertEquals($host, $request->getHost());
2104 $this->assertLessThan(5, microtime(true) - $start);
2105 }
2106
2107 /**
2108 * @dataProvider getHostValidities
2109 */
2110 public function testHostValidity($host, $isValid, $expectedHost = null, $expectedPort = null)
2111 {
2112 $request = Request::create('/');
2113 $request->headers->set('host', $host);
2114
2115 if ($isValid) {
2116 $this->assertSame($expectedHost ?: $host, $request->getHost());
2117 if ($expectedPort) {
2118 $this->assertSame($expectedPort, $request->getPort());
2119 }
2120 } else {
2121 $this->expectException(SuspiciousOperationException::class);
2122 $this->expectExceptionMessage('Invalid Host');
2123
2124 $request->getHost();
2125 }
2126 }
2127
2128 public function getHostValidities()
2129 {
2130 return [
2131 ['.a', false],
2132 ['a..', false],
2133 ['a.', true],
2134 ["\xE9", false],
2135 ['[::1]', true],
2136 ['[::1]:80', true, '[::1]', 80],
2137 [str_repeat('.', 101), false],
2138 ];
2139 }
2140
2141 public function getLongHostNames()
2142 {
2143 return [
2144 ['a'.str_repeat('.a', 40000)],
2145 [str_repeat(':', 101)],
2146 ];
2147 }
2148
2149 /**
2150 * @dataProvider methodIdempotentProvider
2151 */
2152 public function testMethodIdempotent($method, $idempotent)
2153 {
2154 $request = new Request();
2155 $request->setMethod($method);
2156 $this->assertEquals($idempotent, $request->isMethodIdempotent());
2157 }
2158
2159 public function methodIdempotentProvider()
2160 {
2161 return [
2162 ['HEAD', true],
2163 ['GET', true],
2164 ['POST', false],
2165 ['PUT', true],
2166 ['PATCH', false],
2167 ['DELETE', true],
2168 ['PURGE', true],
2169 ['OPTIONS', true],
2170 ['TRACE', true],
2171 ['CONNECT', false],
2172 ];
2173 }
2174
2175 /**
2176 * @dataProvider methodSafeProvider
2177 */
2178 public function testMethodSafe($method, $safe)
2179 {
2180 $request = new Request();
2181 $request->setMethod($method);
2182 $this->assertEquals($safe, $request->isMethodSafe(false));
2183 }
2184
2185 public function methodSafeProvider()
2186 {
2187 return [
2188 ['HEAD', true],
2189 ['GET', true],
2190 ['POST', false],
2191 ['PUT', false],
2192 ['PATCH', false],
2193 ['DELETE', false],
2194 ['PURGE', false],
2195 ['OPTIONS', true],
2196 ['TRACE', true],
2197 ['CONNECT', false],
2198 ];
2199 }
2200
2201 /**
2202 * @group legacy
2203 * @expectedDeprecation Checking only for cacheable HTTP methods with Symfony\Component\HttpFoundation\Request::isMethodSafe() is deprecated since Symfony 3.2 and will throw an exception in 4.0. Disable checking only for cacheable methods by calling the method with `false` as first argument or use the Request::isMethodCacheable() instead.
2204 */
2205 public function testMethodSafeChecksCacheable()
2206 {
2207 $request = new Request();
2208 $request->setMethod('OPTIONS');
2209 $this->assertFalse($request->isMethodSafe());
2210 }
2211
2212 /**
2213 * @dataProvider methodCacheableProvider
2214 */
2215 public function testMethodCacheable($method, $cacheable)
2216 {
2217 $request = new Request();
2218 $request->setMethod($method);
2219 $this->assertEquals($cacheable, $request->isMethodCacheable());
2220 }
2221
2222 public function methodCacheableProvider()
2223 {
2224 return [
2225 ['HEAD', true],
2226 ['GET', true],
2227 ['POST', false],
2228 ['PUT', false],
2229 ['PATCH', false],
2230 ['DELETE', false],
2231 ['PURGE', false],
2232 ['OPTIONS', false],
2233 ['TRACE', false],
2234 ['CONNECT', false],
2235 ];
2236 }
2237
2238 /**
2239 * @group legacy
2240 */
2241 public function testGetTrustedHeaderName()
2242 {
2243 Request::setTrustedProxies(['8.8.8.8'], Request::HEADER_X_FORWARDED_ALL);
2244
2245 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
2246 $this->assertSame('X_FORWARDED_FOR', Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP));
2247 $this->assertSame('X_FORWARDED_HOST', Request::getTrustedHeaderName(Request::HEADER_CLIENT_HOST));
2248 $this->assertSame('X_FORWARDED_PORT', Request::getTrustedHeaderName(Request::HEADER_CLIENT_PORT));
2249 $this->assertSame('X_FORWARDED_PROTO', Request::getTrustedHeaderName(Request::HEADER_CLIENT_PROTO));
2250
2251 Request::setTrustedProxies(['8.8.8.8'], Request::HEADER_FORWARDED);
2252
2253 $this->assertSame('FORWARDED', Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
2254 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP));
2255 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_HOST));
2256 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_PORT));
2257 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_PROTO));
2258
2259 Request::setTrustedHeaderName(Request::HEADER_FORWARDED, 'A');
2260 Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'B');
2261 Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'C');
2262 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'D');
2263 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'E');
2264
2265 Request::setTrustedProxies(['8.8.8.8'], Request::HEADER_FORWARDED);
2266
2267 $this->assertSame('A', Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
2268 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP));
2269 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_HOST));
2270 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_PORT));
2271 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_CLIENT_PROTO));
2272
2273 Request::setTrustedProxies(['8.8.8.8'], Request::HEADER_X_FORWARDED_ALL);
2274
2275 $this->assertNull(Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
2276 $this->assertSame('B', Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP));
2277 $this->assertSame('C', Request::getTrustedHeaderName(Request::HEADER_CLIENT_HOST));
2278 $this->assertSame('D', Request::getTrustedHeaderName(Request::HEADER_CLIENT_PORT));
2279 $this->assertSame('E', Request::getTrustedHeaderName(Request::HEADER_CLIENT_PROTO));
2280
2281 Request::setTrustedProxies(['8.8.8.8'], Request::HEADER_FORWARDED);
2282
2283 $this->assertSame('A', Request::getTrustedHeaderName(Request::HEADER_FORWARDED));
2284
2285 //reset
2286 Request::setTrustedHeaderName(Request::HEADER_FORWARDED, 'FORWARDED');
2287 Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_FORWARDED_FOR');
2288 Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_FORWARDED_HOST');
2289 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X_FORWARDED_PORT');
2290 Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X_FORWARDED_PROTO');
2291 }
2292
2293 /**
2294 * @dataProvider protocolVersionProvider
2295 */
2296 public function testProtocolVersion($serverProtocol, $trustedProxy, $via, $expected)
2297 {
2298 if ($trustedProxy) {
2299 Request::setTrustedProxies(['1.1.1.1'], -1);
2300 }
2301
2302 $request = new Request();
2303 $request->server->set('SERVER_PROTOCOL', $serverProtocol);
2304 $request->server->set('REMOTE_ADDR', '1.1.1.1');
2305 $request->headers->set('Via', $via);
2306
2307 $this->assertSame($expected, $request->getProtocolVersion());
2308 }
2309
2310 public function protocolVersionProvider()
2311 {
2312 return [
2313 'untrusted without via' => ['HTTP/2.0', false, '', 'HTTP/2.0'],
2314 'untrusted with via' => ['HTTP/2.0', false, '1.0 fred, 1.1 nowhere.com (Apache/1.1)', 'HTTP/2.0'],
2315 'trusted without via' => ['HTTP/2.0', true, '', 'HTTP/2.0'],
2316 'trusted with via' => ['HTTP/2.0', true, '1.0 fred, 1.1 nowhere.com (Apache/1.1)', 'HTTP/1.0'],
2317 'trusted with via and protocol name' => ['HTTP/2.0', true, 'HTTP/1.0 fred, HTTP/1.1 nowhere.com (Apache/1.1)', 'HTTP/1.0'],
2318 'trusted with broken via' => ['HTTP/2.0', true, 'HTTP/1^0 foo', 'HTTP/2.0'],
2319 'trusted with partially-broken via' => ['HTTP/2.0', true, '1.0 fred, foo', 'HTTP/1.0'],
2320 ];
2321 }
2322
2323 public function nonstandardRequestsData()
2324 {
2325 return [
2326 ['', '', '/', 'http://host:8080/', ''],
2327 ['/', '', '/', 'http://host:8080/', ''],
2328
2329 ['hello/app.php/x', '', '/x', 'http://host:8080/hello/app.php/x', '/hello', '/hello/app.php'],
2330 ['/hello/app.php/x', '', '/x', 'http://host:8080/hello/app.php/x', '/hello', '/hello/app.php'],
2331
2332 ['', 'a=b', '/', 'http://host:8080/?a=b'],
2333 ['?a=b', 'a=b', '/', 'http://host:8080/?a=b'],
2334 ['/?a=b', 'a=b', '/', 'http://host:8080/?a=b'],
2335
2336 ['x', 'a=b', '/x', 'http://host:8080/x?a=b'],
2337 ['x?a=b', 'a=b', '/x', 'http://host:8080/x?a=b'],
2338 ['/x?a=b', 'a=b', '/x', 'http://host:8080/x?a=b'],
2339
2340 ['hello/x', '', '/x', 'http://host:8080/hello/x', '/hello'],
2341 ['/hello/x', '', '/x', 'http://host:8080/hello/x', '/hello'],
2342
2343 ['hello/app.php/x', 'a=b', '/x', 'http://host:8080/hello/app.php/x?a=b', '/hello', '/hello/app.php'],
2344 ['hello/app.php/x?a=b', 'a=b', '/x', 'http://host:8080/hello/app.php/x?a=b', '/hello', '/hello/app.php'],
2345 ['/hello/app.php/x?a=b', 'a=b', '/x', 'http://host:8080/hello/app.php/x?a=b', '/hello', '/hello/app.php'],
2346 ];
2347 }
2348
2349 /**
2350 * @dataProvider nonstandardRequestsData
2351 */
2352 public function testNonstandardRequests($requestUri, $queryString, $expectedPathInfo, $expectedUri, $expectedBasePath = '', $expectedBaseUrl = null)
2353 {
2354 if (null === $expectedBaseUrl) {
2355 $expectedBaseUrl = $expectedBasePath;
2356 }
2357
2358 $server = [
2359 'HTTP_HOST' => 'host:8080',
2360 'SERVER_PORT' => '8080',
2361 'QUERY_STRING' => $queryString,
2362 'PHP_SELF' => '/hello/app.php',
2363 'SCRIPT_FILENAME' => '/some/path/app.php',
2364 'REQUEST_URI' => $requestUri,
2365 ];
2366
2367 $request = new Request([], [], [], [], [], $server);
2368
2369 $this->assertEquals($expectedPathInfo, $request->getPathInfo());
2370 $this->assertEquals($expectedUri, $request->getUri());
2371 $this->assertEquals($queryString, $request->getQueryString());
2372 $this->assertEquals(8080, $request->getPort());
2373 $this->assertEquals('host:8080', $request->getHttpHost());
2374 $this->assertEquals($expectedBaseUrl, $request->getBaseUrl());
2375 $this->assertEquals($expectedBasePath, $request->getBasePath());
2376 }
2377
2378 public function testTrustedHost()
2379 {
2380 Request::setTrustedProxies(['1.1.1.1'], -1);
2381
2382 $request = Request::create('/');
2383 $request->server->set('REMOTE_ADDR', '1.1.1.1');
2384 $request->headers->set('Forwarded', 'host=localhost:8080');
2385 $request->headers->set('X-Forwarded-Host', 'localhost:8080');
2386
2387 $this->assertSame('localhost:8080', $request->getHttpHost());
2388 $this->assertSame(8080, $request->getPort());
2389
2390 $request = Request::create('/');
2391 $request->server->set('REMOTE_ADDR', '1.1.1.1');
2392 $request->headers->set('Forwarded', 'host="[::1]:443"');
2393 $request->headers->set('X-Forwarded-Host', '[::1]:443');
2394 $request->headers->set('X-Forwarded-Port', 443);
2395
2396 $this->assertSame('[::1]:443', $request->getHttpHost());
2397 $this->assertSame(443, $request->getPort());
2398 }
2399
2400 public function testTrustedPort()
2401 {
2402 Request::setTrustedProxies(['1.1.1.1'], -1);
2403
2404 $request = Request::create('/');
2405 $request->server->set('REMOTE_ADDR', '1.1.1.1');
2406 $request->headers->set('Forwarded', 'host=localhost:8080');
2407 $request->headers->set('X-Forwarded-Port', 8080);
2408
2409 $this->assertSame(8080, $request->getPort());
2410
2411 $request = Request::create('/');
2412 $request->server->set('REMOTE_ADDR', '1.1.1.1');
2413 $request->headers->set('Forwarded', 'host=localhost');
2414 $request->headers->set('X-Forwarded-Port', 80);
2415
2416 $this->assertSame(80, $request->getPort());
2417
2418 $request = Request::create('/');
2419 $request->server->set('REMOTE_ADDR', '1.1.1.1');
2420 $request->headers->set('Forwarded', 'host="[::1]"');
2421 $request->headers->set('X-Forwarded-Proto', 'https');
2422 $request->headers->set('X-Forwarded-Port', 443);
2423
2424 $this->assertSame(443, $request->getPort());
2425 }
2426
2427 public function testTrustedPortDoesNotDefaultToZero()
2428 {
2429 Request::setTrustedProxies(['1.1.1.1'], Request::HEADER_X_FORWARDED_ALL);
2430
2431 $request = Request::create('/');
2432 $request->server->set('REMOTE_ADDR', '1.1.1.1');
2433 $request->headers->set('X-Forwarded-Host', 'test.example.com');
2434 $request->headers->set('X-Forwarded-Port', '');
2435
2436 $this->assertSame(80, $request->getPort());
2437 }
2438 }
2439
2440 class RequestContentProxy extends Request
2441 {
2442 public function getContent($asResource = false)
2443 {
2444 return http_build_query(['_method' => 'PUT', 'content' => 'mycontent'], '', '&');
2445 }
2446 }
2447
2448 class NewRequest extends Request
2449 {
2450 public function getFoo()
2451 {
2452 return 'foo';
2453 }
2454 }
2455