浏览代码

Add Cache-Control header to static files (#3865)

As discussed in https://github.com/zauberzeug/nicegui/discussions/3858,
this PR adds `Cache-Control` header to the framework and custom static
files.

---------

Co-authored-by: Falko Schindler <falko@zauberzeug.com>
Henry Zhu 7 月之前
父节点
当前提交
5e39a4159d
共有 4 个文件被更改,包括 16 次插入4 次删除
  1. 2 2
      nicegui/app/app.py
  2. 2 2
      nicegui/nicegui.py
  3. 11 0
      nicegui/staticfiles.py
  4. 1 0
      tests/test_serving_files.py

+ 2 - 2
nicegui/app/app.py

@@ -9,7 +9,6 @@ from typing import Any, Awaitable, Callable, List, Optional, Union
 
 from fastapi import FastAPI, HTTPException, Request, Response
 from fastapi.responses import FileResponse
-from fastapi.staticfiles import StaticFiles
 
 from .. import background_tasks, helpers
 from ..client import Client
@@ -17,6 +16,7 @@ from ..logging import log
 from ..native import NativeConfig
 from ..observables import ObservableSet
 from ..server import Server
+from ..staticfiles import CacheControlledStaticFiles
 from ..storage import Storage
 from .app_config import AppConfig
 from .range_response import get_range_response
@@ -157,7 +157,7 @@ class App(FastAPI):
         if url_path == '/':
             raise ValueError('''Path cannot be "/", because it would hide NiceGUI's internal "/_nicegui" route.''')
 
-        handler = StaticFiles(directory=local_directory, follow_symlink=follow_symlink)
+        handler = CacheControlledStaticFiles(directory=local_directory, follow_symlink=follow_symlink)
 
         @self.get(url_path + '/{path:path}')
         async def static_file(request: Request, path: str = '') -> Response:

+ 2 - 2
nicegui/nicegui.py

@@ -9,7 +9,6 @@ import socketio
 from fastapi import HTTPException, Request
 from fastapi.middleware.gzip import GZipMiddleware
 from fastapi.responses import FileResponse, Response
-from fastapi.staticfiles import StaticFiles
 
 from . import air, background_tasks, binding, core, favicon, helpers, json, run, welcome
 from .app import App
@@ -21,6 +20,7 @@ from .logging import log
 from .middlewares import RedirectWithPrefixMiddleware
 from .page import page
 from .slot import Slot
+from .staticfiles import CacheControlledStaticFiles
 from .version import __version__
 
 
@@ -56,7 +56,7 @@ mimetypes.add_type('text/css', '.css')
 
 app.add_middleware(GZipMiddleware)
 app.add_middleware(RedirectWithPrefixMiddleware)
-static_files = StaticFiles(
+static_files = CacheControlledStaticFiles(
     directory=(Path(__file__).parent / 'static').resolve(),
     follow_symlink=True,
 )

+ 11 - 0
nicegui/staticfiles.py

@@ -0,0 +1,11 @@
+from starlette.responses import Response
+from starlette.staticfiles import StaticFiles
+from starlette.types import Scope
+
+
+class CacheControlledStaticFiles(StaticFiles):
+
+    async def get_response(self, path: str, scope: Scope) -> Response:
+        response = await super().get_response(path, scope)
+        response.headers['Cache-Control'] = 'public, max-age=3600'
+        return response

+ 1 - 0
tests/test_serving_files.py

@@ -61,6 +61,7 @@ def test_get_from_static_files_dir(url_path: str, screen: Screen):
     with httpx.Client() as http_client:
         r = http_client.get(f'http://localhost:{Screen.PORT}/static/examples/slideshow/slides/slide1.jpg')
         assert r.status_code == 200
+        assert 'max-age=' in r.headers['Cache-Control']
 
 
 def test_404_for_non_existing_static_file(screen: Screen):