Skip to content

Commit 94a3dd8

Browse files
[Routing] ignore trailing slash for non-GET requests
1 parent 19e4acc commit 94a3dd8

File tree

2 files changed

+17
-7
lines changed

2 files changed

+17
-7
lines changed

Matcher/UrlMatcher.php

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ public function addExpressionLanguageProvider(ExpressionFunctionProviderInterfac
118118
*/
119119
protected function matchCollection($pathinfo, RouteCollection $routes)
120120
{
121+
// HEAD and GET are equivalent as per RFC
122+
if ('HEAD' === $method = $this->context->getMethod()) {
123+
$method = 'GET';
124+
}
121125
$supportsTrailingSlash = '/' !== $pathinfo && '' !== $pathinfo && $this instanceof RedirectableUrlMatcherInterface;
122126

123127
foreach ($routes as $name => $route) {
@@ -128,7 +132,7 @@ protected function matchCollection($pathinfo, RouteCollection $routes)
128132
// check the static prefix of the URL first. Only use the more expensive preg_match when it matches
129133
if ('' === $staticPrefix || 0 === strpos($pathinfo, $staticPrefix)) {
130134
// no-op
131-
} elseif (!$supportsTrailingSlash || ($requiredMethods && !\in_array('GET', $requiredMethods))) {
135+
} elseif (!$supportsTrailingSlash || ($requiredMethods && !\in_array('GET', $requiredMethods)) || 'GET' !== $method) {
132136
continue;
133137
} elseif ('/' === substr($staticPrefix, -1) && substr($staticPrefix, 0, -1) === $pathinfo) {
134138
return $this->allow = array();
@@ -149,7 +153,7 @@ protected function matchCollection($pathinfo, RouteCollection $routes)
149153
}
150154

151155
if ($hasTrailingSlash && '/' !== substr($pathinfo, -1)) {
152-
if (!$requiredMethods || \in_array('GET', $requiredMethods)) {
156+
if ((!$requiredMethods || \in_array('GET', $requiredMethods)) && 'GET' === $method) {
153157
return $this->allow = array();
154158
}
155159
continue;
@@ -168,11 +172,6 @@ protected function matchCollection($pathinfo, RouteCollection $routes)
168172

169173
// check HTTP method requirement
170174
if ($requiredMethods) {
171-
// HEAD and GET are equivalent as per RFC
172-
if ('HEAD' === $method = $this->context->getMethod()) {
173-
$method = 'GET';
174-
}
175-
176175
if (!\in_array($method, $requiredMethods)) {
177176
if (self::REQUIREMENT_MATCH === $status[0]) {
178177
$this->allow = array_merge($this->allow, $requiredMethods);

Tests/Matcher/UrlMatcherTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,17 @@ public function testSlashAndVerbPrecedence()
514514
'customerId' => '123',
515515
);
516516
$this->assertEquals($expected, $matcher->match('/api/customers/123/contactpersons'));
517+
518+
$coll = new RouteCollection();
519+
$coll->add('a', new Route('/api/customers/{customerId}/contactpersons/', array(), array(), array(), '', array(), array('get')));
520+
$coll->add('b', new Route('/api/customers/{customerId}/contactpersons', array(), array(), array(), '', array(), array('post')));
521+
522+
$matcher = $this->getUrlMatcher($coll, new RequestContext('', 'POST'));
523+
$expected = array(
524+
'_route' => 'b',
525+
'customerId' => '123',
526+
);
527+
$this->assertEquals($expected, $matcher->match('/api/customers/123/contactpersons'));
517528
}
518529

519530
protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)

0 commit comments

Comments
 (0)