Skip to content

Commit

Permalink
Remove port from Host routing regex (#1322)
Browse files Browse the repository at this point in the history
Co-authored-by: Amin Alaee <mohammadamin.alaee@gmail.com>
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
  • Loading branch information
3 people committed Nov 25, 2021
1 parent 881af38 commit 7c7ec5a
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 4 deletions.
7 changes: 4 additions & 3 deletions docs/routing.md
Expand Up @@ -183,9 +183,10 @@ url = app.url_path_for("user_detail", username=...)
If you want to use different routes for the same path based on the `Host` header.

Note that port is removed from the `Host` header when matching.
For example, `Host (host='example.org:3600', ...)` will not be processed
even if the `Host` header is `example.org:3600`.
Therefore, specify only the domain or IP address
For example, `Host (host='example.org:3600', ...)` will be processed
even if the `Host` header contains or does not contain a port other than `3600`
(`example.org:5600`, `example.org`).
Therefore, you can specify the port if you need it for use in `url_for`.

There are several ways to connect host-based routes to your application

Expand Down
2 changes: 1 addition & 1 deletion starlette/routing.py
Expand Up @@ -146,7 +146,7 @@ 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:]) + "$"
path_regex += re.escape(path[idx:].split(":")[0]) + "$"
path_format += path[idx:]

return re.compile(path_regex), path_format, param_convertors
Expand Down
26 changes: 26 additions & 0 deletions tests/test_routing.py
Expand Up @@ -352,6 +352,11 @@ def users_api(request):
name="api",
app=Router([Route("/users", users_api, name="users")]),
),
Host(
"port.example.org:3600",
name="port",
app=Router([Route("/", homepage, name="homepage")]),
),
]
)

Expand All @@ -375,6 +380,21 @@ def test_host_routing(test_client_factory):
response = client.get("/")
assert response.status_code == 200

client = test_client_factory(mixed_hosts_app, base_url="https://port.example.org/")

response = client.get("/users")
assert response.status_code == 404

response = client.get("/")
assert response.status_code == 200

client = test_client_factory(
mixed_hosts_app, base_url="https://port.example.org:5600/"
)

response = client.get("/")
assert response.status_code == 200


def test_host_reverse_urls():
assert (
Expand All @@ -389,6 +409,12 @@ def test_host_reverse_urls():
mixed_hosts_app.url_path_for("api:users").make_absolute_url("https://whatever")
== "https://api.example.org/users"
)
assert (
mixed_hosts_app.url_path_for("port:homepage").make_absolute_url(
"https://whatever"
)
== "https://port.example.org:3600/"
)


async def subdomain_app(scope, receive, send):
Expand Down

0 comments on commit 7c7ec5a

Please sign in to comment.