Skip to content

Commit 86316a2

Browse files
Support forwarded headers that do not contain a host key (#788)
* Support forwarded headers that do not contain a host key * Add correct PR number to changelog * Avoid python3.10 typing features
1 parent 5ded0c6 commit 86316a2

File tree

3 files changed

+27
-6
lines changed

3 files changed

+27
-6
lines changed

CHANGES.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
### Fixed
6+
7+
* support `forwarded` headers in `ProxyHeaderMiddleware` that do not contain a host key ([#788](https://github.com/stac-utils/stac-fastapi/pull/788))
8+
39
## [4.0.0] - 2025-01-17
410

511
### Changed

stac_fastapi/api/stac_fastapi/api/middleware.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import re
55
import typing
66
from http.client import HTTP_PORT, HTTPS_PORT
7-
from typing import List, Tuple
7+
from typing import List, Optional, Tuple
88

99
from starlette.middleware.cors import CORSMiddleware as _CORSMiddleware
1010
from starlette.types import ASGIApp, Receive, Scope, Send
@@ -95,12 +95,13 @@ def _get_forwarded_url_parts(self, scope: Scope) -> Tuple[str]:
9595
domain = header_host_parts[0]
9696
port = None
9797

98+
port_str = None # make sure it is defined in all paths since we access it later
99+
98100
if forwarded := self._get_header_value_by_name(scope, "forwarded"):
99101
for proxy in forwarded.split(","):
100-
if (proto_expr := _PROTO_HEADER_REGEX.search(proxy)) and (
101-
host_expr := _HOST_HEADER_REGEX.search(proxy)
102-
):
102+
if proto_expr := _PROTO_HEADER_REGEX.search(proxy):
103103
proto = proto_expr.group("proto")
104+
if host_expr := _HOST_HEADER_REGEX.search(proxy):
104105
domain = host_expr.group("host")
105106
port_str = host_expr.group("port") # None if not present in the match
106107

@@ -115,8 +116,8 @@ def _get_forwarded_url_parts(self, scope: Scope) -> Tuple[str]:
115116
return (proto, domain, port)
116117

117118
def _get_header_value_by_name(
118-
self, scope: Scope, header_name: str, default_value: str = None
119-
) -> str:
119+
self, scope: Scope, header_name: str, default_value: Optional[str] = None
120+
) -> Optional[str]:
120121
headers = scope["headers"]
121122
candidates = [
122123
value.decode() for key, value in headers if key.decode() == header_name

stac_fastapi/api/tests/test_middleware.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,20 @@ def test_replace_header_value_by_name(
183183
},
184184
("https", "test", 1234),
185185
),
186+
(
187+
{
188+
"scheme": "http",
189+
"server": ["testserver", 80],
190+
"headers": [
191+
(
192+
b"forwarded",
193+
# proto is set, but no host
194+
b'for="85.193.181.55";proto=https,for="85.193.181.55";proto=https',
195+
)
196+
],
197+
},
198+
("https", "testserver", 80),
199+
),
186200
],
187201
)
188202
def test_get_forwarded_url_parts(

0 commit comments

Comments
 (0)