You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

65 lines
2.3 KiB

  1. from django.conf import settings
  2. from django.contrib.staticfiles import utils
  3. from django.contrib.staticfiles.views import serve
  4. from django.core.handlers.wsgi import WSGIHandler, get_path_info
  5. from django.utils.six.moves.urllib.parse import urlparse
  6. from django.utils.six.moves.urllib.request import url2pathname
  7. class StaticFilesHandler(WSGIHandler):
  8. """
  9. WSGI middleware that intercepts calls to the static files directory, as
  10. defined by the STATIC_URL setting, and serves those files.
  11. """
  12. # May be used to differentiate between handler types (e.g. in a
  13. # request_finished signal)
  14. handles_files = True
  15. def __init__(self, application):
  16. self.application = application
  17. self.base_url = urlparse(self.get_base_url())
  18. super(StaticFilesHandler, self).__init__()
  19. def get_base_url(self):
  20. utils.check_settings()
  21. return settings.STATIC_URL
  22. def _should_handle(self, path):
  23. """
  24. Checks if the path should be handled. Ignores the path if:
  25. * the host is provided as part of the base_url
  26. * the request's path isn't under the media path (or equal)
  27. """
  28. return path.startswith(self.base_url[2]) and not self.base_url[1]
  29. def file_path(self, url):
  30. """
  31. Returns the relative path to the media file on disk for the given URL.
  32. """
  33. relative_url = url[len(self.base_url[2]):]
  34. return url2pathname(relative_url)
  35. def serve(self, request):
  36. """
  37. Actually serves the request path.
  38. """
  39. return serve(request, self.file_path(request.path), insecure=True)
  40. def get_response(self, request):
  41. from django.http import Http404
  42. if self._should_handle(request.path):
  43. try:
  44. return self.serve(request)
  45. except Http404 as e:
  46. if settings.DEBUG:
  47. from django.views import debug
  48. return debug.technical_404_response(request, e)
  49. return super(StaticFilesHandler, self).get_response(request)
  50. def __call__(self, environ, start_response):
  51. if not self._should_handle(get_path_info(environ)):
  52. return self.application(environ, start_response)
  53. return super(StaticFilesHandler, self).__call__(environ, start_response)