Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit aa3a04a

Browse filesBrowse files
committed
bug #26100 [Routing] Throw 405 instead of 404 when redirect is not possible (nicolas-grekas)
This PR was merged into the 2.7 branch. Discussion ---------- [Routing] Throw 405 instead of 404 when redirect is not possible | Q | A | ------------- | --- | Branch? | 2.7 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - Finishes #25962. Commits ------- 9284281 [Routing] Throw 405 instead of 404 when redirect is not possible
2 parents 7218310 + 9284281 commit aa3a04a
Copy full SHA for aa3a04a

File tree

3 files changed

+54
-24
lines changed
Filter options

3 files changed

+54
-24
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php
+31-24Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren
217217
$methods[] = 'HEAD';
218218
}
219219

220-
$supportsTrailingSlash = $supportsRedirections && (!$methods || in_array('HEAD', $methods));
220+
$supportsTrailingSlash = $supportsRedirections && (!$methods || in_array('GET', $methods));
221221

222222
if (!count($compiledRoute->getPathVariables()) && false !== preg_match('#^(.)\^(?P<url>.*?)\$\1#', $compiledRoute->getRegex(), $m)) {
223223
if ($supportsTrailingSlash && '/' === substr($m['url'], -1)) {
@@ -258,34 +258,13 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren
258258
EOF;
259259

260260
$gotoname = 'not_'.preg_replace('/[^A-Za-z0-9_]/', '', $name);
261-
if ($methods) {
262-
if (1 === count($methods)) {
263-
$code .= <<<EOF
264-
if (\$this->context->getMethod() != '$methods[0]') {
265-
\$allow[] = '$methods[0]';
266-
goto $gotoname;
267-
}
268-
269-
270-
EOF;
271-
} else {
272-
$methods = implode("', '", $methods);
273-
$code .= <<<EOF
274-
if (!in_array(\$this->context->getMethod(), array('$methods'))) {
275-
\$allow = array_merge(\$allow, array('$methods'));
276-
goto $gotoname;
277-
}
278-
279-
280-
EOF;
281-
}
282-
}
283261

284262
if ($hasTrailingSlash) {
285263
$code .= <<<EOF
286264
if ('/' === substr(\$pathinfo, -1)) {
287265
// no-op
288266
} elseif (!in_array(\$this->context->getMethod(), array('HEAD', 'GET'))) {
267+
\$allow[] = 'GET';
289268
goto $gotoname;
290269
} else {
291270
return \$this->redirect(\$rawPathinfo.'/', '$name');
@@ -303,13 +282,41 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren
303282
$code .= <<<EOF
304283
\$requiredSchemes = $schemes;
305284
if (!isset(\$requiredSchemes[\$this->context->getScheme()])) {
285+
if (!in_array(\$this->context->getMethod(), array('HEAD', 'GET'))) {
286+
\$allow[] = 'GET';
287+
goto $gotoname;
288+
}
289+
306290
return \$this->redirect(\$rawPathinfo, '$name', key(\$requiredSchemes));
307291
}
308292
309293
310294
EOF;
311295
}
312296

297+
if ($methods) {
298+
if (1 === count($methods)) {
299+
$code .= <<<EOF
300+
if (\$this->context->getMethod() != '$methods[0]') {
301+
\$allow[] = '$methods[0]';
302+
goto $gotoname;
303+
}
304+
305+
306+
EOF;
307+
} else {
308+
$methods = implode("', '", $methods);
309+
$code .= <<<EOF
310+
if (!in_array(\$this->context->getMethod(), array('$methods'))) {
311+
\$allow = array_merge(\$allow, array('$methods'));
312+
goto $gotoname;
313+
}
314+
315+
316+
EOF;
317+
}
318+
}
319+
313320
// optimize parameters array
314321
if ($matches || $hostMatches) {
315322
$vars = array();
@@ -333,7 +340,7 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren
333340
}
334341
$code .= " }\n";
335342

336-
if ($methods || $hasTrailingSlash) {
343+
if ($hasTrailingSlash || $schemes || $methods) {
337344
$code .= " $gotoname:\n";
338345
}
339346

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public function match($rawPathinfo)
6969
if ('/' === substr($pathinfo, -1)) {
7070
// no-op
7171
} elseif (!in_array($this->context->getMethod(), array('HEAD', 'GET'))) {
72+
$allow[] = 'GET';
7273
goto not_baz3;
7374
} else {
7475
return $this->redirect($rawPathinfo.'/', 'baz3');
@@ -85,6 +86,7 @@ public function match($rawPathinfo)
8586
if ('/' === substr($pathinfo, -1)) {
8687
// no-op
8788
} elseif (!in_array($this->context->getMethod(), array('HEAD', 'GET'))) {
89+
$allow[] = 'GET';
8890
goto not_baz4;
8991
} else {
9092
return $this->redirect($rawPathinfo.'/', 'baz4');
@@ -183,6 +185,7 @@ public function match($rawPathinfo)
183185
if ('/' === substr($pathinfo, -1)) {
184186
// no-op
185187
} elseif (!in_array($this->context->getMethod(), array('HEAD', 'GET'))) {
188+
$allow[] = 'GET';
186189
goto not_hey;
187190
} else {
188191
return $this->redirect($rawPathinfo.'/', 'hey');
@@ -333,21 +336,33 @@ public function match($rawPathinfo)
333336
if ('/secure' === $pathinfo) {
334337
$requiredSchemes = array ( 'https' => 0,);
335338
if (!isset($requiredSchemes[$this->context->getScheme()])) {
339+
if (!in_array($this->context->getMethod(), array('HEAD', 'GET'))) {
340+
$allow[] = 'GET';
341+
goto not_secure;
342+
}
343+
336344
return $this->redirect($rawPathinfo, 'secure', key($requiredSchemes));
337345
}
338346

339347
return array('_route' => 'secure');
340348
}
349+
not_secure:
341350

342351
// nonsecure
343352
if ('/nonsecure' === $pathinfo) {
344353
$requiredSchemes = array ( 'http' => 0,);
345354
if (!isset($requiredSchemes[$this->context->getScheme()])) {
355+
if (!in_array($this->context->getMethod(), array('HEAD', 'GET'))) {
356+
$allow[] = 'GET';
357+
goto not_nonsecure;
358+
}
359+
346360
return $this->redirect($rawPathinfo, 'nonsecure', key($requiredSchemes));
347361
}
348362

349363
return array('_route' => 'nonsecure');
350364
}
365+
not_nonsecure:
351366

352367
throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
353368
}

‎src/Symfony/Component/Routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@
1919

2020
class DumpedRedirectableUrlMatcherTest extends RedirectableUrlMatcherTest
2121
{
22+
/**
23+
* @expectedException \Symfony\Component\Routing\Exception\MethodNotAllowedException
24+
*/
25+
public function testRedirectWhenNoSlashForNonSafeMethod()
26+
{
27+
parent::testRedirectWhenNoSlashForNonSafeMethod();
28+
}
29+
2230
protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
2331
{
2432
static $i = 0;

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.