Skip to content

Instantly share code, notes, and snippets.

@stuross
Created June 27, 2012 03:55
Show Gist options
  • Save stuross/3001276 to your computer and use it in GitHub Desktop.
Save stuross/3001276 to your computer and use it in GitHub Desktop.
django ssl middleware
from django.conf import settings
from django.http import HttpResponsePermanentRedirect
SSL = 'SSL'
class SSLRedirect(object):
"""SSL Middleware for views
Example usage:
`url(r'^my-secure-view/$', 'secure_view', {'SSL' : True}, name='my_secure_view'),`
"""
def process_request(self, request):
old_is_secure = request.is_secure
def new_is_secure():
if old_is_secure():
return True
if 'HTTP_X_FORWARDED_SSL' in request.META:
return request.META['HTTP_X_FORWARDED_SSL'] == 'on'
if 'HTTP_X_FORWARDED_PROTO' in request.META:
return request.META['HTTP_X_FORWARDED_PROTO'] == 'https'
return False
request.is_secure = new_is_secure
def process_view(self, request, view_func, view_args, view_kwargs):
secure = False
if getattr(settings, 'ALWAYS_USE_SSL', False):
secure = True
if request.path.startswith('/admin/'):
secure = True
elif request.path.startswith('/accounts/'):
secure = True
elif request.path.startswith('/account/'):
secure = True
if SSL in view_kwargs:
secure = view_kwargs[SSL]
del view_kwargs[SSL]
skip_redirect = (
request.path.startswith('/admin/lookups/')
)
if not skip_redirect and not settings.DEBUG and secure != request.is_secure():
return self._redirect(request, secure)
def _redirect(self, request, secure):
protocol = secure and 'https' or 'http'
new_url = '%s://%s%s' % (protocol, request.get_host(), request.get_full_path())
if settings.DEBUG and request.method == 'POST':
raise RuntimeError(u"Django can't perform an SSL redirect while maintaining POST dat. Your view needs to be restructured so that redirects only occur using GET")
return HttpResponsePermanentRedirect(new_url)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment