11
votes

In my Flask config, I'm setting SERVER_NAME to a domain like "app.example.com". I'm doing that because I need to use url_for with _external URLs. If SERVER_NAME is not set, Flask thinks the server is 127.0.0.1:5000 (it's actually running behind a reverse-proxy), and returns an external URL like http://127.0.0.1:5000/location.

So far so good. But here's my problem: With SERVER_NAME set, every URL returns 404. I see each request hitting the server, to the correct URL, but Flask responds with a 404. If I disable SERVER_NAME, the correct page is returned.

I'm using Apache with ProxyPass and ProxyPassReverse (I know, I'd rather use Nginx, but it's a requirement). Here are the headers I'm adding:

Header add Host "app.example.com"
RequestHeader set Host "app.example.com"

Header add X-Forwarded-Host "app.example.com"
RequestHeader set X-Forwarded-Host "app.example.com"

Any ideas?

1

1 Answers

17
votes

Just found the answer. Apache has an option called ProxyPreserveHost. Once it's set to On, everything works as expected.

More information here: http://flask.pocoo.org/mailinglist/archive/2011/3/14/problem-with-apache-proxy-and-canonical-urls/