Skip to content

Commit

Permalink
Allow colons in routes
Browse files Browse the repository at this point in the history
  • Loading branch information
bodograumann committed May 31, 2022
1 parent d3dccdc commit e863f7b
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 2 deletions.
6 changes: 4 additions & 2 deletions starlette/routing.py
Expand Up @@ -109,6 +109,7 @@ def replace_params(

def compile_path(
path: str,
strip_port: bool = False
) -> typing.Tuple[typing.Pattern, str, typing.Dict[str, Convertor]]:
"""
Given a path string, like: "/{username:str}", return a three-tuple
Expand Down Expand Up @@ -150,7 +151,8 @@ def compile_path(
ending = "s" if len(duplicated_params) > 1 else ""
raise ValueError(f"Duplicated param name{ending} {names} at path {path}")

path_regex += re.escape(path[idx:].split(":")[0]) + "$"
tail: str = path[idx:].split(":")[0] if strip_port else path[idx:]
path_regex += re.escape(tail) + "$"
path_format += path[idx:]

return re.compile(path_regex), path_format, param_convertors
Expand Down Expand Up @@ -432,7 +434,7 @@ def __init__(
self.host = host
self.app = app
self.name = name
self.host_regex, self.host_format, self.param_convertors = compile_path(host)
self.host_regex, self.host_format, self.param_convertors = compile_path(host, strip_port=True)

@property
def routes(self) -> typing.List[BaseRoute]:
Expand Down
11 changes: 11 additions & 0 deletions tests/test_routing.py
Expand Up @@ -18,6 +18,11 @@ def users(request):
return Response("All users", media_type="text/plain")


def disable_user(request):
content = "User " + request.path_params["username"] + " disabled"
return Response(content, media_type="text/plain")


def user(request):
content = "User " + request.path_params["username"]
return Response(content, media_type="text/plain")
Expand Down Expand Up @@ -108,6 +113,7 @@ async def websocket_params(session: WebSocket):
routes=[
Route("/", endpoint=users),
Route("/me", endpoint=user_me),
Route("/{username}:disable", endpoint=disable_user, methods=["PUT"]),
Route("/{username}", endpoint=user),
Route("/nomatch", endpoint=user_no_match),
],
Expand Down Expand Up @@ -189,6 +195,11 @@ def test_router(client):
assert response.url == "http://testserver/users/tomchristie"
assert response.text == "User tomchristie"

response = client.put("/users/tomchristie:disable")
assert response.status_code == 200
assert response.url == "http://testserver/users/tomchristie:disable"
assert response.text == "User tomchristie disabled"

response = client.get("/users/nomatch")
assert response.status_code == 200
assert response.text == "User nomatch"
Expand Down

0 comments on commit e863f7b

Please sign in to comment.