Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow colons in routes again #1657

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 6 additions & 3 deletions starlette/routing.py
Expand Up @@ -108,7 +108,7 @@ def replace_params(


def compile_path(
path: str,
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 +150,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 +433,9 @@ 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