This commit is contained in:
2024-12-17 14:36:15 -08:00
parent b2dbf46d28
commit 06d106de53
17731 changed files with 3037186 additions and 144 deletions

View File

@@ -0,0 +1,82 @@
from urllib.parse import urlparse
from urllib.request import url2pathname
from django.conf import settings
from django.contrib.staticfiles import utils
from django.contrib.staticfiles.views import serve
from django.http import Http404
from .http import AsgiHandler
class StaticFilesWrapper:
"""
ASGI application which wraps another and intercepts requests for static
files, passing them off to Django's static file serving.
"""
def __init__(self, application, staticfiles_handler=None):
self.application = application
self.staticfiles_handler_class = staticfiles_handler or StaticFilesHandler
self.base_url = urlparse(self.get_base_url())
def get_base_url(self):
utils.check_settings()
return settings.STATIC_URL
def _should_handle(self, path):
"""
Checks if the path should be handled. Ignores the path if:
* the host is provided as part of the base_url
* the request's path isn't under the static files path (or equal)
"""
return path.startswith(self.base_url[2]) and not self.base_url[1]
async def __call__(self, scope, receive, send):
# Only even look at HTTP requests
if scope["type"] == "http" and self._should_handle(scope["path"]):
# Serve static content
return await self.staticfiles_handler_class()(
dict(scope, static_base_url=self.base_url), receive, send
)
# Hand off to the main app
return await self.application(scope, receive, send)
class StaticFilesHandler(AsgiHandler):
"""
Subclass of AsgiHandler that serves directly from its get_response.
"""
# TODO: Review hierarchy here. Do we NEED to inherit BaseHandler, AsgiHandler?
async def __call__(self, scope, receive, send):
self.static_base_url = scope["static_base_url"][2]
return await super().__call__(scope, receive, send)
def file_path(self, url):
"""
Returns the relative path to the media file on disk for the given URL.
"""
relative_url = url[len(self.static_base_url) :]
return url2pathname(relative_url)
def serve(self, request):
"""
Actually serves the request path.
"""
return serve(request, self.file_path(request.path), insecure=True)
def get_response(self, request):
"""
Always tries to serve a static file as you don't even get into this
handler subclass without the wrapper directing you here.
"""
try:
return self.serve(request)
except Http404 as e:
if settings.DEBUG:
from django.views import debug
return debug.technical_404_response(request, e)