Skip to content

fix(citizen-server-impl): expose ETag and Cache-Control headers on /files endpoint#3994

Closed
KAZRUTx wants to merge 1 commit into
citizenfx:masterfrom
KAZRUTx:fix/files-endpoint-cache-headers
Closed

fix(citizen-server-impl): expose ETag and Cache-Control headers on /files endpoint#3994
KAZRUTx wants to merge 1 commit into
citizenfx:masterfrom
KAZRUTx:fix/files-endpoint-cache-headers

Conversation

@KAZRUTx
Copy link
Copy Markdown

@KAZRUTx KAZRUTx commented May 17, 2026

Add standard HTTP cache validation headers to the /files endpoint so that CDN and caching proxies can correctly revalidate file changes instead of serving stale content.

Goal of this PR

The /files endpoint currently returns 200 OK with only content-length and transfer-encoding headers, with no cache validation support. When placed behind a CDN or caching proxy, this causes updated resource files to remain stale until the cache is manually purged, since the proxy has no way to know the file has changed.

How is this PR achieving the goal

  • Reads the existing file hash from ResourceFilesComponent::GetFileHashPairs() and exposes it as an ETag response header — no new data is computed, the hash was already being retrieved but unused in the response path
  • Handles incoming If-None-Match request headers — if the client's ETag matches the current file hash, returns 304 Not Modified instead of transferring the full file, saving bandwidth
  • Adds Cache-Control: public, max-age=0, must-revalidate to ensure proxies and CDNs always revalidate before serving cached files, preventing stale content from being served after resource updates

This PR applies to the following area(s)

FiveM

Successfully tested on

Game builds: 3258
Platforms: Windows

Checklist

  • Code compiles and has been tested successfully.
  • Code explains itself well and/or is documented.
  • My commit message explains what the changes do and what they are for.
  • No extra compilation warnings are added by these changes.

Fixes issues

fixes #3918

@github-actions github-actions Bot added invalid Requires changes before it's considered valid and can be (re)triaged triage Needs a preliminary assessment to determine the urgency and required action and removed invalid Requires changes before it's considered valid and can be (re)triaged triage Needs a preliminary assessment to determine the urgency and required action labels May 17, 2026
@AvarianKnight
Copy link
Copy Markdown
Contributor

Is this not an issue with the proxy server, since most should do a cache break on a query parameter being changed (that being /sessionmanager/resource.rpf?hash={some_long_hash}

It would probably still make sense to have this, but this also sounds a lot like a weird proxy config.

@AngeloneISL
Copy link
Copy Markdown

i have a problem with caching files ever since i have started using a proxy for my server

some of the files fail to download and return error 403 filter failed as if the url is invalid

is that related in some way to what you are fixing here?

@AvarianKnight
Copy link
Copy Markdown
Contributor

AvarianKnight commented May 17, 2026

i have a problem with caching files ever since i have started using a proxy for my server

some of the files fail to download and return error 403 filter failed as if the url is invalid

is that related in some way to what you are fixing here?

That doesn't sound related to this at all, do you have proxy_cache_valid 200 {{ cache_ttl }}; set on your nginx?

It sounds like you're accidentally caching error responses, 403 should only be given when a client didn't connect prior to trying to access /files/

@KAZRUTx
Copy link
Copy Markdown
Author

KAZRUTx commented May 17, 2026

Is this not an issue with the proxy server, since most should do a cache break on a query parameter being changed (that being /sessionmanager/resource.rpf?hash={some_long_hash}

It would probably still make sense to have this, but this also sounds a lot like a weird proxy config.

That's a fair point. Query parameter cache busting works in many setups,
but some CDNs ignore query strings by default unless explicitly configured.

Standard ETag/If-None-Match support complements this by providing proper
HTTP-level validation — allowing proxies to confirm freshness with a
lightweight 304 instead of re-downloading, which is more robust and
RFC-compliant regardless of CDN configuration.

@AngeloneISL
Copy link
Copy Markdown

i have a problem with caching files ever since i have started using a proxy for my server
some of the files fail to download and return error 403 filter failed as if the url is invalid
is that related in some way to what you are fixing here?

That doesn't sound related to this at all, do you have proxy_cache_valid 200 {{ cache_ttl }}; set on your nginx?

It sounds like you're accidentally caching error responses, 403 should only be given when a client didn't connect prior to trying to access /files/

i am using the default configuration
https://docs.fivem.net/docs/cookbook/2019/10/29/optimizing-resource-downloads-using-a-caching-proxy/

been using this for ages now without any problem

ever since i started hiding the real ip address ( the nginx is hosted on the same server and uses the unfiltered port )
using sv_endpoints this problem started occuring

@yorick2002
Copy link
Copy Markdown
Contributor

Hello Claude expose ETag and Cache-Control headers on /files endpoint make no mistakes

@KAZRUTx
Copy link
Copy Markdown
Author

KAZRUTx commented May 17, 2026

Hello Claude expose ETag and Cache-Control headers on /files endpoint make no mistakes

Yes I used AI for navigating the codebase and formatting the final PR description firstly wrote by me. I don't see what's wrong with that as it's just a tool like any other. The fix itself I investigated it understood and tested it. Whats wrong? It fixes the bug? Is it contributing to make FiveM better? I use AI to format things such as PR because im not that good at grammar in english and i want to have things nice and clean. And i wanted to help to FiveM. Then i dont see whats wrong

@AvarianKnight
Copy link
Copy Markdown
Contributor

Hello Claude expose ETag and Cache-Control headers on /files endpoint make no mistakes

Yes I used AI for navigating the codebase and formatting the final PR description firstly wrote by me. I don't see what's wrong with that as it's just a tool like any other. The fix itself I investigated it understood and tested it. Whats wrong? It fixes the bug? Is it contributing to make FiveM better? I use AI to format things such as PR because im not that good at grammar in english and i want to have things nice and clean. And i wanted to help to FiveM. Then i dont see whats wrong

It generally just feels like a waste of time when your response seems completely AI generated. The response you gave made it seem like you put it into an LLM and said "write a response to this".

Also this doesn't seem like a great way to fix this either. It would make sense to have Cache-Control and ETag but also we shouldn't need to re-validate this every time, this is doing an extra call and adding extra latency for no reason.

This overall seems to try to fix a misconfiguration on whoever setup their proxy server, whoever set up their proxy and is having this issue should refer to the docs, notably proxy_cache_key $request_uri$is_args$args; where it specifically caches based on the request_uri, which will include the ?hash={xxx} query and cache based on that.

@KAZRUTx
Copy link
Copy Markdown
Author

KAZRUTx commented May 17, 2026

Thanks for feedback. I'm a student and this was my first attempt to contribute to something as big as FiveM which has always been a milestone I wanted to reach. I'll look into things more carefully next time before submitting and make the description of my work by myself. Appreciate the explanation i learned a lot from that :)

@KAZRUTx KAZRUTx closed this May 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

invalid Requires changes before it's considered valid and can be (re)triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

files endpoint does not expose HTTP cache validation headers, causing stale CDN cache

4 participants