From 08798daba7745934ee6eac3775d81c371dba0265 Mon Sep 17 00:00:00 2001 From: Alexandre Gaigalas Date: Sun, 11 Mar 2012 15:28:55 -0300 Subject: [PATCH] Fix for #25, still needs refactoring related to #28 --- library/Respect/Rest/Router.php | 31 +++++++++++++------ library/Respect/Rest/Routes/AbstractRoute.php | 23 +++++++------- tests/library/Respect/Rest/RouterTest.php | 11 ++++++- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/library/Respect/Rest/Router.php b/library/Respect/Rest/Router.php index e34d732..530229b 100644 --- a/library/Respect/Rest/Router.php +++ b/library/Respect/Rest/Router.php @@ -141,16 +141,29 @@ public function dispatchRequest(Request $request=null) $request->uri = preg_replace('#^' . preg_quote($this->virtualHost) . '#', '', $request->uri); - try { - foreach ($this->routes as $route) - if ($this->matchRoute($request, $route, $params)) - return $this->configureRequest($request, $route, static::cleanUpParams($params)); - } catch (MethodNotAllowed $e) { - header('HTTP/1.1 405'); - return; - } + $matchedByPath = array(); + $allowedMethods = array(); + + foreach ($this->routes as $route) + if ($this->matchRoute($request, $route, $params)) { + $matchedByPath[] = $route; + $allowedMethods[] = $route->method; + } + + if (!$matchedByPath) + header('HTTP/1.1 404'); + + foreach ($matchedByPath as $route) + if (0 !== stripos($request->method, '__') + && ($route->method === $request->method || $route->method === 'ANY') + && $route->matchRoutines($request, $params)) + return $this->configureRequest($request, $route, static::cleanUpParams($params)); + + header('HTTP/1.1 405'); + + if ($allowedMethods) + header('Allow: '.implode(', ', $allowedMethods)); - header('HTTP/1.1 404'); $request->route = null; return $request; } diff --git a/library/Respect/Rest/Routes/AbstractRoute.php b/library/Respect/Rest/Routes/AbstractRoute.php index 07ecd13..cc0c60b 100644 --- a/library/Respect/Rest/Routes/AbstractRoute.php +++ b/library/Respect/Rest/Routes/AbstractRoute.php @@ -71,25 +71,24 @@ public function createUri($param1=null, $etc=null) ); } + public function matchRoutines(Request $request, &$params=array()) + { + foreach ($this->routines as $routine) + if ($routine instanceof ProxyableWhen + && !$request->routineCall('when', $request->method, $routine, $params)) + return false; + + return true; + } + /** Checks if this route matches a request */ public function match(Request $request, &$params=array()) { - if (0 === stripos($request->method, '__')) - return false; - - // Checks if the given HTTP method is not implemented - if (($request->method !== $this->method ) && $this->method !== 'ANY') - throw new MethodNotAllowed(sprintf('%s not allowed for %s', $request->method, $this->pattern)); - $matchUri = $request->uri; - foreach ($this->routines as $routine) { - if ($routine instanceof ProxyableWhen - && !$request->routineCall('when', $request->method, $routine, $params)) - return false; + foreach ($this->routines as $routine) if ($routine instanceof IgnorableFileExtension) $matchUri = preg_replace('#(\.\w+)*$#', '', $request->uri); - } if (!preg_match($this->regexForMatch, $matchUri, $params)) return false; diff --git a/tests/library/Respect/Rest/RouterTest.php b/tests/library/Respect/Rest/RouterTest.php index f893195..07c3135 100644 --- a/tests/library/Respect/Rest/RouterTest.php +++ b/tests/library/Respect/Rest/RouterTest.php @@ -108,13 +108,22 @@ function test_dispatch_non_existing_route() $this->assertContains('HTTP/1.1 404', $header); } function test_method_not_allowed_header() + { + global $header; + $this->router->get('/', function() { return 'ok'; }); + $this->router->put('/', function() { return 'ok'; }); + $this->router->dispatch('delete', '/'); + $this->assertContains('HTTP/1.1 405', $header); + $this->assertContains('Allow: GET, PUT', $header); + } + function test_method_not_allowed_header_with_conneg() { global $header; $this->router->get('/', function() { return 'ok'; }) ->accept(array('text/html' => function($d) {return $d;})); $this->router->dispatch('delete', '/'); $this->assertContains('HTTP/1.1 405', $header); - //$this->assertContains('Allow: ', $header); + $this->assertContains('Allow: GET', $header); } } $header=array();