8000 bug #29373 [Routing] fix trailing slash redirection (nicolas-grekas) · symfony/symfony@bce7748 · GitHub
[go: up one dir, main page]

Skip to content

Commit bce7748

Browse files
bug #29373 [Routing] fix trailing slash redirection (nicolas-grekas)
This PR was merged into the 4.1 branch. Discussion ---------- [Routing] fix trailing slash redirection | Q | A | ------------- | --- | Branch? | 4.1 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #29363 | License | MIT | Doc PR | - Commits ------- fbaba23 [Routing] fix trailing slash redirection
2 parents 7ff53ac + fbaba23 commit bce7748

File tree

14 files changed

+143
-38
lines changed

14 files changed

+143
-38
lines changed

src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,9 +550,15 @@ private function compileStaticPrefixCollection(StaticPrefixCollection $tree, \st
550550
private function compileSwitchDefault(bool $hasVars, bool $matchHost): string
551551
{
552552
$code = sprintf("
553-
if ('/' !== \$pathinfo && \$hasTrailingSlash !== ('/' === \$pathinfo[-1])) {
554-
%s;
553+
if ('/' !== \$pathinfo) {
554+
if (!\$hasTrailingSlash && '/' === \$pathinfo[-1]%s) {
555+
%s;
556+
}
557+
if (\$hasTrailingSlash && '/' !== \$pathinfo[-1]) {
558+
%2\$s;
559+
}
555560
}\n",
561+
$hasVars ? ' && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n[\'MARK\']' : '',
556562
$this->supportsRedirections ? 'return null' : 'break'
557563
);
558564

src/Symfony/Component/Routing/Matcher/UrlMatcher.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,13 @@ protected function matchCollection($pathinfo, RouteCollection $routes)
160160
continue;
161161
}
162162

163-
if ($supportsTrailingSlash && $hasTrailingSlash !== ('/' === $pathinfo[-1])) {
164-
return;
163+
if ($supportsTrailingSlash) {
164+
if (!$hasTrailingSlash && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1))) {
165+
return;
166+
}
167+
if ($hasTrailingSlash && '/' !== $pathinfo[-1]) {
168+
return;
169+
}
165170
}
166171

167172
$hostMatches = array();

src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,13 @@ public function match($rawPathinfo)
5454
}
5555
list($ret, $requiredHost, $requiredMethods, $requiredSchemes, $hasTrailingSlash) = $routes[$trimmedPathinfo];
5656

