Merge branch '4.1' into 4.2
* 4.1: [Routing] fix greediness of trailing slash
This commit is contained in:
commit
799ad2e57c
@ -130,12 +130,20 @@ trait PhpMatcherTrait
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('/' === $pathinfo || (!$hasTrailingSlash ? '/' !== $pathinfo[-1] || !preg_match($regex, substr($pathinfo, 0, -1), $n) || $m !== (int) $n['MARK'] : '/' === $pathinfo[-1])) {
|
||||
// no-op
|
||||
} elseif ($this instanceof RedirectableUrlMatcherInterface) {
|
||||
return null;
|
||||
} else {
|
||||
continue;
|
||||
if ('/' !== $pathinfo) {
|
||||
if ('/' === $pathinfo[-1]) {
|
||||
if (preg_match($regex, substr($pathinfo, 0, -1), $n) && $m === (int) $n['MARK']) {
|
||||
$matches = $n;
|
||||
} else {
|
||||
$hasTrailingSlash = true;
|
||||
}
|
||||
}
|
||||
if ($hasTrailingSlash !== ('/' === $pathinfo[-1])) {
|
||||
if ($this instanceof RedirectableUrlMatcherInterface && (!$requiredMethods || isset($requiredMethods['GET']))) {
|
||||
return null;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($vars as $i => $v) {
|
||||
|
@ -135,11 +135,12 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
foreach ($routes as $name => $route) {
|
||||
$compiledRoute = $route->compile();
|
||||
$staticPrefix = $compiledRoute->getStaticPrefix();
|
||||
$requiredMethods = $route->getMethods();
|
||||
|
||||
// check the static prefix of the URL first. Only use the more expensive preg_match when it matches
|
||||
if ('' === $staticPrefix || 0 === strpos($pathinfo, $staticPrefix)) {
|
||||
// no-op
|
||||
} elseif (!$supportsTrailingSlash) {
|
||||
} elseif (!$supportsTrailingSlash || ($requiredMethods && !\in_array('GET', $requiredMethods))) {
|
||||
continue;
|
||||
} elseif ('/' === $staticPrefix[-1] && substr($staticPrefix, 0, -1) === $pathinfo) {
|
||||
return;
|
||||
@ -161,11 +162,18 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
}
|
||||
|
||||
if ($supportsTrailingSlash) {
|
||||
if (!$hasTrailingSlash && '/' === $pathinfo[-1] && preg_match($regex, substr($pathinfo, 0, -1))) {
|
||||
return;
|
||||
if ('/' === $pathinfo[-1]) {
|
||||
if (preg_match($regex, substr($pathinfo, 0, -1), $m)) {
|
||||
$matches = $m;
|
||||
} else {
|
||||
$hasTrailingSlash = true;
|
||||
}
|
||||
}
|
||||
if ($hasTrailingSlash && '/' !== $pathinfo[-1]) {
|
||||
return;
|
||||
if ($hasTrailingSlash !== ('/' === $pathinfo[-1])) {
|
||||
if (!$requiredMethods || \in_array('GET', $requiredMethods)) {
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,7 +189,7 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
|
||||
}
|
||||
|
||||
$hasRequiredScheme = !$route->getSchemes() || $route->hasScheme($this->context->getScheme());
|
||||
if ($requiredMethods = $route->getMethods()) {
|
||||
if ($requiredMethods) {
|
||||
// HEAD and GET are equivalent as per RFC
|
||||
if ('HEAD' === $method = $this->context->getMethod()) {
|
||||
$method = 'GET';
|
||||
|
@ -692,6 +692,25 @@ class UrlMatcherTest extends TestCase
|
||||
$this->assertEquals('a', $matcher->match('/foo/')['_route']);
|
||||
}
|
||||
|
||||
public function testSlashVariant2()
|
||||
{
|
||||
$coll = new RouteCollection();
|
||||
$coll->add('a', new Route('/foo/{bar}/', array(), array('bar' => '.*')));
|
||||
|
||||
$matcher = $this->getUrlMatcher($coll);
|
||||
$this->assertEquals(array('_route' => 'a', 'bar' => 'bar'), $matcher->match('/foo/bar/'));
|
||||
}
|
||||
|
||||
public function testSlashWithVerb()
|
||||
{
|
||||
$coll = new RouteCollection();
|
||||
$coll->add('a', new Route('/{foo}', array(), array(), array(), '', array(), array('put', 'delete')));
|
||||
$coll->add('b', new Route('/bar/'));
|
||||
|
||||
$matcher = $this->getUrlMatcher($coll);
|
||||
$this->assertSame(array('_route' => 'b'), $matcher->match('/bar/'));
|
||||
}
|
||||
|
||||
protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
|
||||
{
|
||||
return new UrlMatcher($routes, $context ?: new RequestContext());
|
||||
|
Reference in New Issue
Block a user