/django/middleware/ssl.py

https://code.google.com/p/mango-py/ · Python · 59 lines · 43 code · 12 blank · 4 comment · 17 complexity · 126229fd086e0212f8b01c3945298d5d MD5 · raw file

  1. # -*- coding: utf-8 -*-
  2. __license__ = "Python"
  3. __copyright__ = "Copyright (C) 2007, Stephen Zabel"
  4. __author__ = "Stephen Zabel - sjzabel@gmail.com"
  5. __contributors__ = "Jay Parlar - parlar@gmail.com"
  6. from django.conf import settings
  7. from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect, get_host
  8. SSL = 'SSL'
  9. class SSLRedirect:
  10. def process_request(self, request):
  11. ssl_force = getattr(settings, 'SSL_FORCE', None)
  12. if settings.SSL_ENABLED and ssl_force:
  13. if not self._is_secure(request):
  14. return self._redirect(request, True)
  15. return None
  16. def process_view(self, request, view_func, view_args, view_kwargs):
  17. if SSL in view_kwargs:
  18. secure = view_kwargs[SSL]
  19. del view_kwargs[SSL]
  20. else:
  21. # none means I don't care if its secure or not, just let the request through
  22. return None
  23. if (not secure == self._is_secure(request)) and settings.SSL_ENABLED:
  24. return self._redirect(request, secure)
  25. def _is_secure(self, request):
  26. if request.is_secure():
  27. return True
  28. #Handle the Webfaction case until this gets resolved in the request.is_secure()
  29. if 'HTTP_X_FORWARDED_SSL' in request.META:
  30. return request.META['HTTP_X_FORWARDED_SSL'] == 'on'
  31. return False
  32. def _redirect(self, request, secure):
  33. protocol = secure and "https" or "http"
  34. host = get_host(request)
  35. # if we are being proxied use the default behavoir. Thus proxied servers will only work if outside the proxy they look like they are on standard ports.
  36. if 'HTTP_X_FORWARDED_HOST' not in request.META:
  37. if hasattr(settings,'HTTP_REDIRECT_TO_HTTPS'):
  38. host = settings.HTTP_REDIRECT_TO_HTTPS
  39. if hasattr(settings,'HTTP_REDIRECT_TO_HTTPS_PORT'):
  40. host = host.split(":")[0] + ":" + str(settings.HTTP_REDIRECT_TO_HTTPS_PORT)
  41. newurl = "%s://%s%s" % (protocol,host,request.get_full_path())
  42. if settings.DEBUG and request.method == 'POST':
  43. raise RuntimeError, \
  44. """Django can't perform a SSL redirect while maintaining POST data.
  45. Please structure your views so that redirects only occur during GETs."""
  46. return HttpResponsePermanentRedirect(newurl)