Skip to content

Commit 0d4747e

Browse files
aadnehovdaKludex
andauthored
Use X-Forwarded-Proto for WebSockets scheme when the proxy provides it (#2258)
* Fix X-Forwarded-Proto when the proxy already sets it to "ws" or "wss" Minor fix for #2043 Traefik already sets the X-Forwarded-Proto headers to ws or wss for websockets. https://github.com/traefik/traefik/blob/c1ef7429771104e79f2e87b236b21495cb5765f0/pkg/middlewares/forwardedheaders/forwarded_header.go#L150 This change should make sure we don't overwrite those values. * Fix the logic * Update test_proxy_headers.py Test whether passing "wss" in X-Forwarded-Proto works * Simplify the logic (probably more ways to write this... lmk which you prefer) * Update tests and min implementation * Remove new line --------- Co-authored-by: Marcelo Trylesinski <[email protected]>
1 parent 93897b5 commit 0d4747e

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

tests/middleware/test_proxy_headers.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,18 @@ async def test_proxy_headers_invalid_x_forwarded_for() -> None:
115115

116116

117117
@pytest.mark.anyio
118+
@pytest.mark.parametrize(
119+
"x_forwarded_proto,addr",
120+
[
121+
("http", "ws://1.2.3.4:0"),
122+
("https", "wss://1.2.3.4:0"),
123+
("ws", "ws://1.2.3.4:0"),
124+
("wss", "wss://1.2.3.4:0"),
125+
],
126+
)
118127
async def test_proxy_headers_websocket_x_forwarded_proto(
128+
x_forwarded_proto: str,
129+
addr: str,
119130
ws_protocol_cls: "Type[WSProtocol | WebSocketProtocol]",
120131
http_protocol_cls: "Type[H11Protocol | HttpToolsProtocol]",
121132
unused_tcp_port: int,
@@ -138,7 +149,7 @@ async def websocket_app(scope, receive, send):
138149

139150
async with run_server(config):
140151
url = f"ws://127.0.0.1:{unused_tcp_port}"
141-
headers = {"X-Forwarded-Proto": "https", "X-Forwarded-For": "1.2.3.4"}
152+
headers = {"X-Forwarded-Proto": x_forwarded_proto, "X-Forwarded-For": "1.2.3.4"}
142153
async with websockets.client.connect(url, extra_headers=headers) as websocket:
143154
data = await websocket.recv()
144-
assert data == "wss://1.2.3.4:0"
155+
assert data == addr

uvicorn/middleware/proxy_headers.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,7 @@ async def __call__(
6363
headers[b"x-forwarded-proto"].decode("latin1").strip()
6464
)
6565
if scope["type"] == "websocket":
66-
scope["scheme"] = (
67-
"wss" if x_forwarded_proto == "https" else "ws"
68-
)
66+
scope["scheme"] = x_forwarded_proto.replace("http", "ws")
6967
else:
7068
scope["scheme"] = x_forwarded_proto
7169

0 commit comments

Comments
 (0)