diff --git a/sanic/router.py b/sanic/router.py index f7877f15..39872469 100644 --- a/sanic/router.py +++ b/sanic/router.py @@ -16,6 +16,7 @@ REGEX_TYPES = { 'int': (int, r'\d+'), 'number': (float, r'[0-9\\.]+'), 'alpha': (str, r'[A-Za-z]+'), + 'path': (str, r'[^/].*?'), } ROUTER_CACHE_SIZE = 1024 @@ -71,7 +72,8 @@ class Router: self.routes_always_check = [] self.hosts = set() - def parse_parameter_string(self, parameter_string): + @classmethod + def parse_parameter_string(cls, parameter_string): """Parse a parameter string into its constituent name, type, and pattern @@ -161,10 +163,10 @@ class Router: parameters.append(parameter) # Mark the whole route as unhashable if it has the hash key in it - if re.search('(^|[^^]){1}/', pattern): + if re.search(r'(^|[^^]){1}/', pattern): properties['unhashable'] = True # Mark the route as unhashable if it matches the hash key - elif re.search(pattern, '/'): + elif re.search(r'/', pattern): properties['unhashable'] = True return '({})'.format(pattern) diff --git a/tests/test_routes.py b/tests/test_routes.py index 3506db66..b3e19355 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -238,6 +238,30 @@ def test_dynamic_route_regex(): assert response.status == 200 +def test_dynamic_route_path(): + app = Sanic('test_dynamic_route_path') + + @app.route('//info') + async def handler(request, path): + return text('OK') + + request, response = app.test_client.get('/path/1/info') + assert response.status == 200 + + request, response = app.test_client.get('/info') + assert response.status == 404 + + @app.route('/') + async def handler1(request, path): + return text('OK') + + request, response = app.test_client.get('/info') + assert response.status == 200 + + request, response = app.test_client.get('/whatever/you/set') + assert response.status == 200 + + def test_dynamic_route_unhashable(): app = Sanic('test_dynamic_route_unhashable')