‪TYPO3CMS  ‪main
RequestTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\StreamInterface;
24 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
25 
31 final class ‪RequestTest extends UnitTestCase
32 {
33  protected ?‪Request ‪$request;
34 
35  protected function ‪setUp(): void
36  {
37  parent::setUp();
38  $this->request = new ‪Request();
39  }
40 
44  public function ‪getMethodIsGetByDefault(): void
45  {
46  self::assertEquals('GET', $this->request->getMethod());
47  }
48 
53  {
54  ‪$request = $this->request->‪withMethod('GET');
55  self::assertNotSame($this->request, ‪$request);
56  self::assertEquals('GET', ‪$request->‪getMethod());
57  }
58 
63  {
64  ‪$request = $this->request->‪withUri(new ‪Uri('https://example.com:10082/foo/bar?baz=bat'));
65  self::assertNotSame($this->request, ‪$request);
66  $request2 = ‪$request->‪withUri(new ‪Uri('/baz/bat?foo=bar'));
67  self::assertNotSame($this->request, $request2);
68  self::assertNotSame(‪$request, $request2);
69  self::assertEquals('/baz/bat?foo=bar', (string)$request2->getUri());
70  }
71 
76  {
77  $uri = new ‪Uri('http://example.com/');
78  $body = new ‪Stream('php://memory');
79  $headers = [
80  'x-foo' => ['bar'],
81  ];
82  ‪$request = new ‪Request(
83  $uri,
84  'POST',
85  $body,
86  $headers
87  );
88 
89  self::assertSame($uri, ‪$request->‪getUri());
90  self::assertEquals('POST', ‪$request->‪getMethod());
91  self::assertSame($body, ‪$request->‪getBody());
92  $testHeaders = ‪$request->‪getHeaders();
93  foreach ($headers as $key => $value) {
94  self::assertArrayHasKey($key, $testHeaders);
95  self::assertEquals($value, $testHeaders[$key]);
96  }
97  }
98 
103  {
104  $this->expectException(\InvalidArgumentException::class);
105  $this->expectExceptionCode(1436717275);
106  new ‪Request(null, 'BOGUS-METHOD');
107  }
108 
109  public static function ‪invalidRequestBodyDataProvider(): array
110  {
111  return [
112  'true' => [true],
113  'false' => [false],
114  'int' => [1],
115  'float' => [1.1],
116  'array' => [['BODY']],
117  'stdClass' => [(object)['body' => 'BODY']],
118  ];
119  }
120 
125  public function ‪constructorRaisesExceptionForInvalidBody($body): void
126  {
127  $this->expectException(\InvalidArgumentException::class);
128  $this->expectExceptionCode(1436717271);
129  new ‪Request(null, 'GET', $body);
130  }
131 
132  public static function ‪validRequestBodyDataProvider(): array
133  {
134  return [
135  'stringResourceIdentifier' => ['php://input'],
136  'streamResource' => [fopen('php://memory', 'r')],
137  'streamInterface' => [new ‪Stream(fopen('php://memory', 'r'))],
138  'null' => [null],
139  ];
140  }
141 
148  {
149  new ‪Request(null, 'GET', $body);
150  }
151 
155  public function ‪constructorIgnoresInvalidHeaders(): void
156  {
157  $headers = [
158  ['INVALID'],
159  'x-invalid-null' => null,
160  'x-invalid-object' => (object)['INVALID'],
161  'x-valid-true' => true,
162  'x-valid-false' => false,
163  'x-valid-int' => 1,
164  'x-valid-float' => 1.5,
165  'x-valid-string' => 'VALID',
166  'x-valid-array' => ['VALID'],
167  ];
168  $expected = [
169  'x-valid-true' => ['1'],
170  'x-valid-false' => [''],
171  'x-valid-int' => ['1'],
172  'x-valid-float' => ['1.5'],
173  'x-valid-string' => ['VALID'],
174  'x-valid-array' => ['VALID'],
175  ];
176  ‪$request = new ‪Request(null, 'GET', 'php://memory', $headers);
177  self::assertEquals($expected, ‪$request->‪getHeaders());
178  }
179 
184  {
185  ‪$request = new ‪Request();
186  self::assertEquals('/', ‪$request->‪getRequestTarget());
187  }
188 
193  {
194  ‪$request = (new ‪Request())
195  ->withUri(new ‪Uri('http://example.com'));
196  self::assertEquals('/', ‪$request->‪getRequestTarget());
197  }
198 
199  public static function ‪requestsWithUriDataProvider(): array
200  {
201  return [
202  'absolute-uri' => [
203  (new ‪Request())
204  ->withUri(new ‪Uri('https://api.example.com/user'))
205  ->withMethod('POST'),
206  '/user',
207  ],
208  'absolute-uri-with-query' => [
209  (new ‪Request())
210  ->withUri(new ‪Uri('https://api.example.com/user?foo=bar'))
211  ->withMethod('POST'),
212  '/user?foo=bar',
213  ],
214  'relative-uri' => [
215  (new ‪Request())
216  ->withUri(new ‪Uri('/user'))
217  ->withMethod('GET'),
218  '/user',
219  ],
220  'relative-uri-with-query' => [
221  (new ‪Request())
222  ->withUri(new ‪Uri('/user?foo=bar'))
223  ->withMethod('GET'),
224  '/user?foo=bar',
225  ],
226  ];
227  }
228 
233  public function ‪getRequestTargetWhenUriIsPresent(‪$request, $expected): void
234  {
235  self::assertEquals($expected, ‪$request->‪getRequestTarget());
236  }
237 
238  public static function ‪validRequestTargetsDataProvider(): array
239  {
240  return [
241  'asterisk-form' => ['*'],
242  'authority-form' => ['api.example.com'],
243  'absolute-form' => ['https://api.example.com/users'],
244  'absolute-form-query' => ['https://api.example.com/users?foo=bar'],
245  'origin-form-path-only' => ['/users'],
246  'origin-form' => ['/users?id=foo'],
247  ];
248  }
249 
254  public function ‪getRequestTargetCanProvideARequestTarget($requestTarget): void
255  {
256  ‪$request = (new ‪Request())->withRequestTarget($requestTarget);
257  self::assertEquals($requestTarget, ‪$request->‪getRequestTarget());
258  }
259 
264  {
265  ‪$request = new ‪Request();
266  $this->expectException(\InvalidArgumentException::class);
267  $this->expectExceptionCode(1436717273);
268  ‪$request->‪withRequestTarget('foo bar baz');
269  }
270 
275  {
276  ‪$request = (new ‪Request())->withUri(new ‪Uri('https://example.com/foo/bar'));
277  $original = ‪$request->‪getRequestTarget();
278  $newRequest = ‪$request->‪withUri(new ‪Uri('http://mwop.net/bar/baz'));
279  self::assertNotEquals($original, $newRequest->getRequestTarget());
280  }
281 
285  public function ‪getRequestTargetIsResetWithNewUri(): void
286  {
287  ‪$request = (new ‪Request())->withUri(new ‪Uri('https://example.com/foo/bar'));
289  ‪$request->‪withUri(new ‪Uri('http://mwop.net/bar/baz'));
290  }
291 
296  {
297  ‪$request = new ‪Request('http://example.com');
298  $headers = ‪$request->‪getHeaders();
299  self::assertArrayHasKey('host', $headers);
300  self::assertContains('example.com', $headers['host']);
301  }
302 
307  {
308  ‪$request = new ‪Request();
309  $headers = ‪$request->‪getHeaders();
310  self::assertArrayNotHasKey('host', $headers);
311  }
312 
317  {
318  ‪$request = new ‪Request(new ‪Uri());
319  $headers = ‪$request->‪getHeaders();
320  self::assertArrayNotHasKey('host', $headers);
321  }
322 
327  {
328  ‪$request = new ‪Request('http://example.com');
329  $header = ‪$request->‪getHeader('host');
330  self::assertEquals(['example.com'], $header);
331  }
332 
337  {
338  ‪$request = new ‪Request();
339  self::assertSame([], ‪$request->‪getHeader('host'));
340  }
341 
346  {
347  ‪$request = new ‪Request(new ‪Uri());
348  self::assertSame([], ‪$request->‪getHeader('host'));
349  }
350 
355  {
356  ‪$request = new ‪Request('http://example.com');
357  $header = ‪$request->‪getHeaderLine('host');
358  self::assertStringContainsString('example.com', $header);
359  }
360 
365  {
366  ‪$request = new ‪Request();
367  self::assertSame('', ‪$request->‪getHeaderLine('host'));
368  }
369 
374  {
375  ‪$request = new ‪Request(new ‪Uri());
376  self::assertSame('', ‪$request->‪getHeaderLine('host'));
377  }
378 
383  {
384  ‪$request = (new ‪Request())
385  ->withAddedHeader('Host', 'example.com');
386 
387  $uri = (new ‪Uri())->withHost('www.example.com');
388  $new = ‪$request->‪withUri($uri, true);
389 
390  self::assertEquals('example.com', $new->getHeaderLine('Host'));
391  }
392 
397  {
398  ‪$request = (new ‪Request())
399  ->withAddedHeader('Host', 'example.com');
400 
401  $uri = new ‪Uri();
402  $new = ‪$request->‪withUri($uri);
403 
404  self::assertEquals('example.com', $new->getHeaderLine('Host'));
405  }
406 
411  {
412  ‪$request = (new ‪Request())
413  ->withAddedHeader('Host', 'example.com');
414 
415  $uri = (new ‪Uri())
416  ->withHost('www.example.com')
417  ->withPort(10081);
418  $new = ‪$request->‪withUri($uri);
419 
420  self::assertEquals('www.example.com:10081', $new->getHeaderLine('Host'));
421  }
422 
424  {
425  // 'name' => [$headerName, $headerValue, $expectedValue]
426  return [
427  'Foo' => ['Foo', 'bar', 'bar'],
428  'foo' => ['foo', 'bar', 'bar'],
429  'Foo-with-array' => ['Foo', ['bar'], 'bar'],
430  'foo-with-array' => ['foo', ['bar'], 'bar'],
431  ];
432  }
433 
438  public function ‪headerCanBeRetrieved($header, $value, $expected): void
439  {
440  ‪$request = new ‪Request(null, 'GET', 'php://memory', [$header => $value]);
441  self::assertEquals([$expected], ‪$request->‪getHeader(strtolower($header)));
442  self::assertEquals([$expected], ‪$request->‪getHeader(strtoupper($header)));
443  }
444 
445  public static function ‪headersWithInjectionVectorsDataProvider(): array
446  {
447  return [
448  'name-with-cr' => ["X-Foo\r-Bar", 'value'],
449  'name-with-lf' => ["X-Foo\n-Bar", 'value'],
450  'name-with-crlf' => ["X-Foo\r\n-Bar", 'value'],
451  'name-with-2crlf' => ["X-Foo\r\n\r\n-Bar", 'value'],
452  'value-with-cr' => ['X-Foo-Bar', "value\rinjection"],
453  'value-with-lf' => ['X-Foo-Bar', "value\ninjection"],
454  'value-with-crlf' => ['X-Foo-Bar', "value\r\ninjection"],
455  'value-with-2crlf' => ['X-Foo-Bar', "value\r\n\r\ninjection"],
456  'array-value-with-cr' => ['X-Foo-Bar', ["value\rinjection"]],
457  'array-value-with-lf' => ['X-Foo-Bar', ["value\ninjection"]],
458  'array-value-with-crlf' => ['X-Foo-Bar', ["value\r\ninjection"]],
459  'array-value-with-2crlf' => ['X-Foo-Bar', ["value\r\n\r\ninjection"]],
460  ];
461  }
462 
467  public function ‪constructorRaisesExceptionForHeadersWithCRLFVectors($name, $value): void
468  {
469  $this->expectException(\InvalidArgumentException::class);
470  new ‪Request(null, 'GET', 'php://memory', [$name => $value]);
471  }
472 
476  public function ‪supportedRequestMethodsWork(): void
477  {
478  ‪$request = new ‪Request('some-uri', 'PURGE');
479  self::assertEquals('PURGE', ‪$request->‪getMethod());
480  }
481 
486  {
487  $this->expectException(\InvalidArgumentException::class);
488  new ‪Request('some-uri', 'UNSUPPORTED');
489  }
490 }
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\setUp
‪setUp()
Definition: RequestTest.php:35
‪TYPO3\CMS\Core\Http\Message\getBody
‪StreamInterface getBody()
Definition: Message.php:287
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getRequestTargetIsResetWithNewUri
‪getRequestTargetIsResetWithNewUri()
Definition: RequestTest.php:285
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getRequestTargetIsSlashWhenUriHasNoPathOrQuery
‪getRequestTargetIsSlashWhenUriHasNoPathOrQuery()
Definition: RequestTest.php:192
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest
Definition: RequestTest.php:32
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getHeadersContainsNoHostHeaderIfUriDoesNotContainHost
‪getHeadersContainsNoHostHeaderIfUriDoesNotContainHost()
Definition: RequestTest.php:316
‪TYPO3\CMS\Core\Tests\Unit\Http
Definition: ApplicationTypeTest.php:18
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getMethodIsGetByDefault
‪getMethodIsGetByDefault()
Definition: RequestTest.php:44
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getHeaderLineWithHostDoesNotTakePrecedenceOverHostWithPortFromUri
‪getHeaderLineWithHostDoesNotTakePrecedenceOverHostWithPortFromUri()
Definition: RequestTest.php:410
‪TYPO3\CMS\Core\Http\Request\getRequestTarget
‪getRequestTarget()
Definition: Request.php:200
‪TYPO3\CMS\Core\Http\Message\getHeaderLine
‪string getHeaderLine(string $name)
Definition: Message.php:178
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getHeaderLineWithHostReturnsEmptyStringIfNoUriPresent
‪getHeaderLineWithHostReturnsEmptyStringIfNoUriPresent()
Definition: RequestTest.php:364
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\invalidRequestBodyDataProvider
‪static invalidRequestBodyDataProvider()
Definition: RequestTest.php:109
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\constructorCanAcceptAllMessageParts
‪constructorCanAcceptAllMessageParts()
Definition: RequestTest.php:75
‪TYPO3\CMS\Core\Http\Request\getUri
‪UriInterface getUri()
Definition: Request.php:285
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\validRequestTargetsDataProvider
‪static validRequestTargetsDataProvider()
Definition: RequestTest.php:238
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\constructorRaisesExceptionForInvalidMethodByString
‪constructorRaisesExceptionForInvalidMethodByString()
Definition: RequestTest.php:102
‪TYPO3\CMS\Core\Http\Request\withUri
‪withUri(UriInterface $uri, bool $preserveHost=false)
Definition: Request.php:320
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\requestsWithUriDataProvider
‪static requestsWithUriDataProvider()
Definition: RequestTest.php:199
‪TYPO3\CMS\Core\Http\Request\getMethod
‪getMethod()
Definition: Request.php:250
‪TYPO3\CMS\Core\Http\Uri
Definition: Uri.php:30
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\headersWithUpperAndLowerCaseValuesDataProvider
‪static headersWithUpperAndLowerCaseValuesDataProvider()
Definition: RequestTest.php:423
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\headerCanBeRetrieved
‪headerCanBeRetrieved($header, $value, $expected)
Definition: RequestTest.php:438
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getHeaderWithHostReturnsEmptyArrayIfNoUriPresent
‪getHeaderWithHostReturnsEmptyArrayIfNoUriPresent()
Definition: RequestTest.php:336
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getRequestTargetCanProvideARequestTarget
‪getRequestTargetCanProvideARequestTarget($requestTarget)
Definition: RequestTest.php:254
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\constructorRaisesExceptionForHeadersWithCRLFVectors
‪constructorRaisesExceptionForHeadersWithCRLFVectors($name, $value)
Definition: RequestTest.php:467
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\withRequestTargetCannotContainWhitespace
‪withRequestTargetCannotContainWhitespace()
Definition: RequestTest.php:263
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getHeadersContainsHostHeaderIfUriWithHostIsPresent
‪getHeadersContainsHostHeaderIfUriWithHostIsPresent()
Definition: RequestTest.php:295
‪TYPO3\CMS\Core\Http\Request\withRequestTarget
‪withRequestTarget(mixed $requestTarget)
Definition: Request.php:237
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getHeadersContainsNoHostHeaderIfNoUriPresent
‪getHeadersContainsNoHostHeaderIfNoUriPresent()
Definition: RequestTest.php:306
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\nonSupportedRequestMethodsRaisesException
‪nonSupportedRequestMethodsRaisesException()
Definition: RequestTest.php:485
‪TYPO3\CMS\Core\Http\Stream
Definition: Stream.php:31
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\supportedRequestMethodsWork
‪supportedRequestMethodsWork()
Definition: RequestTest.php:476
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\headersWithInjectionVectorsDataProvider
‪static headersWithInjectionVectorsDataProvider()
Definition: RequestTest.php:445
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getRequestTargetDoesNotCacheBetweenInstances
‪getRequestTargetDoesNotCacheBetweenInstances()
Definition: RequestTest.php:274
‪TYPO3\CMS\Core\Http\Request\getHeaders
‪array getHeaders()
Definition: Request.php:145
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getRequestTargetWhenUriIsPresent
‪getRequestTargetWhenUriIsPresent($request, $expected)
Definition: RequestTest.php:233
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\$request
‪Request $request
Definition: RequestTest.php:33
‪TYPO3\CMS\Core\Http\Request\withMethod
‪withMethod(string $method)
Definition: Request.php:269
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getHeaderLineWithHostReturnsEmptyStringIfUriDoesNotContainHost
‪getHeaderLineWithHostReturnsEmptyStringIfUriDoesNotContainHost()
Definition: RequestTest.php:373
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getHeaderWithHostReturnsUriHostWhenPresent
‪getHeaderWithHostReturnsUriHostWhenPresent()
Definition: RequestTest.php:326
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\constructorRaisesExceptionForInvalidBody
‪constructorRaisesExceptionForInvalidBody($body)
Definition: RequestTest.php:125
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getHeaderWithHostReturnsEmptyArrayIfUriDoesNotContainHost
‪getHeaderWithHostReturnsEmptyArrayIfUriDoesNotContainHost()
Definition: RequestTest.php:345
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getHeaderLineWithHostReturnsUriHostWhenPresent
‪getHeaderLineWithHostReturnsUriHostWhenPresent()
Definition: RequestTest.php:354
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getHeaderLineWithHostTakesPrecedenceOverModifiedUri
‪getHeaderLineWithHostTakesPrecedenceOverModifiedUri()
Definition: RequestTest.php:382
‪TYPO3\CMS\Core\Http\Request\getHeader
‪string[] getHeader(string $name)
Definition: Request.php:168
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\withUriReturnsNewInstanceWithNewUri
‪withUriReturnsNewInstanceWithNewUri()
Definition: RequestTest.php:62
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\constructorDoesNotRaiseExceptionForValidBody
‪constructorDoesNotRaiseExceptionForValidBody($body)
Definition: RequestTest.php:147
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\constructorIgnoresInvalidHeaders
‪constructorIgnoresInvalidHeaders()
Definition: RequestTest.php:155
‪TYPO3\CMS\Core\Http\Request
Definition: Request.php:35
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getRequestTargetIsSlashWhenNoUriPresent
‪getRequestTargetIsSlashWhenNoUriPresent()
Definition: RequestTest.php:183
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\validRequestBodyDataProvider
‪static validRequestBodyDataProvider()
Definition: RequestTest.php:132
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getMethodMutatorReturnsCloneWithChangedMethod
‪getMethodMutatorReturnsCloneWithChangedMethod()
Definition: RequestTest.php:52
‪TYPO3\CMS\Core\Tests\Unit\Http\RequestTest\getHeaderLineWithHostTakesPrecedenceOverEmptyUri
‪getHeaderLineWithHostTakesPrecedenceOverEmptyUri()
Definition: RequestTest.php:396