From ed351a53b6b5bd10854a41a8cf50d78aa30c30c4 Mon Sep 17 00:00:00 2001 From: Marcin Date: Thu, 11 Jun 2026 18:41:44 +0100 Subject: [PATCH] fix: ignore .woff2 and modern static-asset extensions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The static-asset ignore list predates woff2 and other modern web formats. Because matching is suffix-based, '.woff' does not cover '.woff2', so bot requests for woff2 fonts were proxied to the Prerender service instead of passing through. Verified live on prerender.io itself: Googlebot requesting inter-*.woff2 received a 504 while a normal UA received a 200 (.css/.js correctly bypassed). Adds .woff2, .otf, .eot, .webp, .avif and .webmanifest to EXTENSIONS_TO_IGNORE, per integration-contract CONTRACT.md section 3 (prerender/integration-contract#1). Also fixes _is_static_asset to lowercase the request path before the suffix check — the contract mandates case-insensitive matching, so '/STYLES.CSS' must pass through like '/styles.css'. Co-Authored-By: Claude Fable 5 --- prerender_django/middleware.py | 2 ++ tests/test_middleware.py | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/prerender_django/middleware.py b/prerender_django/middleware.py index 8429e38..154c0a6 100644 --- a/prerender_django/middleware.py +++ b/prerender_django/middleware.py @@ -25,6 +25,7 @@ '.exe', '.wmv', '.avi', '.ppt', '.mpg', '.mpeg', '.tif', '.wav', '.mov', '.psd', '.ai', '.xls', '.mp4', '.m4a', '.swf', '.dat', '.dmg', '.iso', '.flv', '.m4v', '.torrent', '.ttf', '.woff', '.svg', + '.woff2', '.otf', '.eot', '.webp', '.avif', '.webmanifest', ]) @@ -38,6 +39,7 @@ def _is_bot(user_agent): def _is_static_asset(path): + path = path.lower() return any(path.endswith(ext) for ext in EXTENSIONS_TO_IGNORE) diff --git a/tests/test_middleware.py b/tests/test_middleware.py index d78b9f5..e0311e6 100644 --- a/tests/test_middleware.py +++ b/tests/test_middleware.py @@ -51,6 +51,22 @@ def test_static_asset_with_bot_ua_passes_through(): assert response.content == b'original' +def test_font_asset_with_bot_ua_passes_through(): + middleware = PrerenderMiddleware(normal_response) + request = factory.get('/fonts/inter.woff2', HTTP_USER_AGENT=BOT_UA) + response = middleware(request) + assert response.status_code == 200 + assert response.content == b'original' + + +def test_uppercase_static_asset_with_bot_ua_passes_through(): + middleware = PrerenderMiddleware(normal_response) + request = factory.get('/STYLES.CSS', HTTP_USER_AGENT=BOT_UA) + response = middleware(request) + assert response.status_code == 200 + assert response.content == b'original' + + def test_escaped_fragment_triggers_prerender(): middleware = PrerenderMiddleware(normal_response) request = factory.get('/', {'_escaped_fragment_': ''}, HTTP_USER_AGENT=BROWSER_UA)