8000 bug #26100 [Routing] Throw 405 instead of 404 when redirect is not po… · symfony/symfony@aa3a04a · GitHub
[go: up one dir, main page]

Skip to content

Commit aa3a04a

Browse 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

File tree

3 files changed

+54
-24
lines changed

3 files changed

+54
-24
lines changed

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

Lines 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

Lines 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

Lines 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