﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
19517	Add support for X-Forwarded-Port to HttpRequest.get_host when USE_X_FORWARDED_HOST is in use	david_k_hess@…	nobody	"The use case is an app served on ports 80, 443 (SSL) and 444 (SSL) served by gunicorn behind nginx. I'm sending X-Forwarded-Host and X-Forwarded-Port from nginx to gunicorn. Port 80 is open solely to redirect to 443 and both are open to the public internet. 444 is firewalled and reserved for the admin interface which is protected by this middleware component:

{{{
class ProtectAdminMiddleware(object):
    def process_request(self, request):
        if request.path.startswith(""/admin"") and request.META[""HTTP_X_FORWARDED_PORT""] != ""444"":
            raise Http404
}}}

When turning on USE_X_FORWARDED_HOST, the code in HttpRequest.get_host does not take port into account:

{{{
    [...]
    if settings.USE_X_FORWARDED_HOST and (
        'HTTP_X_FORWARDED_HOST' in self.META):
        host = self.META['HTTP_X_FORWARDED_HOST']
    elif 'HTTP_HOST' in self.META:
        host = self.META['HTTP_HOST']
    [...]
}}}

Because of this, at least two things in the admin interface on port 444 don't function correctly; the CSRF token breaks saying there is a problem between referrer on 444 and token on 443 and you can't login. Also, redirects from say ""/admin"" on port 444 redirect to ""/admin/"" on 443 instead of staying on 444. That's just what I was able to reach with logins broken.

I monkey-patched HttpRequest.get_host to add support for X-Forwarded-Port when USE_X_FORWARDED_HOST is specified and it appears to have corrected these issues:

{{{
    [...]
    if settings.USE_X_FORWARDED_HOST and (
        'HTTP_X_FORWARDED_HOST' in self.META):
        host = self.META['HTTP_X_FORWARDED_HOST']
        if 'HTTP_X_FORWARDED_PORT' in self.META:
            server_port = str(self.META['HTTP_X_FORWARDED_PORT'])
            if server_port != (self.is_secure() and '443' or '80'):
                host = '%s:%s' % (host, server_port)
    elif 'HTTP_HOST' in self.META:
        host = self.META['HTTP_HOST']
    [...]
}}}"	Bug	closed	HTTP handling	1.4	Normal	wontfix	httprequest, get_host, X-Forwarded-Host, USE_X_FORWARDED_HOST	hirokiky@… matt@…	Accepted	1	0	0	0	1	0
