# https://gist.github.com/bryanchow/6917ddc1823c09b5cc9f import re from django.http import HttpResponseRedirect from django.conf import settings SHOULD_REDIRECT_SSL = getattr( settings, 'SHOULD_REDIRECT_SSL', not settings.DEBUG ) SSL_URLS = getattr(settings, 'SSL_URLS', []) SSL_IGNORE_URLS = getattr(settings, 'SSL_IGNORE_URLS', []) class SSLRedirectMiddleware: secure_urls = tuple([re.compile(url) for url in SSL_URLS]) ignore_urls = tuple([re.compile(url) for url in SSL_IGNORE_URLS]) def process_request(self, request): if not SHOULD_REDIRECT_SSL: return secure = False ignore = False for url in self.ignore_urls: if url.match(request.path): ignore = True break if not ignore: for url in self.secure_urls: if url.match(request.path): secure = True break if not secure == self._is_secure(request): return self._redirect(request, secure) def _is_secure(self, request): if request.is_secure(): return True return False def _redirect(self, request, secure): protocol = secure and "https" or "http" if secure: host = getattr(settings, 'SSL_HOST', request.get_host()) else: host = getattr(settings, 'HTTP_HOST', request.get_host()) new_url = "%s://%s%s" % (protocol, host, request.get_full_path()) if settings.DEBUG and request.method == 'POST': raise RuntimeError, ( "Django can't perform a SSL redirect while maintaining POST " "data. Please structure your views so that redirects only " "occur during GETs." ) return HttpResponseRedirect(new_url)