Skip to content

Commit c8e69f8

Browse files
Support multiple proxy servers in Forwarded header parsing
1 parent 6d65525 commit c8e69f8

File tree

2 files changed

+33
-15
lines changed

2 files changed

+33
-15
lines changed

stac_fastapi/api/stac_fastapi/api/middleware.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
7575
)
7676
await self.app(scope, receive, send)
7777

78-
def _get_forwarded_url_parts(self, scope: Scope) -> Tuple[str]:
78+
def _get_forwarded_url_parts(self, scope: Scope) -> Tuple[str]: # noqa: C901
7979
proto = scope.get("scheme", "http")
8080
header_host = self._get_header_value_by_name(scope, "host")
8181
if header_host is None:
@@ -89,20 +89,24 @@ def _get_forwarded_url_parts(self, scope: Scope) -> Tuple[str]:
8989
port = None
9090
forwarded = self._get_header_value_by_name(scope, "forwarded")
9191
if forwarded is not None:
92-
parts = forwarded.split(";")
93-
for part in parts:
94-
if len(part) > 0 and re.search("=", part):
95-
key, value = part.split("=")
96-
if key == "proto":
97-
proto = value
98-
elif key == "host":
99-
host_parts = value.split(":")
100-
domain = host_parts[0]
101-
try:
102-
port = int(host_parts[1]) if len(host_parts) == 2 else None
103-
except ValueError:
104-
# ignore ports that are not valid integers
105-
pass
92+
proxy_servers = forwarded.split(",") # values from the last server are used
93+
for proxy_server in proxy_servers:
94+
parts = proxy_server.split(";")
95+
for part in parts:
96+
if len(part) > 0 and re.search("=", part):
97+
key, value = part.split("=")
98+
if key == "proto":
99+
proto = value
100+
elif key == "host":
101+
host_parts = value.split(":")
102+
domain = host_parts[0]
103+
try:
104+
port = (
105+
int(host_parts[1]) if len(host_parts) == 2 else None
106+
)
107+
except ValueError:
108+
# ignore ports that are not valid integers
109+
pass
106110
else:
107111
domain = self._get_header_value_by_name(scope, "x-forwarded-host", domain)
108112
proto = self._get_header_value_by_name(scope, "x-forwarded-proto", proto)

stac_fastapi/api/tests/test_middleware.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,20 @@ def test_replace_header_value_by_name(
155155
},
156156
("https", "test", 1234),
157157
),
158+
(
159+
{
160+
"scheme": "http",
161+
"server": ["testserver", 80],
162+
"headers": [
163+
(
164+
b"forwarded",
165+
# two proxy servers added an entry, we want to use the last one
166+
b"proto=https;host=test:1234,proto=https;host=second-server:1111",
167+
)
168+
],
169+
},
170+
("https", "second-server", 1111),
171+
),
158172
],
159173
)
160174
def test_get_forwarded_url_parts(

0 commit comments

Comments
 (0)