feature #26304 [Routing] support scheme requirement without redirectable dumped matcher (Tobion)
This PR was merged into the 4.1-dev branch.
Discussion
----------
[Routing] support scheme requirement without redirectable dumped matcher
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | yes
| New feature? | yes
| BC breaks? | no
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md files -->
| Tests pass? | yes <!-- please add some, will be required by reviewers -->
| Fixed tickets |
| License | MIT
| Doc PR |
The scheme handling was just redirecting immediately without testing the other routes at all for potential matches. This can cause Problems when you try to have different routes/controllers for the same path but different schemes. See added test.
```
$coll = new RouteCollection();
$coll->add('https_route', new Route('/', array(), array(), array(), '', array('https')));
$coll->add('http_route', new Route('/', array(), array(), array(), '', array('http')));
$matcher = $this->getUrlMatcher($coll);
$this->assertEquals(array('_route' => 'http_route'), $matcher->match('/'));
```
Instead of matching the right route, it would redirect immediatly as soon as it hits the first route.
This does not make sense and is not consistent with the other logic. Redirection should only happen when nothing matches. While fixing this I could also remove the limitation
> throw new \LogicException('The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.');
If redirection is not possible, the wrong scheme will just not match the route. This is the same as already implemented by UrlMatcher (not RedirecableUrlMatcher). If redirection is supported, it will redirect to the first supported scheme if no other route matches. This makes the implementation similar to redirection for trailing slash and handling not allowed methods.
Also previously, the scheme redirection was done for non-safe verbs which shouldn't happen as well, ref. #25962
Commits
-------
f9b54c5
[Routing] support scheme requirement without redirectable dumped matcher
This commit is contained in:
commit
a1b241473d
@ -29,7 +29,6 @@ class PhpMatcherDumper extends MatcherDumper
|
||||
{
|
||||
private $expressionLanguage;
|
||||
private $signalingException;
|
||||
private $supportsRedirections;
|
||||
|
||||
/**
|
||||
* @var ExpressionFunctionProviderInterface[]
|
||||
@ -57,7 +56,7 @@ class PhpMatcherDumper extends MatcherDumper
|
||||
|
||||
// trailing slash support is only enabled if we know how to redirect the user
|
||||
$interfaces = class_implements($options['base_class']);
|
||||
$this->supportsRedirections = isset($interfaces[RedirectableUrlMatcherInterface::class]);
|
||||
$supportsRedirections = isset($interfaces[RedirectableUrlMatcherInterface::class]);
|
||||
|
||||
return <<<EOF
|
||||
<?php
|
||||
@ -77,7 +76,7 @@ class {$options['class']} extends {$options['base_class']}
|
||||
\$this->context = \$context;
|
||||
}
|
||||
|
||||
{$this->generateMatchMethod()}
|
||||
{$this->generateMatchMethod($supportsRedirections)}
|
||||
}
|
||||
|
||||
EOF;
|
||||
@ -91,7 +90,7 @@ EOF;
|
||||
/**
|
||||
* Generates the code for the match method implementing UrlMatcherInterface.
|
||||
*/
|
||||
private function generateMatchMethod(): string
|
||||
private function generateMatchMethod(bool $supportsRedirections): string
|
||||
{
|
||||
// Group hosts by same-suffix, re-order when possible
|
||||
$matchHost = false;
|
||||
@ -111,7 +110,7 @@ EOF;
|
||||
|
||||
$code = <<<EOF
|
||||
{
|
||||
\$allow = array();
|
||||
\$allow = \$allowSchemes = array();
|
||||
\$pathinfo = rawurldecode(\$rawPathinfo);
|
||||
\$context = \$this->context;
|
||||
\$requestMethod = \$canonicalMethod = \$context->getMethod();
|
||||
@ -124,25 +123,44 @@ $code
|
||||
|
||||
EOF;
|
||||
|
||||
if ($this->supportsRedirections) {
|
||||
if ($supportsRedirections) {
|
||||
return <<<'EOF'
|
||||
public function match($pathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
if ($ret = $this->doMatch($pathinfo, $allow)) {
|
||||
$allow = $allowSchemes = array();
|
||||
if ($ret = $this->doMatch($pathinfo, $allow, $allowSchemes)) {
|
||||
return $ret;
|
||||
}
|
||||
if ('/' !== $pathinfo && in_array($this->context->getMethod(), array('HEAD', 'GET'), true)) {
|
||||
if ($allow) {
|
||||
throw new MethodNotAllowedException(array_keys($allow));
|
||||
}
|
||||
if (!in_array($this->context->getMethod(), array('HEAD', 'GET'), true)) {
|
||||
// no-op
|
||||
} elseif ($allowSchemes) {
|
||||
redirect_scheme:
|
||||
$scheme = $this->context->getScheme();
|
||||
$this->context->setScheme(key($allowSchemes));
|
||||
try {
|
||||
if ($ret = $this->doMatch($pathinfo)) {
|
||||
return $this->redirect($pathinfo, $ret['_route'], $this->context->getScheme()) + $ret;
|
||||
}
|
||||
} finally {
|
||||
$this->context->setScheme($scheme);
|
||||
}
|
||||
} elseif ('/' !== $pathinfo) {
|
||||
$pathinfo = '/' !== $pathinfo[-1] ? $pathinfo.'/' : substr($pathinfo, 0, -1);
|
||||
if ($ret = $this->doMatch($pathinfo)) {
|
||||
if ($ret = $this->doMatch($pathinfo, $allow, $allowSchemes)) {
|
||||
return $this->redirect($pathinfo, $ret['_route']) + $ret;
|
||||
}
|
||||
if ($allowSchemes) {
|
||||
goto redirect_scheme;
|
||||
}
|
||||
}
|
||||
|
||||
throw $allow ? new MethodNotAllowedException(array_keys($allow)) : new ResourceNotFoundException();
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
private function doMatch(string $rawPathinfo, array &$allow = array()): ?array
|
||||
private function doMatch(string $rawPathinfo, array &$allow = array(), array &$allowSchemes = array()): ?array
|
||||
|
||||
EOF
|
||||
.$code."\n return null;\n }";
|
||||
@ -238,9 +256,6 @@ EOF
|
||||
}
|
||||
|
||||
if (!$route->getCondition()) {
|
||||
if (!$this->supportsRedirections && $route->getSchemes()) {
|
||||
throw new \LogicException('The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.');
|
||||
}
|
||||
$default .= sprintf(
|
||||
"%s => array(%s, %s, %s, %s),\n",
|
||||
self::export($url),
|
||||
@ -535,8 +550,8 @@ EOF;
|
||||
} else {
|
||||
$code = '';
|
||||
}
|
||||
if ($this->supportsRedirections) {
|
||||
$code .= <<<EOF
|
||||
|
||||
$code .= <<<EOF
|
||||
|
||||
\$hasRequiredScheme = !\$requiredSchemes || isset(\$requiredSchemes[\$context->getScheme()]);
|
||||
if (\$requiredMethods && !isset(\$requiredMethods[\$canonicalMethod]) && !isset(\$requiredMethods[\$requestMethod])) {
|
||||
@ -546,28 +561,13 @@ EOF;
|
||||
break;
|
||||
}
|
||||
if (!\$hasRequiredScheme) {
|
||||
if ('GET' !== \$canonicalMethod) {
|
||||
break;
|
||||
}
|
||||
|
||||
return \$this->redirect(\$rawPathinfo, \$ret['_route'], key(\$requiredSchemes)) + \$ret;
|
||||
}
|
||||
|
||||
return \$ret;
|
||||
|
||||
EOF;
|
||||
} else {
|
||||
$code .= <<<EOF
|
||||
|
||||
if (\$requiredMethods && !isset(\$requiredMethods[\$canonicalMethod]) && !isset(\$requiredMethods[\$requestMethod])) {
|
||||
\$allow += \$requiredMethods;
|
||||
\$allowSchemes += \$requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
return \$ret;
|
||||
|
||||
EOF;
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
@ -647,9 +647,6 @@ EOF;
|
||||
}
|
||||
|
||||
if ($schemes = $route->getSchemes()) {
|
||||
if (!$this->supportsRedirections) {
|
||||
throw new \LogicException('The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.');
|
||||
}
|
||||
$schemes = self::export(array_flip($schemes));
|
||||
if ($methods) {
|
||||
$code .= <<<EOF
|
||||
@ -662,11 +659,8 @@ EOF;
|
||||
goto $gotoname;
|
||||
}
|
||||
if (!\$hasRequiredScheme) {
|
||||
if ('GET' !== \$canonicalMethod) {
|
||||
goto $gotoname;
|
||||
}
|
||||
|
||||
return \$this->redirect(\$rawPathinfo, '$name', key(\$requiredSchemes)) + \$ret;
|
||||
\$allowSchemes += \$requiredSchemes;
|
||||
goto $gotoname;
|
||||
}
|
||||
|
||||
|
||||
@ -675,11 +669,8 @@ EOF;
|
||||
$code .= <<<EOF
|
||||
\$requiredSchemes = $schemes;
|
||||
if (!isset(\$requiredSchemes[\$context->getScheme()])) {
|
||||
if ('GET' !== \$canonicalMethod) {
|
||||
goto $gotoname;
|
||||
}
|
||||
|
||||
return \$this->redirect(\$rawPathinfo, '$name', key(\$requiredSchemes)) + \$ret;
|
||||
\$allowSchemes += \$requiredSchemes;
|
||||
goto $gotoname;
|
||||
}
|
||||
|
||||
|
||||
|
@ -11,8 +11,8 @@
|
||||
|
||||
namespace Symfony\Component\Routing\Matcher;
|
||||
|
||||
use Symfony\Component\Routing\Exception\ExceptionInterface;
|
||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
use Symfony\Component\Routing\Route;
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
@ -27,38 +27,38 @@ abstract class RedirectableUrlMatcher extends UrlMatcher implements Redirectable
|
||||
try {
|
||||
return parent::match($pathinfo);
|
||||
} catch (ResourceNotFoundException $e) {
|
||||
if ('/' === $pathinfo || !\in_array($this->context->getMethod(), array('HEAD', 'GET'), true)) {
|
||||
if (!\in_array($this->context->getMethod(), array('HEAD', 'GET'), true)) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
try {
|
||||
$pathinfo = '/' !== $pathinfo[-1] ? $pathinfo.'/' : substr($pathinfo, 0, -1);
|
||||
$ret = parent::match($pathinfo);
|
||||
if ($this->allowSchemes) {
|
||||
redirect_scheme:
|
||||
$scheme = $this->context->getScheme();
|
||||
$this->context->setScheme(current($this->allowSchemes));
|
||||
try {
|
||||
$ret = parent::match($pathinfo);
|
||||
|
||||
return $this->redirect($pathinfo, $ret['_route'] ?? null) + $ret;
|
||||
} catch (ResourceNotFoundException $e2) {
|
||||
return $this->redirect($pathinfo, $ret['_route'] ?? null, $this->context->getScheme()) + $ret;
|
||||
} catch (ExceptionInterface $e2) {
|
||||
throw $e;
|
||||
} finally {
|
||||
$this->context->setScheme($scheme);
|
||||
}
|
||||
} elseif ('/' === $pathinfo) {
|
||||
throw $e;
|
||||
} else {
|
||||
try {
|
||||
$pathinfo = '/' !== $pathinfo[-1] ? $pathinfo.'/' : substr($pathinfo, 0, -1);
|
||||
$ret = parent::match($pathinfo);
|
||||
|
||||
return $this->redirect($pathinfo, $ret['_route'] ?? null) + $ret;
|
||||
} catch (ExceptionInterface $e2) {
|
||||
if ($this->allowSchemes) {
|
||||
goto redirect_scheme;
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function handleRouteRequirements($pathinfo, $name, Route $route)
|
||||
{
|
||||
// expression condition
|
||||
if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) {
|
||||
return array(self::REQUIREMENT_MISMATCH, null);
|
||||
}
|
||||
|
||||
// check HTTP scheme requirement
|
||||
$scheme = $this->context->getScheme();
|
||||
$schemes = $route->getSchemes();
|
||||
if ($schemes && !$route->hasScheme($scheme)) {
|
||||
return array(self::ROUTE_MATCH, $this->redirect($pathinfo, $name, current($schemes)));
|
||||
}
|
||||
|
||||
return array(self::REQUIREMENT_MATCH, null);
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,19 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
const ROUTE_MATCH = 2;
|
||||
|
||||
protected $context;
|
||||
|
||||
/**
|
||||
* Collects HTTP methods that would be allowed for the request.
|
||||
*/
|
||||
protected $allow = array();
|
||||
|
||||
/**
|
||||
* Collects URI schemes that would be allowed for the request.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
protected $allowSchemes = array();
|
||||
|
||||
protected $routes;
|
||||
protected $request;
|
||||
protected $expressionLanguage;
|
||||
@ -70,7 +82,7 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
*/
|
||||
public function match($pathinfo)
|
||||
{
|
||||
$this->allow = array();
|
||||
$this->allow = $this->allowSchemes = array();
|
||||
|
||||
if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) {
|
||||
return $ret;
|
||||
@ -141,7 +153,7 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
continue;
|
||||
}
|
||||
|
||||
// check HTTP method requirement
|
||||
$hasRequiredScheme = !$route->getSchemes() || $route->hasScheme($this->context->getScheme());
|
||||
if ($requiredMethods = $route->getMethods()) {
|
||||
// HEAD and GET are equivalent as per RFC
|
||||
if ('HEAD' === $method = $this->context->getMethod()) {
|
||||
@ -149,7 +161,7 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
}
|
||||
|
||||
if (!in_array($method, $requiredMethods)) {
|
||||
if (self::REQUIREMENT_MATCH === $status[0]) {
|
||||
if ($hasRequiredScheme) {
|
||||
$this->allow = array_merge($this->allow, $requiredMethods);
|
||||
}
|
||||
|
||||
@ -157,6 +169,12 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
}
|
||||
}
|
||||
|
||||
if (!$hasRequiredScheme) {
|
||||
$this->allowSchemes = array_merge($this->allowSchemes, $route->getSchemes());
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
return $this->getAttributes($route, $name, array_replace($matches, $hostMatches, isset($status[1]) ? $status[1] : array()));
|
||||
}
|
||||
}
|
||||
@ -197,11 +215,7 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
return array(self::REQUIREMENT_MISMATCH, null);
|
||||
}
|
||||
|
||||
// check HTTP scheme requirement
|
||||
$scheme = $this->context->getScheme();
|
||||
$status = $route->getSchemes() && !$route->hasScheme($scheme) ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH;
|
||||
|
||||
return array($status, null);
|
||||
return array(self::REQUIREMENT_MATCH, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,7 +17,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
public function match($rawPathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
$allow = $allowSchemes = array();
|
||||
$pathinfo = rawurldecode($rawPathinfo);
|
||||
$context = $this->context;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
|
@ -17,7 +17,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
public function match($rawPathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
$allow = $allowSchemes = array();
|
||||
$pathinfo = rawurldecode($rawPathinfo);
|
||||
$context = $this->context;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
@ -64,8 +64,15 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
}
|
||||
}
|
||||
|
||||
$hasRequiredScheme = !$requiredSchemes || isset($requiredSchemes[$context->getScheme()]);
|
||||
if ($requiredMethods && !isset($requiredMethods[$canonicalMethod]) && !isset($requiredMethods[$requestMethod])) {
|
||||
$allow += $requiredMethods;
|
||||
if ($hasRequiredScheme) {
|
||||
$allow += $requiredMethods;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!$hasRequiredScheme) {
|
||||
$allowSchemes += $requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -209,8 +216,15 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
}
|
||||
}
|
||||
|
||||
$hasRequiredScheme = !$requiredSchemes || isset($requiredSchemes[$context->getScheme()]);
|
||||
if ($requiredMethods && !isset($requiredMethods[$canonicalMethod]) && !isset($requiredMethods[$requestMethod])) {
|
||||
$allow += $requiredMethods;
|
||||
if ($hasRequiredScheme) {
|
||||
$allow += $requiredMethods;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!$hasRequiredScheme) {
|
||||
$allowSchemes += $requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
public function match($rawPathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
$allow = $allowSchemes = array();
|
||||
$pathinfo = rawurldecode($rawPathinfo);
|
||||
$context = $this->context;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
@ -2799,8 +2799,15 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
}
|
||||
}
|
||||
|
||||
$hasRequiredScheme = !$requiredSchemes || isset($requiredSchemes[$context->getScheme()]);
|
||||
if ($requiredMethods && !isset($requiredMethods[$canonicalMethod]) && !isset($requiredMethods[$requestMethod])) {
|
||||
$allow += $requiredMethods;
|
||||
if ($hasRequiredScheme) {
|
||||
$allow += $requiredMethods;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!$hasRequiredScheme) {
|
||||
$allowSchemes += $requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -17,23 +17,42 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
|
||||
public function match($pathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
if ($ret = $this->doMatch($pathinfo, $allow)) {
|
||||
$allow = $allowSchemes = array();
|
||||
if ($ret = $this->doMatch($pathinfo, $allow, $allowSchemes)) {
|
||||
return $ret;
|
||||
}
|
||||
if ('/' !== $pathinfo && in_array($this->context->getMethod(), array('HEAD', 'GET'), true)) {
|
||||
if ($allow) {
|
||||
throw new MethodNotAllowedException(array_keys($allow));
|
||||
}
|
||||
if (!in_array($this->context->getMethod(), array('HEAD', 'GET'), true)) {
|
||||
// no-op
|
||||
} elseif ($allowSchemes) {
|
||||
redirect_scheme:
|
||||
$scheme = $this->context->getScheme();
|
||||
$this->context->setScheme(key($allowSchemes));
|
||||
try {
|
||||
if ($ret = $this->doMatch($pathinfo)) {
|
||||
return $this->redirect($pathinfo, $ret['_route'], $this->context->getScheme()) + $ret;
|
||||
}
|
||||
} finally {
|
||||
$this->context->setScheme($scheme);
|
||||
}
|
||||
} elseif ('/' !== $pathinfo) {
|
||||
$pathinfo = '/' !== $pathinfo[-1] ? $pathinfo.'/' : substr($pathinfo, 0, -1);
|
||||
if ($ret = $this->doMatch($pathinfo)) {
|
||||
if ($ret = $this->doMatch($pathinfo, $allow, $allowSchemes)) {
|
||||
return $this->redirect($pathinfo, $ret['_route']) + $ret;
|
||||
}
|
||||
if ($allowSchemes) {
|
||||
goto redirect_scheme;
|
||||
}
|
||||
}
|
||||
|
||||
throw $allow ? new MethodNotAllowedException(array_keys($allow)) : new ResourceNotFoundException();
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
private function doMatch(string $rawPathinfo, array &$allow = array()): ?array
|
||||
private function doMatch(string $rawPathinfo, array &$allow = array(), array &$allowSchemes = array()): ?array
|
||||
{
|
||||
$allow = array();
|
||||
$allow = $allowSchemes = array();
|
||||
$pathinfo = rawurldecode($rawPathinfo);
|
||||
$context = $this->context;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
@ -113,11 +132,8 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
break;
|
||||
}
|
||||
if (!$hasRequiredScheme) {
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
break;
|
||||
}
|
||||
|
||||
return $this->redirect($rawPathinfo, $ret['_route'], key($requiredSchemes)) + $ret;
|
||||
$allowSchemes += $requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
@ -17,7 +17,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
public function match($rawPathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
$allow = $allowSchemes = array();
|
||||
$pathinfo = rawurldecode($rawPathinfo);
|
||||
$context = $this->context;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
@ -69,8 +69,15 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
}
|
||||
}
|
||||
|
||||
$hasRequiredScheme = !$requiredSchemes || isset($requiredSchemes[$context->getScheme()]);
|
||||
if ($requiredMethods && !isset($requiredMethods[$canonicalMethod]) && !isset($requiredMethods[$requestMethod])) {
|
||||
$allow += $requiredMethods;
|
||||
if ($hasRequiredScheme) {
|
||||
$allow += $requiredMethods;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!$hasRequiredScheme) {
|
||||
$allowSchemes += $requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
public function match($rawPathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
$allow = $allowSchemes = array();
|
||||
$pathinfo = rawurldecode($rawPathinfo);
|
||||
$context = $this->context;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
|
@ -17,23 +17,42 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
|
||||
public function match($pathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
if ($ret = $this->doMatch($pathinfo, $allow)) {
|
||||
$allow = $allowSchemes = array();
|
||||
if ($ret = $this->doMatch($pathinfo, $allow, $allowSchemes)) {
|
||||
return $ret;
|
||||
}
|
||||
if ('/' !== $pathinfo && in_array($this->context->getMethod(), array('HEAD', 'GET'), true)) {
|
||||
if ($allow) {
|
||||
throw new MethodNotAllowedException(array_keys($allow));
|
||||
}
|
||||
if (!in_array($this->context->getMethod(), array('HEAD', 'GET'), true)) {
|
||||
// no-op
|
||||
} elseif ($allowSchemes) {
|
||||
redirect_scheme:
|
||||
$scheme = $this->context->getScheme();
|
||||
$this->context->setScheme(key($allowSchemes));
|
||||
try {
|
||||
if ($ret = $this->doMatch($pathinfo)) {
|
||||
return $this->redirect($pathinfo, $ret['_route'], $this->context->getScheme()) + $ret;
|
||||
}
|
||||
} finally {
|
||||
$this->context->setScheme($scheme);
|
||||
}
|
||||
} elseif ('/' !== $pathinfo) {
|
||||
$pathinfo = '/' !== $pathinfo[-1] ? $pathinfo.'/' : substr($pathinfo, 0, -1);
|
||||
if ($ret = $this->doMatch($pathinfo)) {
|
||||
if ($ret = $this->doMatch($pathinfo, $allow, $allowSchemes)) {
|
||||
return $this->redirect($pathinfo, $ret['_route']) + $ret;
|
||||
}
|
||||
if ($allowSchemes) {
|
||||
goto redirect_scheme;
|
||||
}
|
||||
}
|
||||
|
||||
throw $allow ? new MethodNotAllowedException(array_keys($allow)) : new ResourceNotFoundException();
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
private function doMatch(string $rawPathinfo, array &$allow = array()): ?array
|
||||
private function doMatch(string $rawPathinfo, array &$allow = array(), array &$allowSchemes = array()): ?array
|
||||
{
|
||||
$allow = array();
|
||||
$allow = $allowSchemes = array();
|
||||
$pathinfo = rawurldecode($rawPathinfo);
|
||||
$context = $this->context;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
@ -90,11 +109,8 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
break;
|
||||
}
|
||||
if (!$hasRequiredScheme) {
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
break;
|
||||
}
|
||||
|
||||
return $this->redirect($rawPathinfo, $ret['_route'], key($requiredSchemes)) + $ret;
|
||||
$allowSchemes += $requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
@ -245,11 +261,8 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
break;
|
||||
}
|
||||
if (!$hasRequiredScheme) {
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
break;
|
||||
}
|
||||
|
||||
return $this->redirect($rawPathinfo, $ret['_route'], key($requiredSchemes)) + $ret;
|
||||
$allowSchemes += $requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
@ -17,7 +17,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
public function match($rawPathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
$allow = $allowSchemes = array();
|
||||
$pathinfo = rawurldecode($rawPathinfo);
|
||||
$context = $this->context;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
@ -43,8 +43,15 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
}
|
||||
list($ret, $requiredHost, $requiredMethods, $requiredSchemes) = $routes[$pathinfo];
|
||||
|
||||
$hasRequiredScheme = !$requiredSchemes || isset($requiredSchemes[$context->getScheme()]);
|
||||
if ($requiredMethods && !isset($requiredMethods[$canonicalMethod]) && !isset($requiredMethods[$requestMethod])) {
|
||||
$allow += $requiredMethods;
|
||||
if ($hasRequiredScheme) {
|
||||
$allow += $requiredMethods;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!$hasRequiredScheme) {
|
||||
$allowSchemes += $requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -74,8 +81,15 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
}
|
||||
}
|
||||
|
||||
$hasRequiredScheme = !$requiredSchemes || isset($requiredSchemes[$context->getScheme()]);
|
||||
if ($requiredMethods && !isset($requiredMethods[$canonicalMethod]) && !isset($requiredMethods[$requestMethod])) {
|
||||
$allow += $requiredMethods;
|
||||
if ($hasRequiredScheme) {
|
||||
$allow += $requiredMethods;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!$hasRequiredScheme) {
|
||||
$allowSchemes += $requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
public function match($rawPathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
$allow = $allowSchemes = array();
|
||||
$pathinfo = rawurldecode($rawPathinfo);
|
||||
$context = $this->context;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
@ -60,8 +60,15 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
}
|
||||
list($ret, $requiredHost, $requiredMethods, $requiredSchemes) = $routes[$pathinfo];
|
||||
|
||||
$hasRequiredScheme = !$requiredSchemes || isset($requiredSchemes[$context->getScheme()]);
|
||||
if ($requiredMethods && !isset($requiredMethods[$canonicalMethod]) && !isset($requiredMethods[$requestMethod])) {
|
||||
$allow += $requiredMethods;
|
||||
if ($hasRequiredScheme) {
|
||||
$allow += $requiredMethods;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!$hasRequiredScheme) {
|
||||
$allowSchemes += $requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -17,23 +17,42 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
|
||||
public function match($pathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
if ($ret = $this->doMatch($pathinfo, $allow)) {
|
||||
$allow = $allowSchemes = array();
|
||||
if ($ret = $this->doMatch($pathinfo, $allow, $allowSchemes)) {
|
||||
return $ret;
|
||||
}
|
||||
if ('/' !== $pathinfo && in_array($this->context->getMethod(), array('HEAD', 'GET'), true)) {
|
||||
if ($allow) {
|
||||
throw new MethodNotAllowedException(array_keys($allow));
|
||||
}
|
||||
if (!in_array($this->context->getMethod(), array('HEAD', 'GET'), true)) {
|
||||
// no-op
|
||||
} elseif ($allowSchemes) {
|
||||
redirect_scheme:
|
||||
$scheme = $this->context->getScheme();
|
||||
$this->context->setScheme(key($allowSchemes));
|
||||
try {
|
||||
if ($ret = $this->doMatch($pathinfo)) {
|
||||
return $this->redirect($pathinfo, $ret['_route'], $this->context->getScheme()) + $ret;
|
||||
}
|
||||
} finally {
|
||||
$this->context->setScheme($scheme);
|
||||
}
|
||||
} elseif ('/' !== $pathinfo) {
|
||||
$pathinfo = '/' !== $pathinfo[-1] ? $pathinfo.'/' : substr($pathinfo, 0, -1);
|
||||
if ($ret = $this->doMatch($pathinfo)) {
|
||||
if ($ret = $this->doMatch($pathinfo, $allow, $allowSchemes)) {
|
||||
return $this->redirect($pathinfo, $ret['_route']) + $ret;
|
||||
}
|
||||
if ($allowSchemes) {
|
||||
goto redirect_scheme;
|
||||
}
|
||||
}
|
||||
|
||||
throw $allow ? new MethodNotAllowedException(array_keys($allow)) : new ResourceNotFoundException();
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
private function doMatch(string $rawPathinfo, array &$allow = array()): ?array
|
||||
private function doMatch(string $rawPathinfo, array &$allow = array(), array &$allowSchemes = array()): ?array
|
||||
{
|
||||
$allow = array();
|
||||
$allow = $allowSchemes = array();
|
||||
$pathinfo = rawurldecode($rawPathinfo);
|
||||
$context = $this->context;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
@ -72,11 +91,8 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
break;
|
||||
}
|
||||
if (!$hasRequiredScheme) {
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
break;
|
||||
}
|
||||
|
||||
return $this->redirect($rawPathinfo, $ret['_route'], key($requiredSchemes)) + $ret;
|
||||
$allowSchemes += $requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
@ -115,11 +131,8 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
break;
|
||||
}
|
||||
if (!$hasRequiredScheme) {
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
break;
|
||||
}
|
||||
|
||||
return $this->redirect($rawPathinfo, $ret['_route'], key($requiredSchemes)) + $ret;
|
||||
$allowSchemes += $requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
@ -17,7 +17,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
public function match($rawPathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
$allow = $allowSchemes = array();
|
||||
$pathinfo = rawurldecode($rawPathinfo);
|
||||
$context = $this->context;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
@ -44,8 +44,15 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
}
|
||||
list($ret, $requiredHost, $requiredMethods, $requiredSchemes) = $routes[$pathinfo];
|
||||
|
||||
$hasRequiredScheme = !$requiredSchemes || isset($requiredSchemes[$context->getScheme()]);
|
||||
if ($requiredMethods && !isset($requiredMethods[$canonicalMethod]) && !isset($requiredMethods[$requestMethod])) {
|
||||
$allow += $requiredMethods;
|
||||
if ($hasRequiredScheme) {
|
||||
$allow += $requiredMethods;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!$hasRequiredScheme) {
|
||||
$allowSchemes += $requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -93,8 +100,15 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
}
|
||||
}
|
||||
|
||||
$hasRequiredScheme = !$requiredSchemes || isset($requiredSchemes[$context->getScheme()]);
|
||||
if ($requiredMethods && !isset($requiredMethods[$canonicalMethod]) && !isset($requiredMethods[$requestMethod])) {
|
||||
$allow += $requiredMethods;
|
||||
if ($hasRequiredScheme) {
|
||||
$allow += $requiredMethods;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!$hasRequiredScheme) {
|
||||
$allowSchemes += $requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -17,23 +17,42 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
|
||||
public function match($pathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
if ($ret = $this->doMatch($pathinfo, $allow)) {
|
||||
$allow = $allowSchemes = array();
|
||||
if ($ret = $this->doMatch($pathinfo, $allow, $allowSchemes)) {
|
||||
return $ret;
|
||||
}
|
||||
if ('/' !== $pathinfo && in_array($this->context->getMethod(), array('HEAD', 'GET'), true)) {
|
||||
if ($allow) {
|
||||
throw new MethodNotAllowedException(array_keys($allow));
|
||||
}
|
||||
if (!in_array($this->context->getMethod(), array('HEAD', 'GET'), true)) {
|
||||
// no-op
|
||||
} elseif ($allowSchemes) {
|
||||
redirect_scheme:
|
||||
$scheme = $this->context->getScheme();
|
||||
$this->context->setScheme(key($allowSchemes));
|
||||
try {
|
||||
if ($ret = $this->doMatch($pathinfo)) {
|
||||
return $this->redirect($pathinfo, $ret['_route'], $this->context->getScheme()) + $ret;
|
||||
}
|
||||
} finally {
|
||||
$this->context->setScheme($scheme);
|
||||
}
|
||||
} elseif ('/' !== $pathinfo) {
|
||||
$pathinfo = '/' !== $pathinfo[-1] ? $pathinfo.'/' : substr($pathinfo, 0, -1);
|
||||
if ($ret = $this->doMatch($pathinfo)) {
|
||||
if ($ret = $this->doMatch($pathinfo, $allow, $allowSchemes)) {
|
||||
return $this->redirect($pathinfo, $ret['_route']) + $ret;
|
||||
}
|
||||
if ($allowSchemes) {
|
||||
goto redirect_scheme;
|
||||
}
|
||||
}
|
||||
|
||||
throw $allow ? new MethodNotAllowedException(array_keys($allow)) : new ResourceNotFoundException();
|
||||
throw new ResourceNotFoundException();
|
||||
}
|
||||
|
||||
private function doMatch(string $rawPathinfo, array &$allow = array()): ?array
|
||||
private function doMatch(string $rawPathinfo, array &$allow = array(), array &$allowSchemes = array()): ?array
|
||||
{
|
||||
$allow = array();
|
||||
$allow = $allowSchemes = array();
|
||||
$pathinfo = rawurldecode($rawPathinfo);
|
||||
$context = $this->context;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
@ -68,11 +87,8 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
break;
|
||||
}
|
||||
if (!$hasRequiredScheme) {
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
break;
|
||||
}
|
||||
|
||||
return $this->redirect($rawPathinfo, $ret['_route'], key($requiredSchemes)) + $ret;
|
||||
$allowSchemes += $requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
@ -127,11 +143,8 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
break;
|
||||
}
|
||||
if (!$hasRequiredScheme) {
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
break;
|
||||
}
|
||||
|
||||
return $this->redirect($rawPathinfo, $ret['_route'], key($requiredSchemes)) + $ret;
|
||||
$allowSchemes += $requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
@ -17,7 +17,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
public function match($rawPathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
$allow = $allowSchemes = array();
|
||||
$pathinfo = rawurldecode($rawPathinfo);
|
||||
$context = $this->context;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
@ -57,8 +57,15 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
}
|
||||
}
|
||||
|
||||
$hasRequiredScheme = !$requiredSchemes || isset($requiredSchemes[$context->getScheme()]);
|
||||
if ($requiredMethods && !isset($requiredMethods[$canonicalMethod]) && !isset($requiredMethods[$requestMethod])) {
|
||||
$allow += $requiredMethods;
|
||||
if ($hasRequiredScheme) {
|
||||
$allow += $requiredMethods;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!$hasRequiredScheme) {
|
||||
$allowSchemes += $requiredSchemes;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
public function match($rawPathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
$allow = $allowSchemes = array();
|
||||
$pathinfo = rawurldecode($rawPathinfo);
|
||||
$context = $this->context;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
|
@ -17,24 +17,6 @@ use Symfony\Component\Routing\RequestContext;
|
||||
|
||||
class DumpedUrlMatcherTest extends UrlMatcherTest
|
||||
{
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @expectedExceptionMessage The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.
|
||||
*/
|
||||
public function 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)
|
||||
{
|
||||
static $i = 0;
|
||||
|
@ -46,24 +46,6 @@ class PhpMatcherDumperTest extends TestCase
|
||||
@unlink($this->dumpPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
*/
|
||||
public function testDumpWhenSchemeIsUsedWithoutAProperDumper()
|
||||
{
|
||||
$collection = new RouteCollection();
|
||||
$collection->add('secure', new Route(
|
||||
'/secure',
|
||||
array(),
|
||||
array(),
|
||||
array(),
|
||||
'',
|
||||
array('https')
|
||||
));
|
||||
$dumper = new PhpMatcherDumper($collection);
|
||||
$dumper->dump();
|
||||
}
|
||||
|
||||
public function testRedirectPreservesUrlEncoding()
|
||||
{
|
||||
$collection = new RouteCollection();
|
||||
|
@ -17,7 +17,7 @@ use Symfony\Component\Routing\RequestContext;
|
||||
|
||||
class RedirectableUrlMatcherTest extends UrlMatcherTest
|
||||
{
|
||||
public function testRedirectWhenNoSlash()
|
||||
public function testMissingTrailingSlash()
|
||||
{
|
||||
$coll = new RouteCollection();
|
||||
$coll->add('foo', new Route('/foo/'));
|
||||
@ -27,7 +27,7 @@ class RedirectableUrlMatcherTest extends UrlMatcherTest
|
||||
$matcher->match('/foo');
|
||||
}
|
||||
|
||||
public function testRedirectWhenSlash()
|
||||
public function testExtraTrailingSlash()
|
||||
{
|
||||
$coll = new RouteCollection();
|
||||
$coll->add('foo', new Route('/foo'));
|
||||
@ -127,6 +127,16 @@ class RedirectableUrlMatcherTest extends UrlMatcherTest
|
||||
$this->assertSame(array('_route' => 'foo'), $matcher->match('/foo'));
|
||||
}
|
||||
|
||||
public function testMissingTrailingSlashAndScheme()
|
||||
{
|
||||
$coll = new RouteCollection();
|
||||
$coll->add('foo', (new Route('/foo/'))->setSchemes(array('https')));
|
||||
|
||||
$matcher = $this->getUrlMatcher($coll);
|
||||
$matcher->expects($this->once())->method('redirect')->with('/foo/', 'foo', 'https')->will($this->returnValue(array()));
|
||||
$matcher->match('/foo');
|
||||
}
|
||||
|
||||
protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
|
||||
{
|
||||
return $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($routes, $context ?: new RequestContext()));
|
||||
|
@ -325,6 +325,58 @@ class UrlMatcherTest extends TestCase
|
||||
$matcher->match('/do.t.html');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
|
||||
*/
|
||||
public function testMissingTrailingSlash()
|
||||
{
|
||||
$coll = new RouteCollection();
|
||||
$coll->add('foo', new Route('/foo/'));
|
||||
|
||||
$matcher = $this->getUrlMatcher($coll);
|
||||
$matcher->match('/foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
|
||||
*/
|
||||
public function testExtraTrailingSlash()
|
||||
{
|
||||
$coll = new RouteCollection();
|
||||
$coll->add('foo', new Route('/foo'));
|
||||
|
||||
$matcher = $this->getUrlMatcher($coll);
|
||||
$matcher->match('/foo/');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
|
||||
*/
|
||||
public function testMissingTrailingSlashForNonSafeMethod()
|
||||
{
|
||||
$coll = new RouteCollection();
|
||||
$coll->add('foo', new Route('/foo/'));
|
||||
|
||||
$context = new RequestContext();
|
||||
$context->setMethod('POST');
|
||||
$matcher = $this->getUrlMatcher($coll, $context);
|
||||
$matcher->match('/foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
|
||||
*/
|
||||
public function testExtraTrailingSlashForNonSafeMethod()
|
||||
{
|
||||
$coll = new RouteCollection();
|
||||
$coll->add('foo', new Route('/foo'));
|
||||
|
||||
$context = new RequestContext();
|
||||
$context->setMethod('POST');
|
||||
$matcher = $this->getUrlMatcher($coll, $context);
|
||||
$matcher->match('/foo/');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
|
||||
*/
|
||||
@ -336,6 +388,29 @@ class UrlMatcherTest extends TestCase
|
||||
$matcher->match('/foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
|
||||
*/
|
||||
public function testSchemeRequirementForNonSafeMethod()
|
||||
{
|
||||
$coll = new RouteCollection();
|
||||
$coll->add('foo', new Route('/foo', array(), array(), array(), '', array('https')));
|
||||
|
||||
$context = new RequestContext();
|
||||
$context->setMethod('POST');
|
||||
$matcher = $this->getUrlMatcher($coll, $context);
|
||||
$matcher->match('/foo');
|
||||
}
|
||||
|
||||
public function testSamePathWithDifferentScheme()
|
||||
{
|
||||
$coll = new RouteCollection();
|
||||
$coll->add('https_route', new Route('/', array(), array(), array(), '', array('https')));
|
||||
$coll->add('http_route', new Route('/', array(), array(), array(), '', array('http')));
|
||||
$matcher = $this->getUrlMatcher($coll);
|
||||
$this->assertEquals(array('_route' => 'http_route'), $matcher->match('/'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
|
||||
*/
|
||||
|
Reference in New Issue
Block a user