Support X-Forwarded-Host in proxy-headers
Checklist
- [x] There are no similar issues or pull requests for this yet.
- [ ] I discussed this idea on the community chat and feedback is positive.
Is your feature related to a problem? Please describe.
When using uvicorn, with starlette URLs with url_for are generated with bad host, when application is behind proxy and proxy sets original host to X-Forwarded-Host.
https://github.com/encode/starlette/issues/604
Describe the solution you would like.
Currently uvicorn uses only X-Forwarded-Proto, X-Forwarded-For, X-Forwarded-Port to populate scope with remote information. But there is X-Forwarded-Host header, which should be used for populating server information in scope.
would you mind setting a clear example of what the issue is, it's been a while since I haven't touched this, there is also an old PR on proxy headers so not sure this doesn't address this, will try to find it later
closing as stale, feel free to reopen
@euri10 I would like to expand on the issue here.
A use-case example would be the redirect_slashes feature in starlette.routing.Router (used in fastapi.APIRouter).
When a route is defined as /this/path/ and I make a request to /this/path (missing the trailing check), I will get a redirect to the other route.
This redirect is an absolute URL, not relative, so it includes the Hostname. To build that URL, starlette uses the Host header to find the hostname.
But, in the case of Heroku apps, many CDN setups etc there is a reverse proxy in front of the app. the proxy rewrite the request, puts your webservice into the Host header, and moves the client-side hostname used into the X-Forwarded-For header.
I imagine that ProxyHeadersMiddleware could do a similar swap as with forwarded-proto & forwarded-for, so the forwarded-host is put into the standard host header, so all apps can work with this.
Of course I could also imagine adapting starlette.datastructures.url, not sure what's the best place?
hi @syphar I dont maintain uvicorn anymore nor use it anymore, there are alternatives on pretty much all encode projects you may want to consider ;)
hi @syphar I dont maintain uvicorn anymore nor use it anymore, there are alternatives on pretty much all encode projects you may want to consider ;)
In case you want to provide more info, I don't mind you being more open. I think @euri10 meant (sorry if wrong):
Starlette/FastAPI > Litestar Uvicorn > Granian
What about httpx? aiohttp?
Starlette/FastAPI > Litestar Uvicorn > Granian
:) that's what I'm currently using but you can find many more on https://github.com/florimondmanca/awesome-asgi?tab=readme-ov-file#servers
What about httpx? aiohttp?
still in love httpx, with an aiohttp transport though, but recently https://github.com/MarkusSintonen/pyreqwest popped so that may be an interesting one, idk I never tested.
to be back on topic I would deal with proxy headers at the reverse proxy level and not the webserver, this makes more sense to me but ymmv
thank you for all your responses!
Do understand correctly that uvicorn is unmaintained then? And we should switch?
No, I'm maintaining it.
ah, that's good to hear, sorry vor the misunderstanding.
Do you see a use for the X-Forwarded-Host handling? Would you accept a PR?
Or do you see this somewhere else?
(edit: wrong header name)
yes, PR welcome.
For reference: https://werkzeug.palletsprojects.com/en/stable/middleware/proxy_fix/.