Repository navigation
Local file endpoint: send cache validators and answer conditional requests #17325
woerndl
started this conversation in
Feature Requests & Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Description
The local file endpoint (
packages/payload/src/uploads/endpoints/getFile.ts) streams files without cache validators. It setsContent-Type,Content-Length, andAccept-Ranges, but noETagand noLast-Modified, and it never readsIf-None-MatchorIf-Modified-Since.If you serve uploads from local disk and set a
Cache-Controlmax-age throughupload.modifyResponseHeaders:Each of those requests could be a
304 Not Modified. The handler already callsfsPromises.staton every request, so everything needed for aLast-Modifiedheader (or a weakETagfrom size and mtime) is already read, then thrown away.Why the config options can't fix this
upload.modifyResponseHeadersonly gets{ headers }. No document, no filename, no file stats, so it can't compute a per-file validator. It also can't answer with a 304, because the conditional check needs the request.upload.handlersget the request and the document and can return a fullResponse. But a handler that returns nothing falls through to the default path, which builds a freshHeadersobject, so any headers the handler set are dropped. To attach a validator to the 200 you have to serve the whole response yourself: content type detection,Content-Length, range requests, the SVGContent-Security-Policy, and the CORS headers thatheadersWithCorsnormally adds. And then keep that copy in sync withgetFileHandleracross Payload upgrades.Proposal
Either of these would work:
getFileHandler. SetLast-Modifiedfrom the existingstatresult, maybe a weakETagfrom size and mtime, answerIf-None-MatchandIf-Modified-Sincewith304 Not Modified, and send the same cache headers on the 304 as on the 200.If-None-Matchwins when both are present.Responsedirectly. Then users can add validators without copying the streaming path.Option 1 seems like the better fit for local disk. Cloud storage handlers return their own
Responsebefore this code runs, so they're not affected.Versions
main(2026-07-14): still no validators, no conditional handling, andmodifyResponseHeadersstill only gets{ headers }.staticDir, no storage adapter), where the behavior is the same. Posting as a v4 feature request since v3 only takes bug fixes.All reactions