‪TYPO3CMS  ‪main
RedirectServiceTest.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 PHPUnit\Framework\Attributes\DataProvider;
21 use PHPUnit\Framework\Attributes\Test;
22 use Psr\EventDispatcher\EventDispatcherInterface;
23 use Psr\Log\NullLogger;
24 use Symfony\Component\DependencyInjection\Container;
37 use TYPO3\CMS\Core\TypoScript\FrontendTypoScriptFactory;
44 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
45 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
46 
47 final class ‪RedirectServiceTest extends FunctionalTestCase
48 {
50 
51  protected const ‪LANGUAGE_PRESETS = [
52  'EN' => ['id' => 0, 'title' => 'English', 'locale' => 'en_US.UTF8'],
53  ];
54 
55  protected array ‪$coreExtensionsToLoad = ['redirects'];
56 
57  protected array ‪$testExtensionsToLoad = [
58  'typo3/sysext/redirects/Tests/Functional/Fixtures/Extensions/test_bolt',
59  ];
60 
61  protected array ‪$configurationToUseInTestInstance = [
62  'FE' => [
63  'cacheHash' => [
64  'excludedParameters' => ['L', 'pk_campaign', 'pk_kwd', 'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'gclid', 'fbclid', 'msclkid'],
65  // @todo this should be tested explicitly - enabled and disabled
66  'enforceValidation' => false,
67  ],
68  ],
69  ];
70 
71  protected function ‪setUp(): void
72  {
73  parent::setUp();
74  $this->importCSVDataSet(__DIR__ . '/Fixtures/be_users.csv');
75  $this->setUpBackendUser(1);
76  }
77 
78  #[Test]
80  {
81  $this->importCSVDataSet(__DIR__ . '/Fixtures/RedirectToAccessRestrictedPages.csv');
82 
84  'acme-com',
85  $this->‪buildSiteConfiguration(1, 'https://acme.com/')
86  );
87 
88  $this->setUpFrontendRootPage(1, ['EXT:redirects/Tests/Functional/Service/Fixtures/Redirects.typoscript']);
89 
90  $logger = new NullLogger();
91  $frontendUserAuthentication = new ‪FrontendUserAuthentication();
92  $frontendUserAuthentication->setLogger($logger);
93 
94  $siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
95  $uri = new ‪Uri('https://acme.com/redirect-to-access-restricted-site');
96  $request = ‪$GLOBALS['TYPO3_REQUEST'] = (new ‪ServerRequest($uri))
97  ->withAttribute('site', $siteFinder->getSiteByRootPageId(1))
98  ->withAttribute('frontend.user', $frontendUserAuthentication)
99  ->withAttribute('applicationType', ‪SystemEnvironmentBuilder::REQUESTTYPE_FE);
100 
101  $linkServiceMock = $this->getMockBuilder(LinkService::class)->disableOriginalConstructor()->getMock();
102  $linkServiceMock->method('resolve')->with('t3://page?uid=2')->willReturn(
103  [
104  'pageuid' => 2,
105  'type' => ‪LinkService::TYPE_PAGE,
106  ]
107  );
108 
110  $typoScriptCache = $this->get(CacheManager::class)->getCache('typoscript');
111  $redirectService = new ‪RedirectService(
113  $linkServiceMock,
114  $siteFinder,
116  $this->get(PageInformationFactory::class),
117  $this->get(FrontendTypoScriptFactory::class),
118  $typoScriptCache,
119  $this->get(LogManager::class)->getLogger('Testing'),
120  );
121 
122  // Assert correct redirect is matched
123  $redirectMatch = $redirectService->matchRedirect($uri->getHost(), $uri->getPath(), $uri->getQuery());
124  self::assertEquals(1, $redirectMatch['uid']);
125  self::assertEquals('t3://page?uid=2', $redirectMatch['target']);
126 
127  // Ensure we deal with an unauthorized request!
128  self::assertFalse(GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('frontend.user', 'isLoggedIn'));
129 
130  // Assert link to access restricted page is build
131  ‪$targetUrl = $redirectService->getTargetUrl($redirectMatch, $request);
132  self::assertEquals(new ‪Uri('https://acme.com/access-restricted'), ‪$targetUrl);
133  }
134 
135  public static function ‪redirectsDataProvider(): array
136  {
137  return [
138  [
139  'https://acme.com/redirect-301',
140  301,
141  'https://acme.com/',
142  1,
143  ],
144  [
145  'https://acme.com/redirect-308',
146  308,
147  'https://acme.com/page2',
148  2,
149  ],
150  [
151  'https://acme.com/redirect-302',
152  302,
153  'https://www.typo3.org',
154  3,
155  ],
156  ];
157  }
158 
159  #[DataProvider('redirectsDataProvider')]
160  #[Test]
161  public function ‪checkReponseCodeOnRedirect(‪$url, ‪$statusCode, ‪$targetUrl, $redirectUid): void
162  {
163  $this->importCSVDataSet(__DIR__ . '/Fixtures/RedirectToPages.csv');
164 
166  'acme-com',
167  $this->‪buildSiteConfiguration(1, 'https://acme.com/')
168  );
169 
170  $this->setUpFrontendRootPage(
171  1,
172  ['EXT:redirects/Tests/Functional/Service/Fixtures/Redirects.typoscript']
173  );
174 
175  $response = $this->executeFrontendSubRequest(
176  new InternalRequest(‪$url)
177  );
178  self::assertEquals(‪$statusCode, $response->getStatusCode());
179  self::assertIsArray($response->getHeader('X-Redirect-By'));
180  self::assertIsArray($response->getHeader('location'));
181  self::assertEquals('TYPO3 Redirect ' . $redirectUid, $response->getHeader('X-Redirect-By')[0]);
182  self::assertEquals(‪$targetUrl, $response->getHeader('location')[0]);
183  }
184 
185  public static function ‪checkRegExpRedirectsDataProvider(): array
186  {
187  return [
188  'regexp redirect respecting query parameter but not keeping them' => [
189  'https://acme.com/index.php?option=com_content&page=some_page',
190  301,
191  'https://anotherdomain.com/some_page',
192  1,
193  ],
194  'regexp redirect respecting query parameter and keeping them' => [
195  'https://acme.com/index.php?option=com_content2&page=some_page',
196  301,
197  'https://anotherdomain.com/some_page?option=com_content2&page=some_page',
198  2,
199  ],
200  'regexp redirect not respecting query parameters and not keeping them' => [
201  'https://acme.com/some-old-page-others?option=com_content',
202  301,
203  'https://anotherdomain.com/others',
204  3,
205  ],
206  'regexp redirect not respecting query parameters but keeping them' => [
207  'https://acme.com/some-page-others',
208  301,
209  'https://anotherdomain.com/others',
210  4,
211  ],
212  'regexp redirect not respecting query parameters and not keeping them, with query parameter in request' => [
213  'https://acme.com/some-old-page-others?option=com_content',
214  301,
215  'https://anotherdomain.com/others',
216  3,
217  ],
218  'regexp redirect not respecting query parameters but keeping them, without query parameter in request' => [
219  'https://acme.com/some-page-others',
220  301,
221  'https://anotherdomain.com/others',
222  4,
223  ],
224  // check against unsafe regexp captching group
225  'regexp redirect with unsafe captching group, respecting query parameters and not keeping them, with query parameter in request' => [
226  'https://acme.com/unsafe-captchinggroup-matching-queryparameters-others?option=com_content',
227  301,
228  'https://anotherdomain.com/others',
229  5,
230  ],
231  // checks against unsafe regexp captching group, but as keeping query parameters this may be undetected,
232  // and as such this test acts as counterpart to tests above
233  'regexp redirect with unsafe captching group, respecting query parameters but keeping them, with query parameter in request' => [
234  'https://acme.com/another-unsafe-captchinggroup-matching-queryparameters-others?option=com_content',
235  301,
236  'https://anotherdomain.com/others?option=com_content',
237  6,
238  ],
239  // check against safe regexp captching group
240  'regexp redirect safe captching group, respecting query parameters and not keeping them, with query parameter in request' => [
241  'https://acme.com/safe-captchinggroup-not-matching-queryparameters-others?option=com_content',
242  301,
243  'https://anotherdomain.com/others',
244  7,
245  ],
246  // checks against safe regexp captching group
247  'regexp redirect safe captching group, respecting query parameters but keeping them, with query parameter in request' => [
248  'https://acme.com/another-safe-captchinggroup-not-matching-queryparameters-others?option=com_content',
249  301,
250  'https://anotherdomain.com/others?option=com_content',
251  8,
252  ],
253  // check against more safe regexp captching group - this tests path fallback even with queryparameters in
254  // request for non query regexp with $ as end matching in regexp
255  'regexp redirect safe captching group, not respecting query parameters and not keeping them, with query parameter in request' => [
256  'https://acme.com/more-safe-captchinggroup-not-matching-queryparameters-others?option=com_content',
257  301,
258  'https://anotherdomain.com/others',
259  9,
260  ],
261  'regexp redirect safe captching group, not respecting query parameters but keeping them, with query parameter in request' => [
262  'https://acme.com/another-more-safe-captchinggroup-not-matching-queryparameters-others?option=com_content',
263  301,
264  'https://anotherdomain.com/others?option=com_content',
265  10,
266  ],
267  'regexp capture group with relative target' => [
268  'https://acme.com/relative-target-page2',
269  301,
270  '/page2',
271  11,
272  ],
273  'regexp capture group with relative target - keep query params' => [
274  'https://acme.com/relative-target-keep-page2?param1=value1',
275  301,
276  '/page2?param1=value1',
277  12,
278  ],
279  'regexp capture group with relative target - respect query param' => [
280  'https://acme.com/respect-relative-target-page2?param1=subpage',
281  301,
282  '/page2/subpage',
283  13,
284  ],
285  'regexp capture group with relative target - respect query param and keep them' => [
286  'https://acme.com/respect-keep-relative-target-page2?param1=subpage',
287  301,
288  '/page2/subpage?param1=subpage',
289  14,
290  ],
291  // test for https://forge.typo3.org/issues/89799#note-14
292  'regexp relative target redirect with unsafe regexp and without ending $' => [
293  'https://acme.com/other-relative-target-with-unsafe-capture-group-new',
294  301,
295  '/offer-new',
296  15,
297  ],
298  // test for https://forge.typo3.org/issues/89799#note-14
299  'regexp redirect with unsafe regexp and without ending $' => [
300  'https://acme.com/other-redirect-with-unsafe-capture-group-new',
301  301,
302  'https://anotherdomain.com/offernew',
303  16,
304  ],
305  ];
306  }
307 
308  #[DataProvider('checkRegExpRedirectsDataProvider')]
309  #[Test]
310  public function ‪checkRegExpRedirects(string ‪$url, int $expectedStatusCode, string $expectedRedirectUri, int $expectedRedirectUid)
311  {
312  $this->importCSVDataSet(__DIR__ . '/Fixtures/RedirectService_regexp.csv');
314  'acme-com',
315  $this->‪buildSiteConfiguration(1, 'https://acme.com/')
316  );
317  $this->setUpFrontendRootPage(
318  1,
319  ['EXT:redirects/Tests/Functional/Service/Fixtures/Redirects.typoscript']
320  );
321 
322  $response = $this->executeFrontendSubRequest(
323  new InternalRequest(‪$url),
324  null,
325  false
326  );
327  self::assertEquals($expectedStatusCode, $response->getStatusCode());
328  self::assertIsArray($response->getHeader('X-Redirect-By'));
329  self::assertIsArray($response->getHeader('location'));
330  self::assertEquals('TYPO3 Redirect ' . $expectedRedirectUid, $response->getHeader('X-Redirect-By')[0]);
331  self::assertEquals($expectedRedirectUri, $response->getHeader('location')[0]);
332  }
333 
337  #[Test]
339  {
340  ‪$url = 'https://acme.com/regexp-respect-get-parameter?param1=value1';
341  $expectedStatusCode = 404;
342  $this->importCSVDataSet(__DIR__ . '/Fixtures/RedirectService_regexp.csv');
344  'acme-com',
345  $this->‪buildSiteConfiguration(1, 'https://acme.com/')
346  );
347  $this->setUpFrontendRootPage(
348  1,
349  ['EXT:redirects/Tests/Functional/Service/Fixtures/Redirects.typoscript']
350  );
351 
352  $response = $this->executeFrontendSubRequest(
353  new InternalRequest(‪$url),
354  null,
355  false
356  );
357  self::assertSame($expectedStatusCode, $response->getStatusCode());
358  }
359 
363  #[Test]
365  {
366  ‪$url = 'https://acme.com/regexp-respect-get-parameter';
367  $expectedStatusCode = 301;
368  $expectedRedirectUid = 17;
369  $expectedRedirectUri = 'https://anotherdomain.com/regexp-respect-get-parameter';
370  $this->importCSVDataSet(__DIR__ . '/Fixtures/RedirectService_regexp.csv');
372  'acme-com',
373  $this->‪buildSiteConfiguration(1, 'https://acme.com/')
374  );
375  $this->setUpFrontendRootPage(
376  1,
377  ['EXT:redirects/Tests/Functional/Service/Fixtures/Redirects.typoscript']
378  );
379 
380  $response = $this->executeFrontendSubRequest(
381  new InternalRequest(‪$url),
382  null,
383  false
384  );
385  self::assertSame($expectedStatusCode, $response->getStatusCode());
386  self::assertIsArray($response->getHeader('X-Redirect-By'));
387  self::assertIsArray($response->getHeader('location'));
388  self::assertSame('TYPO3 Redirect ' . $expectedRedirectUid, $response->getHeader('X-Redirect-By')[0]);
389  self::assertSame($expectedRedirectUri, $response->getHeader('location')[0]);
390  }
391 
392  public static function ‪samePathWithSameDomainT3TargetDataProvider(): array
393  {
394  return [
395  'flat' => [
396  'https://acme.com/flat-samehost-1',
397  'https://acme.com/',
398  200,
399  null,
400  null,
401  ],
402  // this should redirect and not pass through
403  'flat - with query parameters' => [
404  'https://acme.com/flat-samehost-1?param1=value1&cHash=e0527192caa60a6dac1e30af7cfeaf64',
405  'https://acme.com/',
406  301,
407  'https://acme.com/flat-samehost-1',
408  1,
409  ],
410  'flat keep_query_parameters' => [
411  'https://acme.com/flat-samehost-2',
412  'https://acme.com/',
413  200,
414  null,
415  null,
416  ],
417  'flat keep_query_parameters - with query parameters' => [
418  'https://acme.com/flat-samehost-2?param1=value1&cHash=e0527192caa60a6dac1e30af7cfeaf64',
419  'https://acme.com/',
420  200,
421  null,
422  null,
423  ],
424  'flat respect_query_parameters' => [
425  'https://acme.com/flat-samehost-3',
426  'https://acme.com/',
427  200,
428  null,
429  null,
430  ],
431  // this should redirect and not pass through
432  'flat respect_query_parameters - with query parameters' => [
433  'https://acme.com/flat-samehost-3?param1=value1',
434  'https://acme.com/',
435  301,
436  'https://acme.com/flat-samehost-3',
437  3,
438  ],
439  'flat respect_query_parameters and keep_query_parameters' => [
440  'https://acme.com/flat-samehost-4',
441  'https://acme.com/',
442  200,
443  null,
444  null,
445  ],
446  'flat respect_query_parameters and keep_query_parameters - with query parameters' => [
447  'https://acme.com/flat-samehost-4?param1=value1&cHash=caa2156411affc2d7c8c5169652c6e13',
448  'https://acme.com/',
449  200,
450  null,
451  null,
452  ],
453  'regexp' => [
454  'https://acme.com/regexp-samehost-1',
455  'https://acme.com/',
456  200,
457  null,
458  null,
459  ],
460  // this should redirect and not pass through
461  'regexp - with query parameters' => [
462  'https://acme.com/regexp-samehost-1?param1=value1',
463  'https://acme.com/',
464  301,
465  'https://acme.com/regexp-samehost-1',
466  5,
467  ],
468  'regexp keep_query_parameters' => [
469  'https://acme.com/regexp-samehost-2',
470  'https://acme.com/',
471  200,
472  null,
473  null,
474  ],
475  'regexp keep_query_parameters - with query parameters' => [
476  'https://acme.com/regexp-samehost-2?param1=value1&cHash=feced69fa13ce7d3bf0483c21ff03064',
477  'https://acme.com/',
478  200,
479  null,
480  null,
481  ],
482  // this should redirect and not pass through
483  'regexp keep_query_parameters - with query parameters but without cHash' => [
484  'https://acme.com/regexp-samehost-2?param1=value1',
485  'https://acme.com/',
486  301,
487  'https://acme.com/regexp-samehost-2?param1=value1&cHash=feced69fa13ce7d3bf0483c21ff03064',
488  6,
489  ],
490  'regexp respect_query_parameters' => [
491  'https://acme.com/regexp-samehost-3',
492  'https://acme.com/',
493  200,
494  null,
495  null,
496  ],
497  // this should redirect and not pass through
498  'regexp respect_query_parameters - with query parameters but without cHash' => [
499  'https://acme.com/regexp-samehost-3?param1=value1',
500  'https://acme.com/',
501  301,
502  'https://acme.com/regexp-samehost-3',
503  7,
504  ],
505  'same host as external target with query arguments in another order than target should pass instead of redirect' => [
506  'https://acme.com/sanatize-samehost-3?param1=value1&param2=value2&param3=&cHash=69f1b01feb7ed14b95b85cbc66ee2a3a',
507  'https://acme.com/',
508  200,
509  null,
510  null,
511  ],
512  'same host as external target with fragment should pass instead of redirect' => [
513  'https://acme.com/sanatize-samehost-4',
514  'https://acme.com/',
515  200,
516  null,
517  null,
518  ],
519  ];
520  }
521 
522  #[DataProvider('samePathWithSameDomainT3TargetDataProvider')]
523  #[Test]
524  public function ‪samePathWithSameDomainT3Target(string ‪$url, string $baseUri, int $expectedStatusCode, ?string $expectedRedirectUri, ?int $expectedRedirectUid): void
525  {
526  $this->importCSVDataSet(__DIR__ . '/Fixtures/RedirectService_samePathWithSameDomainT3Target.csv');
528  'acme-com',
529  $this->‪buildSiteConfiguration(1, $baseUri)
530  );
531  $this->setUpFrontendRootPage(
532  1,
533  ['EXT:redirects/Tests/Functional/Service/Fixtures/Redirects.typoscript']
534  );
535 
536  $response = $this->executeFrontendSubRequest(
537  new InternalRequest(‪$url),
538  null,
539  false
540  );
541  self::assertEquals($expectedStatusCode, $response->getStatusCode());
542  if ($expectedRedirectUri) {
543  self::assertIsArray($response->getHeader('X-Redirect-By'));
544  self::assertIsArray($response->getHeader('location'));
545  self::assertEquals('TYPO3 Redirect ' . $expectedRedirectUid, $response->getHeader('X-Redirect-By')[0]);
546  self::assertEquals($expectedRedirectUri, $response->getHeader('location')[0]);
547  }
548  }
549 
550  public static function ‪samePathWithSameDomainAndRelativeTargetDataProvider(): array
551  {
552  return [
553  'flat' => [
554  'https://acme.com/flat-samehost-1',
555  'https://acme.com/',
556  200,
557  null,
558  null,
559  ],
560  // this should redirect and not pass through
561  'flat - with query parameters' => [
562  'https://acme.com/flat-samehost-1?param1=value1&cHash=e0527192caa60a6dac1e30af7cfeaf64',
563  'https://acme.com/',
564  301,
565  '/flat-samehost-1',
566  1,
567  ],
568  'flat keep_query_parameters' => [
569  'https://acme.com/flat-samehost-2',
570  'https://acme.com/',
571  200,
572  null,
573  null,
574  ],
575  'flat keep_query_parameters - with query parameters' => [
576  'https://acme.com/flat-samehost-2?param1=value1&cHash=e0527192caa60a6dac1e30af7cfeaf64',
577  'https://acme.com/',
578  200,
579  null,
580  null,
581  ],
582  'flat respect_query_parameters' => [
583  'https://acme.com/flat-samehost-3',
584  'https://acme.com/',
585  200,
586  null,
587  null,
588  ],
589  // this should redirect and not pass through
590  'flat respect_query_parameters - with query parameters' => [
591  'https://acme.com/flat-samehost-3?param1=value1',
592  'https://acme.com/',
593  301,
594  '/flat-samehost-3',
595  3,
596  ],
597  'flat respect_query_parameters and keep_query_parameters' => [
598  'https://acme.com/flat-samehost-4',
599  'https://acme.com/',
600  200,
601  null,
602  null,
603  ],
604  'flat respect_query_parameters and keep_query_parameters - with query parameters' => [
605  'https://acme.com/flat-samehost-4?param1=value1&cHash=caa2156411affc2d7c8c5169652c6e13',
606  'https://acme.com/',
607  200,
608  null,
609  null,
610  ],
611  'regexp' => [
612  'https://acme.com/regexp-samehost-1',
613  'https://acme.com/',
614  200,
615  null,
616  null,
617  ],
618  // this should redirect and not pass through
619  'regexp - with query parameters' => [
620  'https://acme.com/regexp-samehost-1?param1=value1',
621  'https://acme.com/',
622  301,
623  '/regexp-samehost-1',
624  5,
625  ],
626  'regexp keep_query_parameters' => [
627  'https://acme.com/regexp-samehost-2',
628  'https://acme.com/',
629  200,
630  null,
631  null,
632  ],
633  'regexp keep_query_parameters - with query parameters' => [
634  'https://acme.com/regexp-samehost-2?param1=value1&cHash=feced69fa13ce7d3bf0483c21ff03064',
635  'https://acme.com/',
636  200,
637  null,
638  null,
639  ],
640  'regexp keep_query_parameters - with query parameters but without cHash' => [
641  'https://acme.com/regexp-samehost-2?param1=value1',
642  'https://acme.com/',
643  200,
644  null,
645  null,
646  ],
647  'regexp respect_query_parameters' => [
648  'https://acme.com/regexp-samehost-3',
649  'https://acme.com/',
650  200,
651  null,
652  null,
653  ],
654  // this should redirect and not pass through
655  'regexp respect_query_parameters - with query parameters but without cHash' => [
656  'https://acme.com/regexp-samehost-3?param1=value1',
657  'https://acme.com/',
658  301,
659  '/regexp-samehost-3',
660  7,
661  ],
662  ];
663  }
664 
665  #[DataProvider('samePathWithSameDomainAndRelativeTargetDataProvider')]
666  #[Test]
667  public function ‪samePathWithSameDomainAndRelativeTarget(string ‪$url, string $baseUri, int $expectedStatusCode, ?string $expectedRedirectUri, ?int $expectedRedirectUid): void
668  {
669  $this->importCSVDataSet(__DIR__ . '/Fixtures/RedirectService_samePathWithSameDomainAndRelativeTarget.csv');
671  'acme-com',
672  $this->‪buildSiteConfiguration(1, $baseUri)
673  );
674  $this->setUpFrontendRootPage(
675  1,
676  ['EXT:redirects/Tests/Functional/Service/Fixtures/Redirects.typoscript']
677  );
678 
679  $response = $this->executeFrontendSubRequest(
680  new InternalRequest(‪$url),
681  null,
682  false
683  );
684  self::assertEquals($expectedStatusCode, $response->getStatusCode());
685  if ($expectedRedirectUri) {
686  self::assertIsArray($response->getHeader('X-Redirect-By'));
687  self::assertIsArray($response->getHeader('location'));
688  self::assertEquals('TYPO3 Redirect ' . $expectedRedirectUid, $response->getHeader('X-Redirect-By')[0]);
689  self::assertEquals($expectedRedirectUri, $response->getHeader('location')[0]);
690  }
691  }
692 
693  public static function ‪samePathRedirectsWithExternalTargetDataProvider(): array
694  {
695  return [
696  'flat' => [
697  'https://acme.com/flat-samehost-1',
698  'https://acme.com/',
699  301,
700  'https://external.acme.com/flat-samehost-1',
701  1,
702  ],
703  'flat - with query parameters' => [
704  'https://acme.com/flat-samehost-1?param1=value1&cHash=e0527192caa60a6dac1e30af7cfeaf64',
705  'https://acme.com/',
706  301,
707  'https://external.acme.com/flat-samehost-1',
708  1,
709  ],
710  'flat keep_query_parameters' => [
711  'https://acme.com/flat-samehost-2',
712  'https://acme.com/',
713  301,
714  'https://external.acme.com/flat-samehost-2',
715  2,
716  ],
717  'flat keep_query_parameters - with query parameters' => [
718  'https://acme.com/flat-samehost-2?param1=value1',
719  'https://acme.com/',
720  301,
721  'https://external.acme.com/flat-samehost-2?param1=value1',
722  2,
723  ],
724  // following will not match at all, so it is expected to be resolved with 200
725  'flat respect_query_parameters' => [
726  'https://acme.com/flat-samehost-3',
727  'https://acme.com/',
728  200,
729  null,
730  null,
731  ],
732  'flat respect_query_parameters - with query parameters' => [
733  'https://acme.com/flat-samehost-3?param1=value1',
734  'https://acme.com/',
735  301,
736  'https://external.acme.com/flat-samehost-3',
737  3,
738  ],
739  // following will not match at all, so it is expected to be resolved with 200
740  'flat respect_query_parameters and keep_query_parameters' => [
741  'https://acme.com/flat-samehost-4',
742  'https://acme.com/',
743  200,
744  null,
745  null,
746  ],
747  'flat respect_query_parameters and keep_query_parameters - with query parameters' => [
748  'https://acme.com/flat-samehost-4?param1=value1',
749  'https://acme.com/',
750  301,
751  'https://external.acme.com/flat-samehost-4?param1=value1',
752  4,
753  ],
754  'regexp' => [
755  'https://acme.com/regexp-samehost-1',
756  'https://acme.com/',
757  301,
758  'https://external.acme.com/regexp-samehost-1',
759  5,
760  ],
761  'regexp - with query parameters' => [
762  'https://acme.com/regexp-samehost-1?param1=value1',
763  'https://acme.com/',
764  301,
765  'https://external.acme.com/regexp-samehost-1',
766  5,
767  ],
768  'regexp keep_query_parameters' => [
769  'https://acme.com/regexp-samehost-2',
770  'https://acme.com/',
771  301,
772  'https://external.acme.com/regexp-samehost-2',
773  6,
774  ],
775  'regexp keep_query_parameters - with query parameters' => [
776  'https://acme.com/regexp-samehost-2?param1=value1',
777  'https://acme.com/',
778  301,
779  'https://external.acme.com/regexp-samehost-2?param1=value1',
780  6,
781  ],
782  'regexp respect_query_parameters' => [
783  'https://acme.com/regexp-samehost-3',
784  'https://acme.com/',
785  301,
786  'https://external.acme.com/regexp-samehost-3',
787  7,
788  ],
789  // this should redirect and not pass through
790  'regexp respect_query_parameters - with query parameters but without cHash' => [
791  'https://acme.com/regexp-samehost-3?param1=value1',
792  'https://acme.com/',
793  301,
794  'https://external.acme.com/regexp-samehost-3',
795  7,
796  ],
797  'same host as external target with port should pass instead of redirect' => [
798  'https://acme.com/sanatize-samehost-1',
799  'https://acme.com/',
800  200,
801  null,
802  null,
803  ],
804  'same host as external target with userinfo should pass instead of redirect' => [
805  'https://acme.com/sanatize-samehost-2',
806  'https://acme.com/',
807  200,
808  null,
809  null,
810  ],
811  'same host as external target with query arguments in another order than target should pass instead of redirect' => [
812  'https://acme.com/sanatize-samehost-3?param1=value1&param2=value2&param3=',
813  'https://acme.com/',
814  200,
815  null,
816  null,
817  ],
818  'same host as external target with fragment should pass instead of redirect' => [
819  'https://acme.com/sanatize-samehost-4',
820  'https://acme.com/',
821  200,
822  null,
823  null,
824  ],
825  ];
826  }
827 
828  #[DataProvider('samePathRedirectsWithExternalTargetDataProvider')]
829  #[Test]
830  public function ‪samePathRedirectsWithExternalTarget(string ‪$url, string $baseUri, int $expectedStatusCode, ?string $expectedRedirectUri, ?int $expectedRedirectUid): void
831  {
832  $this->importCSVDataSet(__DIR__ . '/Fixtures/RedirectService_samePathRedirectsWithExternalTarget.csv');
834  'acme-com',
835  $this->‪buildSiteConfiguration(1, $baseUri)
836  );
837  $this->setUpFrontendRootPage(
838  1,
839  ['EXT:redirects/Tests/Functional/Service/Fixtures/Redirects.typoscript']
840  );
841 
842  $response = $this->executeFrontendSubRequest(
843  new InternalRequest(‪$url),
844  null,
845  false
846  );
847  self::assertEquals($expectedStatusCode, $response->getStatusCode());
848  if ($expectedRedirectUri) {
849  self::assertIsArray($response->getHeader('X-Redirect-By'));
850  self::assertIsArray($response->getHeader('location'));
851  self::assertEquals('TYPO3 Redirect ' . $expectedRedirectUid, $response->getHeader('X-Redirect-By')[0]);
852  self::assertEquals($expectedRedirectUri, $response->getHeader('location')[0]);
853  }
854  }
855 
856  #[Test]
857  public function ‪beforeRedirectMatchDomainEventIsTriggered(): void
858  {
859  $this->importCSVDataSet(__DIR__ . '/Fixtures/BeforeRedirectMatchDomainEventIsTriggered.csv');
861  'acme-com',
862  $this->‪buildSiteConfiguration(1, 'https://acme.com/')
863  );
864 
865  $frontendUserAuthentication = new ‪FrontendUserAuthentication();
866 
867  $siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
868  $uri = new ‪Uri('https://acme.com/non-existing-page');
869  ‪$GLOBALS['TYPO3_REQUEST'] = (new ‪ServerRequest($uri))
870  ->withAttribute('site', $siteFinder->getSiteByRootPageId(1))
871  ->withAttribute('frontend.user', $frontendUserAuthentication)
872  ->withAttribute('applicationType', ‪SystemEnvironmentBuilder::REQUESTTYPE_FE);
873 
875  $dispatchedEvents = [];
877  $container = $this->get('service_container');
878  $container->set(
879  'before-redirect-match-domain-event-is-triggered',
880  static function (‪BeforeRedirectMatchDomainEvent $event) use (&$dispatchedEvents): void {
881  $dispatchedEvents[] = $event;
882  if ($event->‪getMatchDomainName() === '*') {
883  $event->‪setMatchedRedirect(['wildcard-manual-matched' => $event->‪getPath()]);
884  }
885  }
886  );
887 
888  $eventListener = $container->get(ListenerProvider::class);
889  $eventListener->addListener(BeforeRedirectMatchDomainEvent::class, 'before-redirect-match-domain-event-is-triggered');
890 
892  $typoScriptCache = $this->get(CacheManager::class)->getCache('typoscript');
893  $redirectService = new ‪RedirectService(
895  new ‪LinkService(),
896  $siteFinder,
897  $this->get(EventDispatcherInterface::class),
898  $this->get(PageInformationFactory::class),
899  $this->get(FrontendTypoScriptFactory::class),
900  $typoScriptCache,
901  $this->get(LogManager::class)->getLogger('Testing'),
902  );
903 
904  $redirectMatch = $redirectService->matchRedirect($uri->getHost(), $uri->getPath(), $uri->getQuery());
905 
906  self::assertCount(2, $dispatchedEvents);
907  self::assertNull($dispatchedEvents[0]->getMatchedRedirect());
908  self::assertEquals(['wildcard-manual-matched' => $uri->getPath()], $dispatchedEvents[1]->getMatchedRedirect());
909  self::assertSame(['wildcard-manual-matched' => $uri->getPath()], $redirectMatch);
910  }
911 
913  {
914  // Regression test for https://forge.typo3.org/issues/101191
915  yield '#1 Non-query argument regex redirect not respecting get arguments before query-argument regex does not match before query-argument regex' => [
916  'importDataSet' => __DIR__ . '/Fixtures/RegExp/case1.csv',
917  'url' => 'https://acme.com/foo/lightbar.html?type=101',
918  'statusCode' => 301,
919  'redirectUid' => 2,
920  'targetUrl' => 'https://acme.com/page3?type=101',
921  ];
922 
923  yield '#2 Non-query argument regex redirect respecting get arguments before query-argument regex does not match before query-argument regex' => [
924  'importDataSet' => __DIR__ . '/Fixtures/RegExp/case2.csv',
925  'url' => 'https://acme.com/foo/lightbar.html?type=101',
926  'statusCode' => 301,
927  'redirectUid' => 2,
928  'targetUrl' => 'https://acme.com/page3?type=101',
929  ];
930 
931  // Redirect respecting query arguments but has a too open regexp provided and matching takes precedence over
932  // a later redirect with a "better" match. This is a configuration error and therefore the correct way to handle
933  // this case. For example missing trailing `$` or leaving the `respect_query_parameters` option unchecked would
934  // mitigate this.
935  yield '#3 To open non-query argument regex redirect respecting get arguments before query-argument regex proceeds query-argument regex' => [
936  'importDataSet' => __DIR__ . '/Fixtures/RegExp/case3.csv',
937  'url' => 'https://acme.com/foo/lightbar.html?type=101',
938  'statusCode' => 301,
939  'redirectUid' => 1,
940  'targetUrl' => 'https://acme.com/page2',
941  ];
942  }
943 
944  #[DataProvider('regExpRedirectsWithArgumentMatchesWithSimilarRegExpWithoutQueryParamInRecordDataProvider')]
945  #[Test]
947  string $importDataSet,
948  string ‪$url,
949  int ‪$statusCode,
950  int $redirectUid,
951  string ‪$targetUrl
952  ): void {
953  $this->importCSVDataSet($importDataSet);
955  'acme-com',
956  $this->‪buildSiteConfiguration(1, 'https://acme.com/')
957  );
958  $this->setUpFrontendRootPage(
959  1,
960  ['EXT:redirects/Tests/Functional/Service/Fixtures/Redirects.typoscript']
961  );
962 
963  $response = $this->executeFrontendSubRequest(
964  new InternalRequest(‪$url)
965  );
966  self::assertEquals(‪$statusCode, $response->getStatusCode());
967  self::assertIsArray($response->getHeader('X-Redirect-By'));
968  self::assertIsArray($response->getHeader('location'));
969  self::assertEquals('TYPO3 Redirect ' . $redirectUid, $response->getHeader('X-Redirect-By')[0]);
970  self::assertEquals(‪$targetUrl, $response->getHeader('location')[0]);
971  }
972 
974  {
975  yield 'non-configured source_host with site rootpage target using T3 LinkHandler syntax' => [
976  'request' => new InternalRequest('https://non-configured.domain.tld/redirect-to-pid1'),
977  'rootPageTypoScriptFiles' => ['setup' => ['EXT:redirects/Tests/Functional/Service/Fixtures/Redirects.typoscript']],
978  'useTestBolt' => false,
979  'expectedRedirectStatusCode' => 301,
980  'expectedRedirectUid' => 1,
981  'expectedRedirectLocationUri' => 'https://acme.com/',
982  ];
983  yield 'non-configured source_host with site sub-page target using T3 LinkHandler syntax' => [
984  'request' => new InternalRequest('https://non-configured.domain.tld/redirect-to-pid2'),
985  'rootPageTypoScriptFiles' => ['setup' => ['EXT:redirects/Tests/Functional/Service/Fixtures/Redirects.typoscript']],
986  'useTestBolt' => false,
987  'expectedRedirectStatusCode' => 301,
988  'expectedRedirectUid' => 2,
989  'expectedRedirectLocationUri' => 'https://acme.com/page2',
990  ];
991  // Regression test for https://forge.typo3.org/issues/103395
992  yield 'non-configured source_host with site root target without typoscript using T3 LinkHandler syntax' => [
993  'request' => new InternalRequest('https://non-configured.domain.tld/redirect-to-pid1'),
994  'rootPageTypoScriptFiles' => ['setup' => ['EXT:redirects/Tests/Functional/Service/Fixtures/Redirects.typoscript']],
995  'useTestBolt' => true,
996  'expectedRedirectStatusCode' => 301,
997  'expectedRedirectUid' => 1,
998  'expectedRedirectLocationUri' => 'https://acme.com/',
999  ];
1000  // Not configured source host and matched redirect to external page
1001  yield 'non-configured source_host without tailing slash with external target without TypoScript using T3 LinkHandler syntax' => [
1002  'request' => new InternalRequest('https://non-configured.domain.tld/redirect-to-external'),
1003  'rootPageTypoScriptFiles' => ['setup' => ['EXT:redirects/Tests/Functional/Service/Fixtures/Redirects.typoscript']],
1004  'useTestBolt' => true,
1005  'expectedRedirectStatusCode' => 301,
1006  'expectedRedirectUid' => 3,
1007  'expectedRedirectLocationUri' => 'https://external.domain.tld/',
1008  ];
1009  yield 'non-configured source_host with tailing slash with external target without TypoScript using T3 LinkHandler syntax' => [
1010  'request' => new InternalRequest('https://non-configured.domain.tld/redirect-to-external/'),
1011  'rootPageTypoScriptFiles' => ['setup' => ['EXT:redirects/Tests/Functional/Service/Fixtures/Redirects.typoscript']],
1012  'useTestBolt' => true,
1013  'expectedRedirectStatusCode' => 301,
1014  'expectedRedirectUid' => 3,
1015  'expectedRedirectLocationUri' => 'https://external.domain.tld/',
1016  ];
1017  yield 'non-configured source_host without tailing slash with external target with using T3 LinkHandler syntax' => [
1018  'request' => new InternalRequest('https://non-configured.domain.tld/redirect-to-external'),
1019  'rootPageTypoScriptFiles' => ['setup' => ['EXT:redirects/Tests/Functional/Service/Fixtures/Redirects.typoscript']],
1020  'useTestBolt' => false,
1021  'expectedRedirectStatusCode' => 301,
1022  'expectedRedirectUid' => 3,
1023  'expectedRedirectLocationUri' => 'https://external.domain.tld/',
1024  ];
1025  yield 'non-configured source_host with tailing slash with external target with TypoScript using T3 LinkHandler syntax' => [
1026  'request' => new InternalRequest('https://non-configured.domain.tld/redirect-to-external/'),
1027  'rootPageTypoScriptFiles' => ['setup' => ['EXT:redirects/Tests/Functional/Service/Fixtures/Redirects.typoscript']],
1028  'useTestBolt' => false,
1029  'expectedRedirectStatusCode' => 301,
1030  'expectedRedirectUid' => 3,
1031  'expectedRedirectLocationUri' => 'https://external.domain.tld/',
1032  ];
1033  }
1034 
1038  #[DataProvider('sourceHostNotNotContainedInAnySiteConfigRedirectIsRedirectedDataProvider')]
1039  #[Test]
1041  InternalRequest $request,
1042  array $rootPageTypoScriptFiles,
1043  bool $useTestBolt,
1044  int $expectedRedirectStatusCode,
1045  int $expectedRedirectUid,
1046  string $expectedRedirectLocationUri,
1047  ): void {
1048  $this->importCSVDataSet(__DIR__ . '/Fixtures/SourceHostWithoutSourceConfigRedirect.csv');
1050  'acme-com',
1051  $this->‪buildSiteConfiguration(1, 'https://acme.com/')
1052  );
1053  if ($useTestBolt === true) {
1054  $constants = '';
1055  foreach ($rootPageTypoScriptFiles['constants'] ?? [] as $typoScriptFile) {
1056  if (!str_starts_with($typoScriptFile, 'EXT:')) {
1057  // @deprecated will be removed in version 8, use "EXT:" syntax instead
1058  $constants .= '<INCLUDE_TYPOSCRIPT: source="FILE:' . $typoScriptFile . '">' . LF;
1059  } else {
1060  $constants .= '@import \'' . $typoScriptFile . '\'' . LF;
1061  }
1062  }
1063  $setup = '';
1064  foreach ($rootPageTypoScriptFiles['setup'] ?? [] as $typoScriptFile) {
1065  if (!str_starts_with($typoScriptFile, 'EXT:')) {
1066  // @deprecated will be removed in version 8, use "EXT:" syntax instead
1067  $setup .= '<INCLUDE_TYPOSCRIPT: source="FILE:' . $typoScriptFile . '">' . LF;
1068  } else {
1069  $setup .= '@import \'' . $typoScriptFile . '\'' . LF;
1070  }
1071  }
1072  $this->‪mergeSiteConfiguration('acme-com', [
1073  'test_bolt_enabled' => true,
1074  'test_bolt_constants' => $constants,
1075  'test_bolt_setup' => $setup,
1076  ]);
1077  $connection = $this->getConnectionPool()->getConnectionForTable('pages');
1078  $connection->update(
1079  'pages',
1080  ['is_siteroot' => 1],
1081  ['uid' => 1]
1082  );
1083  } else {
1084  $this->setUpFrontendRootPage(1, $rootPageTypoScriptFiles);
1085  }
1086 
1087  $response = $this->executeFrontendSubRequest($request);
1088  self::assertEquals($expectedRedirectStatusCode, $response->getStatusCode());
1089  self::assertIsArray($response->getHeader('X-Redirect-By'));
1090  self::assertIsArray($response->getHeader('location'));
1091  self::assertEquals('TYPO3 Redirect ' . $expectedRedirectUid, $response->getHeader('X-Redirect-By')[0]);
1092  self::assertEquals($expectedRedirectLocationUri, $response->getHeader('location')[0]);
1093  }
1094 }
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\samePathRedirectsWithExternalTargetDataProvider
‪static samePathRedirectsWithExternalTargetDataProvider()
Definition: RedirectServiceTest.php:692
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\redirectsDataProvider
‪static redirectsDataProvider()
Definition: RedirectServiceTest.php:134
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\sourceHostNotNotContainedInAnySiteConfigRedirectIsRedirected
‪sourceHostNotNotContainedInAnySiteConfigRedirectIsRedirected(InternalRequest $request, array $rootPageTypoScriptFiles, bool $useTestBolt, int $expectedRedirectStatusCode, int $expectedRedirectUid, string $expectedRedirectLocationUri,)
Definition: RedirectServiceTest.php:1039
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\regexpWithNoParamRegexpAndRespectingGetParameteresRedirectsIfNoParamsAreGiven
‪regexpWithNoParamRegexpAndRespectingGetParameteresRedirectsIfNoParamsAreGiven()
Definition: RedirectServiceTest.php:363
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\samePathWithSameDomainT3TargetDataProvider
‪static samePathWithSameDomainT3TargetDataProvider()
Definition: RedirectServiceTest.php:391
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\linkForRedirectToAccessRestrictedPageIsBuild
‪linkForRedirectToAccessRestrictedPageIsBuild()
Definition: RedirectServiceTest.php:78
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\samePathWithSameDomainAndRelativeTargetDataProvider
‪static samePathWithSameDomainAndRelativeTargetDataProvider()
Definition: RedirectServiceTest.php:549
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\checkRegExpRedirects
‪checkRegExpRedirects(string $url, int $expectedStatusCode, string $expectedRedirectUri, int $expectedRedirectUid)
Definition: RedirectServiceTest.php:309
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder
Definition: SystemEnvironmentBuilder.php:41
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait
Definition: SiteBasedTestTrait.php:37
‪TYPO3\CMS\Core\Cache\Frontend\PhpFrontend
Definition: PhpFrontend.php:25
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\beforeRedirectMatchDomainEventIsTriggered
‪beforeRedirectMatchDomainEventIsTriggered()
Definition: RedirectServiceTest.php:856
‪TYPO3\CMS\Redirects\Event\BeforeRedirectMatchDomainEvent\getMatchDomainName
‪string getMatchDomainName()
Definition: BeforeRedirectMatchDomainEvent.php:65
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\writeSiteConfiguration
‪writeSiteConfiguration(string $identifier, array $site=[], array $languages=[], array $errorHandling=[])
Definition: SiteBasedTestTrait.php:50
‪TYPO3\CMS\Redirects\Service\RedirectService
Definition: RedirectService.php:54
‪TYPO3\CMS\Core\Site\SiteFinder
Definition: SiteFinder.php:31
‪TYPO3\CMS\Redirects\Message\$targetUrl
‪identifier readonly UriInterface $targetUrl
Definition: RedirectWasHitMessage.php:33
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildSiteConfiguration
‪buildSiteConfiguration(int $rootPageId, string $base='')
Definition: SiteBasedTestTrait.php:88
‪TYPO3\CMS\Redirects\Event\BeforeRedirectMatchDomainEvent\getPath
‪string getPath()
Definition: BeforeRedirectMatchDomainEvent.php:49
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\regExpRedirectsWithArgumentMatchesWithSimilarRegExpWithoutQueryParamInRecord
‪regExpRedirectsWithArgumentMatchesWithSimilarRegExpWithoutQueryParamInRecord(string $importDataSet, string $url, int $statusCode, int $redirectUid, string $targetUrl)
Definition: RedirectServiceTest.php:945
‪TYPO3\CMS\Redirects\Event\BeforeRedirectMatchDomainEvent\setMatchedRedirect
‪setMatchedRedirect(?array $matchedRedirect)
Definition: BeforeRedirectMatchDomainEvent.php:81
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\samePathRedirectsWithExternalTarget
‪samePathRedirectsWithExternalTarget(string $url, string $baseUri, int $expectedStatusCode, ?string $expectedRedirectUri, ?int $expectedRedirectUid)
Definition: RedirectServiceTest.php:829
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\$configurationToUseInTestInstance
‪array $configurationToUseInTestInstance
Definition: RedirectServiceTest.php:60
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:54
‪TYPO3\CMS\Core\Http\Uri
Definition: Uri.php:30
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\samePathWithSameDomainT3Target
‪samePathWithSameDomainT3Target(string $url, string $baseUri, int $expectedStatusCode, ?string $expectedRedirectUri, ?int $expectedRedirectUid)
Definition: RedirectServiceTest.php:523
‪TYPO3\CMS\Redirects\Service\RedirectCacheService
Definition: RedirectCacheService.php:34
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\LANGUAGE_PRESETS
‪const LANGUAGE_PRESETS
Definition: RedirectServiceTest.php:50
‪TYPO3\CMS\Redirects\Message\$statusCode
‪identifier readonly UriInterface readonly int $statusCode
Definition: RedirectWasHitMessage.php:34
‪TYPO3\CMS\Redirects\Tests\Functional\Service
Definition: IntegrityServiceTest.php:18
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\samePathWithSameDomainAndRelativeTarget
‪samePathWithSameDomainAndRelativeTarget(string $url, string $baseUri, int $expectedStatusCode, ?string $expectedRedirectUri, ?int $expectedRedirectUid)
Definition: RedirectServiceTest.php:666
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\checkRegExpRedirectsDataProvider
‪static checkRegExpRedirectsDataProvider()
Definition: RedirectServiceTest.php:184
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:36
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest
Definition: RedirectServiceTest.php:48
‪TYPO3\CMS\Core\Http\ServerRequest
Definition: ServerRequest.php:39
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\checkReponseCodeOnRedirect
‪checkReponseCodeOnRedirect($url, $statusCode, $targetUrl, $redirectUid)
Definition: RedirectServiceTest.php:160
‪TYPO3\CMS\Webhooks\Message\$url
‪identifier readonly UriInterface $url
Definition: LoginErrorOccurredMessage.php:36
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\regexpWithNoParamRegexpAndRespectingGetParameteresIssuesNotFoundStatusIfParamsAreGivenInUrl
‪regexpWithNoParamRegexpAndRespectingGetParameteresIssuesNotFoundStatusIfParamsAreGivenInUrl()
Definition: RedirectServiceTest.php:337
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\setUp
‪setUp()
Definition: RedirectServiceTest.php:70
‪TYPO3\CMS\Core\EventDispatcher\NoopEventDispatcher
Definition: NoopEventDispatcher.php:29
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Log\LogManager
Definition: LogManager.php:33
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\$testExtensionsToLoad
‪array $testExtensionsToLoad
Definition: RedirectServiceTest.php:56
‪TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication
Definition: FrontendUserAuthentication.php:33
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\$coreExtensionsToLoad
‪array $coreExtensionsToLoad
Definition: RedirectServiceTest.php:54
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\sourceHostNotNotContainedInAnySiteConfigRedirectIsRedirectedDataProvider
‪static sourceHostNotNotContainedInAnySiteConfigRedirectIsRedirectedDataProvider()
Definition: RedirectServiceTest.php:972
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\REQUESTTYPE_FE
‪const REQUESTTYPE_FE
Definition: SystemEnvironmentBuilder.php:43
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\mergeSiteConfiguration
‪mergeSiteConfiguration(string $identifier, array $overrides)
Definition: SiteBasedTestTrait.php:73
‪TYPO3\CMS\Core\EventDispatcher\ListenerProvider
Definition: ListenerProvider.php:30
‪TYPO3\CMS\Redirects\Event\BeforeRedirectMatchDomainEvent
Definition: BeforeRedirectMatchDomainEvent.php:28
‪TYPO3\CMS\Redirects\Tests\Functional\Service\RedirectServiceTest\regExpRedirectsWithArgumentMatchesWithSimilarRegExpWithoutQueryParamInRecordDataProvider
‪static regExpRedirectsWithArgumentMatchesWithSimilarRegExpWithoutQueryParamInRecordDataProvider()
Definition: RedirectServiceTest.php:911
‪TYPO3\CMS\Frontend\Page\PageInformationFactory
Definition: PageInformationFactory.php:63