diff --git a/innovedus_cms/mysite/urls.py b/innovedus_cms/mysite/urls.py index 382f332..c4da4d4 100644 --- a/innovedus_cms/mysite/urls.py +++ b/innovedus_cms/mysite/urls.py @@ -11,6 +11,7 @@ from search import views as search_views from home.feeds import LatestArticlesFeed from home import views as home_views from base import views as base_views +from mysite import views as mysite_views urlpatterns = [ path("django-admin/", admin.site.urls), @@ -18,6 +19,7 @@ urlpatterns = [ path("documents/", include(wagtaildocs_urls)), path("feed.xml", LatestArticlesFeed(), name="article_feed"), path("sitemap.xml", sitemap, name="sitemap"), + path("media/", mysite_views.media_proxy, name="media_proxy"), path("health", base_views.health_check, name="health_check"), # use so Unicode tag slugs (e.g. 台北美食) still resolve path("tags//", home_views.hashtag_search, name="hashtag_search"), diff --git a/innovedus_cms/mysite/views.py b/innovedus_cms/mysite/views.py new file mode 100644 index 0000000..33cb9b4 --- /dev/null +++ b/innovedus_cms/mysite/views.py @@ -0,0 +1,25 @@ +import mimetypes +import posixpath + +from django.core.exceptions import SuspiciousFileOperation +from django.core.files.storage import default_storage +from django.http import FileResponse, Http404 + + +def media_proxy(request, path): + normalized_path = posixpath.normpath(path).lstrip("/") + if ( + not normalized_path + or normalized_path == "." + or normalized_path.startswith("../") + or path.startswith("/") + ): + raise SuspiciousFileOperation("Invalid media path") + + try: + file_obj = default_storage.open(normalized_path, "rb") + except FileNotFoundError as exc: + raise Http404("Media file not found") from exc + + content_type, _ = mimetypes.guess_type(normalized_path) + return FileResponse(file_obj, content_type=content_type)