[Feature] Serve pre-compressed static files (.br, .gz)
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 55/100
Research direction
Start with src/Middleware/StaticFilesMiddleware.php, especially the response logic at lines 112 and 121-125, generateEtag() at lines 157-160, and the realpath cache key at line 294. Trace the existing block checks and file response behavior before adding coverage for encoding negotiation, content type, ETags, missing originals, and blocked x.php.gz files. Done includes the default [] behavior and updates to docs/middlewares.md and docs/security.md.
Written by the indexing model from the issue text.
Description
Problem
StaticFilesMiddleware always sends the plain file. It never looks for a compressed copy.
src/Middleware/StaticFilesMiddleware.php:121-125: the response iswithFile($filePath)withLast-Modified,ETagandCache-Control. There is noContent-Encodingand noVaryheader.src/Middleware/StaticFilesMiddleware.php:112: whenfilemtime()fails, it also sends the plain file.grep -rni "accept-encoding\|content-encoding\|gzip" srcfinds nothing.- Build tools (Vite, Webpack) can write
app.js.brandapp.js.gznext toapp.js. Today the worker does not use these files. It sends the big file.
Most production setups serve static files from nginx, Caddy or a CDN. So this helps mostly small setups, or setups with only one container.
Idea
A new constructor argument precompressed for StaticFilesMiddleware:
services:
app.static_files:
class: CrazyGoat\WorkermanBundle\Middleware\StaticFilesMiddleware
arguments:
$rootDirectory: '%kernel.project_dir%/public'
$precompressed: ['br', 'gzip']
For a request to /build/app.js:
- Read
Accept-Encodingfrom the request. - Check the list in order:
br->app.js.br,gzip->app.js.gz. - If the client accepts the encoding and the file is there, send it with
Content-Encoding: br(orgzip). - When the option is on, always send
Vary: Accept-Encoding. - Else send the plain file, like today.
The default is []. So nothing changes for current users.
Seen in
- Caddy
file_server { precompressed br gzip }(also used by FrankenPHP) - nginx
gzip_static onandbrotli_static on
Risks
Content-Type: Workerman takes the type from the extension of the sent file (Response::createHeadForFile()). Forapp.js.brthe type is wrong. If the type isapplication/octet-stream, Workerman also addsContent-Disposition: attachment. The middleware must setContent-Typefrom the original name.ETag:generateEtag()(StaticFilesMiddleware.php:157-160) uses only mtime and path. Each encoding needs its own ETag (for example a-brsuffix). Else caches can mix the files.- The realpath cache key (
StaticFilesMiddleware.php:294) must include the variant. - The
.brand.gzfiles must pass the same block checks as the plain file.gzis not in the block lists, butx.php.gzis blocked today (LEAK_EXTENSIONS, line 13). This must stay so. - The plain file must exist too. Do not send a
.gzfile when there is no plain file. - It is better to fix the open static file issues first: #977, #940, #904, #903.
Done when
- A test shows: with
Accept-Encoding: br, gzipandapp.js.bron disk, the body is the.brfile, withContent-Encoding: br,Vary: Accept-Encodingand theContent-Typefor.js. - A test shows: without
Accept-Encoding, the plain file is sent. - A test shows: the ETag of the
.branswer is not the same as the ETag of the plain answer. - A test shows: a
.gzfile with no plain file next to it is not sent. - A test shows:
x.php.gzis still blocked. - The default
[]keeps the old behaviour. -
docs/middlewares.mdanddocs/security.mddescribe the option.
- Dominant language
- PHP
- Stars
- 2
- Forks
- 3
- Avg merge
- 7h 15m
- Merged PRs (30d)
- 97
Getting set up
- Ships a Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from crazy-goat/workerman-bundle
-
[Tests] TaskTest::testTaskIsRunning is flaky on slow CI runners (4 s recency window)Possibly taken @rootsiemen claimed this 5 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
crazy-goat/workerman-bundle#1081 ·
Maintainers usually reply within 1 day
-
[Tests] ComposerAuditE2ETest fails on packagist.org network timeoutsPossibly taken @rootsiemen claimed this 5 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 80/100
crazy-goat/workerman-bundle#1080 ·
Maintainers usually reply within 1 day
-
[Tests] Matrix sed rewrite class [a-z-]+ excludes digits — future symfony/foo2bar silently skippedPossibly taken @rootsiemen claimed this 4 days ago. Openpriority:low type:refactor
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
crazy-goat/workerman-bundle#1060 ·
Maintainers usually reply within 1 day
-
[Code Quality] SfxDownloader extract path has no destination-writability pre-check for cached zipsPossibly taken @rootsiemen claimed this 7 days ago. Openpriority:low type:refactor
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
crazy-goat/workerman-bundle#1052 ·
Maintainers usually reply within 1 day
-
[Code Quality] Runner env-drift re-warm wrapper throws bare RuntimeException outside WorkermanExceptionInterfacePossibly taken @rootsiemen claimed this 13 days ago. Openpriority:low type:refactor
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
crazy-goat/workerman-bundle#1040 ·
Maintainers usually reply within 1 day
All issues in crazy-goat/workerman-bundle
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
MISP/misp-docker#478 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
glpi-project/glpi#26045 ·
Maintainers usually reply within 1 day
-
sync-en
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
sync-en
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 2 days
-
Перевод устарел
Difficulty 2/5 1-3 hours Newbie friendliness 82/100