Skip to content

fix(fs): don't remove stale compressed files of a custom FS.FS from disk - #2489

Merged
erikdubbelboer merged 1 commit into
valyala:masterfrom
Thanatos9404:fix/fs-fs-stale-cache-remove
Oct 19, 2026
Merged

erikdubbelboer merged 1 commit into
valyala:masterfrom
Thanatos9404:fix/fs-fs-stale-cache-remove

Conversation

@Thanatos9404

Copy link
Copy Markdown
Contributor

When FS.Compress is on and a custom FS.FS contains a precompressed file (for example app.js.fasthttp.gz) that is older than the original, openFSFile treats it as stale and calls os.Remove(filePath) before compressing again. For a custom FS.FS, filePath is a name inside that filesystem, such as app.js.fasthttp.gz, so os.Remove resolves it against the process working directory instead. It deletes whatever file has that name relative to the working directory, and it can't remove the stale file anyway since an fs.FS is read-only here.

This change only removes the stale file for the default OS filesystem. For a custom FS.FS the file is compressed again in memory, which is what already happened after the removal.

Behavior change

With FS: os.DirFS(".") (or another os.DirFS whose directory is the working directory), the relative name used to point at the real stale file, so it got deleted as a side effect. It now stays on disk, and a request for it is compressed in memory on each cache miss until the file is regenerated or removed by other means. Serving the default OS filesystem (FS.FS nil) is unchanged.

Test

TestFSFSStaleCompressedFileNotRemovedFromDisk serves a fstest.MapFS with a fresh page.html and an hour older page.html.fasthttp.gz, from a temporary working directory that holds an unrelated page.html.fasthttp.gz. It checks that the response is the original compressed again and that the file in the working directory is still there. It fails on master and passes with this change.

Ran go test -shuffle=on ./... on Windows and the root package on Linux, go vet ./... for windows, linux and darwin, gofmt -l ., and golangci-lint run ./... (0 issues on linux).

When FS found a precompressed file in a custom FS.FS whose original was
newer, it removed the compressed file with os.Remove before compressing
again. The name is relative to the FS.FS, not to the working directory,
so this removed whatever file had the same relative name in the working
directory, and never the stale file itself unless FS.FS happened to be
os.DirFS(".").

Only remove stale compressed files for the default OS filesystem. For a
custom FS.FS the file is compressed again in memory, as before.
@erikdubbelboer
erikdubbelboer merged commit b679399 into valyala:master Oct 19, 2026
8 checks passed
@erikdubbelboer

Copy link
Copy Markdown
Collaborator

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants