diff --git a/pylib/djangomiddleware/redirect_middleware.py b/pylib/djangomiddleware/redirect_middleware.py index 6292ca65..2544eba0 100644 --- a/pylib/djangomiddleware/redirect_middleware.py +++ b/pylib/djangomiddleware/redirect_middleware.py @@ -4,7 +4,9 @@ import logging from django.http import HttpResponseRedirect -from django.contrib.sites.models import Site +from django.conf import settings +from django.core.exceptions import ImproperlyConfigured + class FullyQualifiedRedirectMiddleware(object): def process_response(self, request, response): @@ -24,12 +26,32 @@ def process_response(self, request, response): if not (parsed_location.scheme and parsed_location.netloc): new_location = list(parsed_location) - # FIXME - we can do better than hardcoding this - new_location[0] = 'http' - new_location[1] = Site.objects.get_current().domain + new_location[0] = 'https' if self.request_is_secure(request) else 'http' + new_location[1] = request.get_host() new_location[2] = urlparse.urljoin(request.META['PATH_INFO'], parsed_location.path) - + response['Location'] = urlparse.urlunparse(new_location) return response + def request_is_secure(self, request): + """Check if a request is secure""" + # From Django 1.4 onwards request.is_secure() takes care of identifying + # secure requests forwarded via a proxy, by checking the header given + # in the SECURE_PROXY_SSL_HEADER setting. + # See: https://docs.djangoproject.com/en/1.4/ref/settings/#secure-proxy-ssl-header + # Older versions would always return false if the request was being + # forwarded by a proxy, since they would see only http. + # Therefore, we duplicate the functionality from: + # https://github.com/django/django/blob/master/django/http/request.py + # here, so that older versions can use the setting too. + # Remember to set it correctly! + if settings.SECURE_PROXY_SSL_HEADER: + try: + header, value = settings.SECURE_PROXY_SSL_HEADER + except ValueError: + raise ImproperlyConfigured('The SECURE_PROXY_SSL_HEADER setting must be a tuple containing two values.') + if request.META.get(header, None) == value: + return True + else: + return request.is_secure()