[Routing] Don't throw 405 when scheme requirement doesn't match
This commit is contained in:
parent
d8395f5035
commit
9d70ef0915
@ -278,6 +278,28 @@ EOF;
|
|||||||
throw new \LogicException('The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.');
|
throw new \LogicException('The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.');
|
||||||
}
|
}
|
||||||
$schemes = str_replace("\n", '', var_export(array_flip($schemes), true));
|
$schemes = str_replace("\n", '', var_export(array_flip($schemes), true));
|
||||||
|
if ($methods) {
|
||||||
|
$methods = implode("', '", $methods);
|
||||||
|
$code .= <<<EOF
|
||||||
|
\$requiredSchemes = $schemes;
|
||||||
|
\$hasRequiredScheme = isset(\$requiredSchemes[\$this->context->getScheme()]);
|
||||||
|
if (!in_array(\$this->context->getMethod(), array('$methods'))) {
|
||||||
|
if (\$hasRequiredScheme) {
|
||||||
|
\$allow = array_merge(\$allow, array('$methods'));
|
||||||
|
}
|
||||||
|
goto $gotoname;
|
||||||
|
}
|
||||||
|
if (!\$hasRequiredScheme) {
|
||||||
|
if (!in_array(\$this->context->getMethod(), array('HEAD', 'GET'))) {
|
||||||
|
goto $gotoname;
|
||||||
|
}
|
||||||
|
|
||||||
|
return \$this->redirect(\$rawPathinfo, '$name', key(\$requiredSchemes));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EOF;
|
||||||
|
} else {
|
||||||
$code .= <<<EOF
|
$code .= <<<EOF
|
||||||
\$requiredSchemes = $schemes;
|
\$requiredSchemes = $schemes;
|
||||||
if (!isset(\$requiredSchemes[\$this->context->getScheme()])) {
|
if (!isset(\$requiredSchemes[\$this->context->getScheme()])) {
|
||||||
@ -291,8 +313,7 @@ EOF;
|
|||||||
|
|
||||||
EOF;
|
EOF;
|
||||||
}
|
}
|
||||||
|
} elseif ($methods) {
|
||||||
if ($methods) {
|
|
||||||
if (1 === count($methods)) {
|
if (1 === count($methods)) {
|
||||||
$code .= <<<EOF
|
$code .= <<<EOF
|
||||||
if (\$this->context->getMethod() != '$methods[0]') {
|
if (\$this->context->getMethod() != '$methods[0]') {
|
||||||
|
@ -129,6 +129,12 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$status = $this->handleRouteRequirements($pathinfo, $name, $route);
|
||||||
|
|
||||||
|
if (self::REQUIREMENT_MISMATCH === $status[0]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// check HTTP method requirement
|
// check HTTP method requirement
|
||||||
if ($requiredMethods = $route->getMethods()) {
|
if ($requiredMethods = $route->getMethods()) {
|
||||||
// HEAD and GET are equivalent as per RFC
|
// HEAD and GET are equivalent as per RFC
|
||||||
@ -137,22 +143,18 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array($method, $requiredMethods)) {
|
if (!in_array($method, $requiredMethods)) {
|
||||||
|
if (self::REQUIREMENT_MATCH === $status[0]) {
|
||||||
$this->allow = array_merge($this->allow, $requiredMethods);
|
$this->allow = array_merge($this->allow, $requiredMethods);
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$status = $this->handleRouteRequirements($pathinfo, $name, $route);
|
|
||||||
|
|
||||||
if (self::ROUTE_MATCH === $status[0]) {
|
if (self::ROUTE_MATCH === $status[0]) {
|
||||||
return $status[1];
|
return $status[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self::REQUIREMENT_MISMATCH === $status[0]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->getAttributes($route, $name, array_replace($matches, $hostMatches));
|
return $this->getAttributes($route, $name, array_replace($matches, $hostMatches));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,15 @@ class DumpedUrlMatcherTest extends UrlMatcherTest
|
|||||||
parent::testSchemeRequirement();
|
parent::testSchemeRequirement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \LogicException
|
||||||
|
* @expectedExceptionMessage The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.
|
||||||
|
*/
|
||||||
|
public function testSchemeAndMethodMismatch()
|
||||||
|
{
|
||||||
|
parent::testSchemeRequirement();
|
||||||
|
}
|
||||||
|
|
||||||
protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
|
protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
|
||||||
{
|
{
|
||||||
static $i = 0;
|
static $i = 0;
|
||||||
|
@ -464,6 +464,18 @@ class UrlMatcherTest extends TestCase
|
|||||||
$this->assertEquals(array('_route' => 'buz'), $matcher->match('/prefix/buz'));
|
$this->assertEquals(array('_route' => 'buz'), $matcher->match('/prefix/buz'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
|
||||||
|
*/
|
||||||
|
public function testSchemeAndMethodMismatch()
|
||||||
|
{
|
||||||
|
$coll = new RouteCollection();
|
||||||
|
$coll->add('foo', new Route('/', array(), array(), array(), null, array('https'), array('POST')));
|
||||||
|
|
||||||
|
$matcher = $this->getUrlMatcher($coll);
|
||||||
|
$matcher->match('/');
|
||||||
|
}
|
||||||
|
|
||||||
protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
|
protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
|
||||||
{
|
{
|
||||||
return new UrlMatcher($routes, $context ?: new RequestContext());
|
return new UrlMatcher($routes, $context ?: new RequestContext());
|
||||||
|
Reference in New Issue
Block a user