57-
if ('/' !== $pathinfo && $hasTrailingSlash !== ('/' === $pathinfo[-1])) {
58-
break;
57+
if ('/' !== $pathinfo) {
58+
if (!$hasTrailingSlash && '/' === $pathinfo[-1]) {
59+
break;
60+
}
61+
if ($hasTrailingSlash && '/' !== $pathinfo[-1]) {
62+
break;
63+
}
5964
}
6065

6166
if ($requiredHost) {
@@ -232,8 +237,13 @@ public function match($rawPathinfo)
232237

233238
list($ret, $vars, $requiredMethods, $requiredSchemes, $hasTrailingSlash) = $routes[$m];
234239

235-
if ('/' !== $pathinfo && $hasTrailingSlash !== ('/' === $pathinfo[-1])) {
236-
break;
240+
if ('/' !== $pathinfo) {
241+
if (!$hasTrailingSlash && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
242+
break;
243+
}
244+
if ($hasTrailingSlash && '/' !== $pathinfo[-1]) {
245+
break;
246+
}
237247
}
238248

239249
foreach ($vars as $i => $v) {

src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher10.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2793,8 +2793,13 @@ public function match($rawPathinfo)
27932793

27942794
list($ret, $vars, $requiredMethods, $requiredSchemes, $hasTrailingSlash) = $routes[$m];
27952795

2796-
if ('/' !== $pathinfo && $hasTrailingSlash !== ('/' === $pathinfo[-1])) {
2797-
break;
2796+
if ('/' !== $pathinfo) {
2797+
if (!$hasTrailingSlash && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
2798+
break;
2799+
}
2800+
if ($hasTrailingSlash && '/' !== $pathinfo[-1]) {
2801+
break;
2802+
}
27982803
}
27992804

28002805
foreach ($vars as $i => $v) {

src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher11.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,13 @@ private function doMatch(string $rawPathinfo, array &$allow = array(), array &$a
118118

119119
list($ret, $vars, $requiredMethods, $requiredSchemes, $hasTrailingSlash) = $routes[$m];
120120

121-
if ('/' !== $pathinfo && $hasTrailingSlash !== ('/' === $pathinfo[-1])) {
122-
return null;
121+
if ('/' !== $pathinfo) {
122+
if (!$hasTrailingSlash && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
123+
return null;
124+
}
125+
if ($hasTrailingSlash && '/' !== $pathinfo[-1]) {
126+
return null;
127+
}
123128
}
124129

125130
foreach ($vars as $i => $v) {

src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher12.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,13 @@ public function match($rawPathinfo)
6363

6464
list($ret, $vars, $requiredMethods, $requiredSchemes, $hasTrailingSlash) = $routes[$m];
6565

66-
if ('/' !== $pathinfo && $hasTrailingSlash !== ('/' === $pathinfo[-1])) {
67-
break;
66+
if ('/' !== $pathinfo) {
67+
if (!$hasTrailingSlash && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
68+
break;
69+
}
70+
if ($hasTrailingSlash && '/' !== $pathinfo[-1]) {
71+
break;
72+
}
6873
}
6974

7075
foreach ($vars as $i => $v) {

src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,13 @@ private function doMatch(string $rawPathinfo, array &$allow = array(), array &$a
9191
}
9292
list($ret, $requiredHost, $requiredMethods, $requiredSchemes, $hasTrailingSlash) = $routes[$trimmedPathinfo];
9393

94-
if ('/' !== $pathinfo && $hasTrailingSlash !== ('/' === $pathinfo[-1])) {
95-
return null;
94+
if ('/' !== $pathinfo) {
95+
if (!$hasTrailingSlash && '/' === $pathinfo[-1]) {
96+
return null;
97+
}
98+
if ($hasTrailingSlash && '/' !== $pathinfo[-1]) {
99+
return null;
100+
}
96101
}
97102

98103
if ($requiredHost) {
@@ -269,8 +274,13 @@ private function doMatch(string $rawPathinfo, array &$allow = array(), array &$a
269274

270275
list($ret, $vars, $requiredMethods, $requiredSchemes, $hasTrailingSlash) = $routes[$m];
271276

272-
if ('/' !== $pathinfo && $hasTrailingSlash !== ('/' === $pathinfo[-1])) {
273-
return null;
277+
if ('/' !== $pathinfo) {
278+
if (!$hasTrailingSlash && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
279+
return null;
280+
}
281+
if ($hasTrailingSlash && '/' !== $pathinfo[-1]) {
282+
return null;
283+
}
274284
}
275285

276286
foreach ($vars as $i => $v) {

src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher3.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,13 @@ public function match($rawPathinfo)
4646
}
4747
list($ret, $requiredHost, $requiredMethods, $requiredSchemes, $hasTrailingSlash) = $routes[$trimmedPathinfo];
4848

49-
if ('/' !== $pathinfo && $hasTrailingSlash !== ('/' === $pathinfo[-1])) {
50-
break;
49+
if ('/' !== $pathinfo) {
50+
if (!$hasTrailingSlash && '/' === $pathinfo[-1]) {
51+
break;
52+
}
53+
if ($hasTrailingSlash && '/' !== $pathinfo[-1]) {
54+
break;
55+
}
5156
}
5257

5358
$hasRequiredScheme = !$requiredSchemes || isset($requiredSchemes[$context->getScheme()]);
@@ -82,8 +87,13 @@ public function match($rawPathinfo)
8287

8388
list($ret, $vars, $requiredMethods, $requiredSchemes, $hasTrailingSlash) = $routes[$m];
8489

85-
if ('/' !== $pathinfo && $hasTrailingSlash !== ('/' === $pathinfo[-1])) {
86-
break;
90+
if ('/' !== $pathinfo) {
91+
if (!$hasTrailingSlash && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
92+
break;
93+
}
94+
if ($hasTrailingSlash && '/' !== $pathinfo[-1]) {
95+
break;
96+
}
8797
}
8898

8999
foreach ($vars as $i => $v) {

src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher4.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,13 @@ public function match($rawPathinfo)
6666
}
6767
list($ret, $requiredHost, $requiredMethods, $requiredSchemes, $hasTrailingSlash) = $routes[$trimmedPathinfo];
6868

69-
if ('/' !== $pathinfo && $hasTrailingSlash !== ('/' === $pathinfo[-1])) {
70-
break;
69+
if ('/' !== $pathinfo) {
70+
if (!$hasTrailingSlash && '/' === $pathinfo[-1]) {
71+
break;
72+
}
73+
if ($hasTrailingSlash && '/' !== $pathinfo[-1]) {
74+
break;
75+
}
7176
}
7277

7378
$hasRequiredScheme = !$requiredSchemes || isset($requiredSchemes[$context->getScheme()]);

src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher5.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,13 @@ private function doMatch(string $rawPathinfo, array &$allow = array(), array &$a
8383
}
8484
list($ret, $requiredHost, $requiredMethods, $requiredSchemes, $hasTrailingSlash) = $routes[$trimmedPathinfo];
8585

86-
if ('/' !== $pathinfo && $hasTrailingSlash !== ('/' === $pathinfo[-1])) {
87-
return null;
86+
if ('/' !== $pathinfo) {
87+
if (!$hasTrailingSlash && '/' === $pathinfo[-1]) {
88+
return null;
89+
}
90+
if ($hasTrailingSlash && '/' !== $pathinfo[-1]) {
91+
return null;
92+
}
8893
}
8994

9095
$hasRequiredScheme = !$requiredSchemes || isset($requiredSchemes[$context->getScheme()]);
@@ -121,8 +126,13 @@ private function doMatch(string $rawPathinfo, array &$allow = array(), array &$a
121126

122127
list($ret, $vars, $requiredMethods, $requiredSchemes, $hasTrailingSlash) = $routes[$m];
123128

124-
if ('/' !== $pathinfo && $hasTrailingSlash !== ('/' === $pathinfo[-1])) {
125-
return null;
129+
if ('/' !== $pathinfo) {
130+
if (!$hasTrailingSlash && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
131+
return null;
132+
}
133+
if ($hasTrailingSlash && '/' !== $pathinfo[-1]) {
134+
return null;
135+
}
126136
}
127137

128138
foreach ($vars as $i => $v) {

0 commit comments

Comments
 (0)
0