8000 Merge branch '3.4' into 4.1 · symfony/symfony@db2c64d · GitHub
[go: up one dir, main page]

Skip to content

Commit db2c64d

Browse files
Merge branch '3.4' into 4.1
* 3.4: [Routing] ignore trailing slash for non-GET requests
2 parents b8f87e1 + 317a2f9 commit db2c64d

File tree

12 files changed

+84
-51
lines changed

12 files changed

+84
-51
lines changed

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

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ private function compileSwitchDefault(bool $hasVars, bool $matchHost): string
564564
}
565565
}\n" : '',
566566
$this->supportsRedirections ? "
567-
if (!\$requiredMethods || isset(\$requiredMethods['GET'])) {
567+
if ((!\$requiredMethods || isset(\$requiredMethods['GET'])) && 'GET' === \$canonicalMethod) {
568568
return \$allow = \$allowSchemes = array();
569569
}" : ''
570570
);
@@ -628,34 +628,44 @@ private function compileRoute(Route $route, string $name, bool $checkHost, bool
628628
$matches = (bool) $compiledRoute->getPathVariables();
629629
$hostMatches = (bool) $compiledRoute->getHostVariables();
630630
$methods = array_flip($route->getMethods());
631+
$gotoname = 'not_'.preg_replace('/[^A-Za-z0-9_]/', '', $name);
631632
$code = " // $name";
632633

633634
if ('/' === $route->getPath()) {
634635
$code .= "\n";
635636
} elseif (!$matches) {
636637
$code .= sprintf("
637-
if ('/' !== \$pathinfo && '/' %s \$pathinfo[-1]) {
638-
%s;
638+
if ('/' !== \$pathinfo && '/' %s \$pathinfo[-1]) {%s
639+
goto $gotoname;
639640
}\n\n",
640641
$hasTrailingSlash ? '!==' : '===',
641-
$this->supportsRedirections && (!$methods || isset($methods['GET'])) ? 'return $allow = $allowSchemes = array()' : 'break'
642+
$this->supportsRedirections && (!$methods || isset($methods['GET'])) ? "
643+
if ('GET' === \$canonicalMethod) {
644+
return \$allow = \$allowSchemes = array();
645+
}" : ''
642646
);
643647
} elseif ($hasTrailingSlash) {
644648
$code .= sprintf("
645-
if ('/' !== \$pathinfo[-1]) {
646-
%s;
649+
if ('/' !== \$pathinfo[-1]) {%s
650+
goto $gotoname;
647651
}
648652
if ('/' !== \$pathinfo && preg_match(\$regex, substr(\$pathinfo, 0, -1), \$n) && \$m === (int) \$n['MARK']) {
649653
\$matches = \$n;
650654
}\n\n",
651-
$this->supportsRedirections && (!$methods || isset($methods['GET'])) ? 'return $allow = $allowSchemes = array()' : 'break'
655+
$this->supportsRedirections && (!$methods || isset($methods['GET'])) ? "
656+
if ('GET' === \$canonicalMethod) {
657+
return \$allow = \$allowSchemes = array();
658+
}" : ''
652659
);
653660
} else {
654661
$code .= sprintf("
655-
if ('/' !== \$pathinfo && '/' === \$pathinfo[-1] && preg_match(\$regex, substr(\$pathinfo, 0, -1), \$n) && \$m === (int) \$n['MARK']) {
656-
%s;
662+
if ('/' !== \$pathinfo && '/' === \$pathinfo[-1] && preg_match(\$regex, substr(\$pathinfo, 0, -1), \$n) && \$m === (int) \$n['MARK']) {%s
663+
goto $gotoname;
657664
}\n\n",
658-
$this->supportsRedirections && (!$methods || isset($methods['GET'])) ? 'return $allow = $allowSchemes = array()' : 'break'
665+
$this->supportsRedirections && (!$methods || isset($methods['GET'])) ? "
666+
if ('GET' === \$canonicalMethod) {
667+
return \$allow = \$allowSchemes = array();
668+
}" : ''
659669
);
660670
}
661671

@@ -687,8 +697,6 @@ private function compileRoute(Route $route, string $name, bool $checkHost, bool
687697
$code = $this->indent($code);
688698
}
689699

690-
$gotoname = 'not_'.preg_replace('/[^A-Za-z0-9_]/', '', $name);
691-
692700
// the offset where the return value is appended below, with indendation
693701
$retOffset = 12 + \strlen($code);
694702
$defaults = $route->getDefaults();
@@ -770,16 +778,10 @@ private function compileRoute(Route $route, string $name, bool $checkHost, bool
770778
$code = substr_replace($code, 'return', $retOffset, 6);
771779
}
772780
if ($conditions) {
773-
$code .= " }\n";
774-
} elseif ($schemes || $methods) {
775-
$code .= ' ';
776-
}
777-
778-
if ($schemes || $methods) {
779-
$code .= " $gotoname:\n";
781+
$code = $this->indent($code)." }\n";
780782
}
781783

782-
return $conditions ? $this->indent($code) : $code;
784+
return $code." $gotoname:\n";
783785
}
784786

785787
private function getExpressionLanguage()

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ public function addExpressionLanguageProvider(ExpressionFunctionProviderInterfac
130130
*/
131131
protected function matchCollection($pathinfo, RouteCollection $routes)
132132
{
133+
// HEAD and GET are equivalent as per RFC
134+
if ('HEAD' === $method = $this->context->getMethod()) {
135+
$method = 'GET';
136+
}
133137
$supportsTrailingSlash = '/' !== $pathinfo && '' !== $pathinfo && $this instanceof RedirectableUrlMatcherInterface;
134138

135139
foreach ($routes as $name => $route) {
@@ -140,7 +144,7 @@ protected function matchCollection($pathinfo, RouteCollection $routes)
140144
// check the static prefix of the URL first. Only use the more expensive preg_match when it matches
141145
if ('' === $staticPrefix || 0 === strpos($pathinfo, $staticPrefix)) {
142146
// no-op
143-
} elseif (!$supportsTrailingSlash || ($requiredMethods && !\in_array('GET', $requiredMethods))) {
147+
} elseif (!$supportsTrailingSlash || ($requiredMethods && !\in_array('GET', $requiredMethods)) || 'GET' !== $method) {
144148
continue;
145149
} elseif ('/' === $staticPrefix[-1] && substr($staticPrefix, 0, -1) === $pathinfo) {
146150
return $this->allow = $this->allowSchemes = array();
@@ -170,7 +174,7 @@ protected function matchCollection($pathinfo, RouteCollection $routes)
170174
}
171175
}
172176
if ($hasTrailingSlash !== ('/' === $pathinfo[-1])) {
173-
if (!$requiredMethods || \in_array('GET', $requiredMethods)) {
177+
if ((!$requiredMethods || \in_array('GET', $requiredMethods)) && 'GET' === $method) {
174178
return $this->allow = $this->allowSchemes = array();
175179
}
176180
continue;
@@ -190,11 +194,6 @@ protected function matchCollection($pathinfo, RouteCollection $routes)
190194

191195
$hasRequiredScheme = !$route->getSchemes() || $route->hasScheme($this->context->getScheme());
192196
if ($requiredMethods) {
193-
// HEAD and GET are equivalent as per RFC
194-
if ('HEAD' === $method = $this->context->getMethod()) {
195-
$method = 'GET';
196-
}
197-
198197
if (!\in_array($method, $requiredMethods)) {
199198
if ($hasRequiredScheme) {
200199
$this->allow = array_merge($this->allow, $requiredMethods);

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,17 +143,18 @@ public function match($rawPathinfo)
143143

144144
// baz4
145145
if ('/' !== $pathinfo[-1]) {
146-
break;
146+
goto not_baz4;
147147
}
148148
if ('/' !== $pathinfo && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
149149
$matches = $n;
150150
}
151151

152152
return $this->mergeDefaults(array('_route' => 'baz4') + $matches, array());
153+
not_baz4:
153154

154155
// baz5
155156
if ('/' !== $pathinfo[-1]) {
156-
break;
157+
goto not_baz5;
157158
}
158159
if ('/' !== $pathinfo && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
159160
$matches = $n;
@@ -170,7 +171,7 @@ public function match($rawPathinfo)
170171

171172
// baz.baz6
172173
if ('/' !== $pathinfo[-1]) {
173-
break;
174+
goto not_bazbaz6;
174175
}
175176
if ('/' !== $pathinfo && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
176177
$matches = $n;
@@ -191,7 +192,7 @@ public function match($rawPathinfo)
191192

192193
// foo1
193194
if ('/' !== $pathinfo && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
194-
break;
195+
goto not_foo1;
195196
}
196197

197198
$ret = $this->mergeDefaults(array('_route' => 'foo1') + $matches, array());
@@ -209,21 +210,23 @@ public function match($rawPathinfo)
209210

210211
// foo2
211212
if ('/' !== $pathinfo && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
212-
break;
213+
goto not_foo2;
213214
}
214215

215216
return $this->mergeDefaults(array('_route' => 'foo2') + $matches, array());
217+
not_foo2:
216218

217219
break;
218220
case 279:
219221
$matches = array('_locale' => $matches[1] ?? null, 'foo' => $matches[2] ?? null);
220222

221223
// foo3
222224
if ('/' !== $pathinfo && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
223-
break;
225+
goto not_foo3;
224226
}
225227

226228
return $this->mergeDefaults(array('_route' => 'foo3') + $matches, array());
229+
not_foo3:
227230

228231
break;
229232
default:

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ private function doMatch(string $rawPathinfo, array &$allow = array(), array &$a
128128
}
129129

130130
if ($hasTrailingSlash !== ('/' === $pathinfo[-1])) {
131-
if (!$requiredMethods || isset($requiredMethods['GET'])) {
131+
if ((!$requiredMethods || isset($requiredMethods['GET'])) && 'GET' === $canonicalMethod) {
132132
return $allow = $allowSchemes = array();
133133
}
134134
break;

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,19 @@ public function match($rawPathinfo)
4646

4747
// r1
4848
if ('/' !== $pathinfo && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
49-
break;
49+
goto not_r1;
5050
}
5151

5252
return $this->mergeDefaults(array('_route' => 'r1') + $matches, array());
53+
not_r1:
5354

5455
// r2
5556
if ('/' !== $pathinfo && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
56-
break;
57+
goto not_r2;
5758
}
5859

5960
return $this->mergeDefaults(array('_route' => 'r2') + $matches, array());
61+
not_r2:
6062

6163
break;
6264
}

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

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

9494
if ('/' !== $pathinfo) {
9595
if ($hasTrailingSlash !== ('/' === $pathinfo[-1])) {
96-
if (!$requiredMethods || isset($requiredMethods['GET'])) {
96+
if ((!$requiredMethods || isset($requiredMethods['GET'])) && 'GET' === $canonicalMethod) {
9797
return $allow = $allowSchemes = array();
9898
}
9999
break;
@@ -183,17 +183,21 @@ private function doMatch(string $rawPathinfo, array &$allow = array(), array &$a
183183

184184
// baz4
185185
if ('/' !== $pathinfo[-1]) {
186-
return $allow = $allowSchemes = array();
186+
if ('GET' === $canonicalMethod) {
187+
return $allow = $allowSchemes = array();
188+
}
189+
goto not_baz4;
187190
}
188191
if ('/' !== $pathinfo && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
189192
$matches = $n;
190193
}
191194

192195
return $this->mergeDefaults(array('_route' => 'baz4') + $matches, array());
196+
not_baz4:
193197

194198
// baz5
195199
if ('/' !== $pathinfo[-1]) {
196-
break;
200+
goto not_baz5;
197201
}
198202
if ('/' !== $pathinfo && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
199203
$matches = $n;
@@ -210,7 +214,7 @@ private function doMatch(string $rawPathinfo, array &$allow = array(), array &$a
210214

211215
// baz.baz6
212216
if ('/' !== $pathinfo[-1]) {
213-
break;
217+
goto not_bazbaz6;
214218
}
215219
if ('/' !== $pathinfo && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
216220
$matches = $n;
@@ -231,7 +235,7 @@ private function doMatch(string $rawPathinfo, array &$allow = array(), array &$a
231235

232236
// foo1
233237
if ('/' !== $pathinfo && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
234-
break;
238+
goto not_foo1;
235239
}
236240

237241
$ret = $this->mergeDefaults(array('_route' => 'foo1') + $matches, array());
@@ -249,21 +253,29 @@ private function doMatch(string $rawPathinfo, array &$allow = array(), array &$a
249253

250254
// foo2
251255
if ('/' !== $pathinfo && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
252-
return $allow = $allowSchemes = array();
256+
if ('GET' === $canonicalMethod) {
257+
return $allow = $allowSchemes = array();
258+
}
259+
goto not_foo2;
253260
}
254261

255262
return $this->mergeDefaults(array('_route' => 'foo2') + $matches, array());
263+
not_foo2:
256264

257265
break;
258266
case 279:
259267
$matches = array('_locale' => $matches[1] ?? null, 'foo' => $matches[2] ?? null);
260268

261269
// foo3
262270
if ('/' !== $pathinfo && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
263-
return $allow = $allowSchemes = array();
271+
if ('GET' === $canonicalMethod) {
272+
return $allow = $allowSchemes = array();
273+
}
274+
goto not_foo3;
264275
}
265276

266277
return $this->mergeDefaults(array('_route' => 'foo3') + $matches, array());
278+
not_foo3:
267279

268280
break;
269281
default:
@@ -299,7 +311,7 @@ private function doMatch(string $rawPathinfo, array &$allow = array(), array &$a
299311
}
300312

301313
if ($hasTrailingSlash !== ('/' === $pathinfo[-1])) {
302-
if (!$requiredMethods || isset($requiredMethods['GET'])) {
314+
if ((!$requiredMethods || isset($requiredMethods['GET'])) && 'GET' === $canonicalMethod) {
303315
return $allow = $allowSchemes = array();
304316
}
305317
break;

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,13 @@ public function match($rawPathinfo)
3030
case '/with-condition':
3131
// with-condition
3232
if ('/' !== $pathinfo && '/' === $pathinfo[-1]) {
33-
break;
33+
goto not_withcondition;
3434
}
3535

3636
if (($context->getMethod() == "GET")) {
3737
return array('_route' => 'with-condition');
3838
}
39+
not_withcondition:
3940
break;
4041
default:
4142
$routes = array(

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public function match($rawPathinfo)
3030
case '/put_and_post':
3131
// put_and_post
3232
if ('/' !== $pathinfo && '/' === $pathinfo[-1]) {
33-
break;
33+
goto not_put_and_post;
3434
}
3535

3636
$ret = array('_route' => 'put_and_post');
@@ -43,7 +43,7 @@ public function match($rawPathinfo)
4343
not_put_and_post:
4444
// put_and_get_and_head
4545
if ('/' !== $pathinfo && '/' === $pathinfo[-1]) {
46-
break;
46+
goto not_put_and_get_and_head;
4747
}
4848

4949
$ret = array('_route' => 'put_and_get_and_head');

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

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

8686
if ('/' !== $pathinfo) {
8787
if ($hasTrailingSlash !== ('/' === $pathinfo[-1])) {
88-
if (!$requiredMethods || isset($requiredMethods['GET'])) {
88+
if ((!$requiredMethods || isset($requiredMethods['GET'])) && 'GET' === $canonicalMethod) {
8989
return $allow = $allowSchemes = array();
9090
}
9191
break;
@@ -136,7 +136,7 @@ private function doMatch(string $rawPathinfo, array &$allow = array(), array &$a
136136
}
137137

138138
if ($hasTrailingSlash !== ('/' === $pathinfo[-1])) {
139-
if (!$requiredMethods || isset($requiredMethods['GET'])) {
139+
if ((!$requiredMethods || isset($requiredMethods['GET'])) && 'GET' === $canonicalMethod) {
140140
return $allow = $allowSchemes = array();
141141
}
142142
break;

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

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

8282
if ('/' !== $pathinfo) {
8383
if ($hasTrailingSlash !== ('/' === $pathinfo[-1])) {
84-
if (!$requiredMethods || isset($requiredMethods['GET'])) {
84+
if ((!$requiredMethods || isset($requiredMethods['GET'])) && 'GET' === $canonicalMethod) {
8585
return $allow = $allowSchemes = array();
8686
}
8787
break;
@@ -148,7 +148,7 @@ private function doMatch(string $rawPathinfo, array &$allow = array(), array &$a
148148
}
149149

150150
if ($hasTrailingSlash !== ('/' === $pathinfo[-1])) {
151-
if (!$requiredMethods || isset($requiredMethods['GET'])) {
151+
if ((!$requiredMethods || isset($requiredMethods['GET'])) && 'GET' === $canonicalMethod) {
152152
return $allow = $allowSchemes = array();
153153
}
154154
break;

0 commit comments

Comments
 (0)
0