Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Forward client IP chain to session allocator
Browse filesPreserve the incoming X-Forwarded-For chain for load-balancer network attribution. Requests without the header continue to omit it.
- README.md +2 -1
- app.py +1 -0
- tests/test_session_proxy.py +11 -0
README.md
CHANGED
|
@@ -31,4 +31,5 @@ Optional:
|
|
| 31 |
- `GET /session-url`: returns the currently configured upstream allocator URL
|
| 32 |
- `GET /config`: alias for `/session-url`
|
| 33 |
- `POST /session`: proxies the session allocation request to the upstream URL,
|
| 34 |
-
including
|
|
|
|
|
|
| 31 |
- `GET /session-url`: returns the currently configured upstream allocator URL
|
| 32 |
- `GET /config`: alias for `/session-url`
|
| 33 |
- `POST /session`: proxies the session allocation request to the upstream URL,
|
| 34 |
+
including valid incoming bearer `Authorization` and `X-Forwarded-For`
|
| 35 |
+
headers when present
|
app.py
CHANGED
|
@@ -74,6 +74,7 @@ def _upstream_headers(request: Request) -> dict[str, str]:
|
|
| 74 |
"Content-Type": request.headers.get("content-type"),
|
| 75 |
"Accept": request.headers.get("accept"),
|
| 76 |
"Authorization": _bearer_authorization(request.headers.get("authorization")),
|
|
|
|
| 77 |
}
|
| 78 |
headers.update({name: value for name, value in forwarded_headers.items() if value})
|
| 79 |
return headers
|
|
|
|
| 74 |
"Content-Type": request.headers.get("content-type"),
|
| 75 |
"Accept": request.headers.get("accept"),
|
| 76 |
"Authorization": _bearer_authorization(request.headers.get("authorization")),
|
| 77 |
+
"X-Forwarded-For": request.headers.get("x-forwarded-for"),
|
| 78 |
}
|
| 79 |
headers.update({name: value for name, value in forwarded_headers.items() if value})
|
| 80 |
return headers
|
tests/test_session_proxy.py
CHANGED
|
@@ -98,8 +98,19 @@ class SessionProxyTests(unittest.IsolatedAsyncioTestCase):
|
|
| 98 |
post = await self.proxy({})
|
| 99 |
|
| 100 |
self.assertNotIn("Authorization", post["headers"])
|
|
|
|
| 101 |
|
| 102 |
async def test_does_not_forward_non_bearer_authorization(self):
|
| 103 |
post = await self.proxy({"Authorization": "Basic credentials"})
|
| 104 |
|
| 105 |
self.assertNotIn("Authorization", post["headers"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
post = await self.proxy({})
|
| 99 |
|
| 100 |
self.assertNotIn("Authorization", post["headers"])
|
| 101 |
+
self.assertNotIn("X-Forwarded-For", post["headers"])
|
| 102 |
|
| 103 |
async def test_does_not_forward_non_bearer_authorization(self):
|
| 104 |
post = await self.proxy({"Authorization": "Basic credentials"})
|
| 105 |
|
| 106 |
self.assertNotIn("Authorization", post["headers"])
|
| 107 |
+
|
| 108 |
+
async def test_forwards_client_ip_chain_to_upstream(self):
|
| 109 |
+
post = await self.proxy(
|
| 110 |
+
{"X-Forwarded-For": "203.0.113.8, 10.0.0.4"}
|
| 111 |
+
)
|
| 112 |
+
|
| 113 |
+
self.assertEqual(
|
| 114 |
+
post["headers"]["X-Forwarded-For"],
|
| 115 |
+
"203.0.113.8, 10.0.0.4",
|
| 116 |
+
)
|