diff --git a/sanic/router.py b/sanic/router.py index ec67f690..e25572fb 100644 --- a/sanic/router.py +++ b/sanic/router.py @@ -210,29 +210,40 @@ class Router: url = host + url # Check against known static routes route = self.routes_static.get(url) + method_not_supported = InvalidUsage( + 'Method {} not allowed for URL {}'.format( + method, url), status_code=405) if route: + if route.methods and method not in route.methods: + raise method_not_supported match = route.pattern.match(url) else: + route_found = False # Move on to testing all regex routes for route in self.routes_dynamic[url_hash(url)]: match = route.pattern.match(url) - if match: + route_found |= match is not None + # Do early method checking + if match and method in route.methods: break else: # Lastly, check against all regex routes that cannot be hashed for route in self.routes_always_check: match = route.pattern.match(url) - if match: + route_found |= match is not None + # Do early method checking + if match and method in route.methods: break else: + # Route was found but the methods didn't match + if route_found: + raise method_not_supported raise NotFound('Requested URL {} not found'.format(url)) - if route.methods and method not in route.methods: - raise InvalidUsage( - 'Method {} not allowed for URL {}'.format( - method, url), status_code=405) - kwargs = {p.name: p.cast(value) for value, p in zip(match.groups(1), route.parameters)} - return route.handler, [], kwargs + route_handler = route.handler + if hasattr(route_handler, 'handlers'): + route_handler = route_handler.handlers[method] + return route_handler, [], kwargs diff --git a/sanic/sanic.py b/sanic/sanic.py index 1ed14b7f..00b1961b 100644 --- a/sanic/sanic.py +++ b/sanic/sanic.py @@ -90,7 +90,7 @@ class Sanic: def patch(self, uri, host=None): return self.route(uri, methods=["PATCH"], host=host) - def add_route(self, handler, uri, methods=None, host=None): + def add_route(self, handler, uri, methods=frozenset({'GET'}), host=None): """ A helper method to register class instance or functions as a handler to the application url