Skip to content

Use weak comparison and accept lists and * in Plug.Static If-None-Match - #1338

Open
wleeaf wants to merge 1 commit into
elixir-plug:mainfrom
wleeaf:static-if-none-match-list
Open

wleeaf wants to merge 1 commit into
elixir-plug:mainfrom
wleeaf:static-if-none-match-list

Conversation

@wleeaf

@wleeaf wleeaf commented Oct 25, 2026

Copy link
Copy Markdown

Plug.Static returns 304 only when an If-None-Match header value is exactly its ETag. RFC 9110 section 13.1.2 defines the field as * or a comma-separated list of entity tags, compared with the weak comparison function, which ignores the W/ prefix. So these requests all get a full 200 today even though the file is unchanged:

  • If-None-Match: W/"<etag>"
  • If-None-Match: "other", "<etag>"
  • If-None-Match: *

The W/ case is the one in #1133. Cloudflare weakens the ETag when it compresses a response, so browsers behind it send W/"<etag>" back and never get a 304. That issue was about whether Plug's ETag itself should be weak. This change leaves the ETag as it is and only fixes the comparison, which the RFC requires to be weak for If-None-Match.

put_cache_header/6 now splits each If-None-Match value with Plug.Conn.Utils.list/1. It treats the request as fresh when an element is *, or when it equals the ETag once a W/ prefix is removed from both. A value that is exactly the ETag still matches without splitting, so a custom :etag_generation value that contains a comma behaves as before.

The new test "performs etag negotiation with weak etags, lists and *" checks:

  • The weak form, a list containing the ETag (with and without W/), and * get 304.
  • A different ETag and a list without the ETag still get 200.

Without the change, the test fails on the weak form. With it, mix test passes (616 tests) and mix format --check-formatted is clean.

The two Plug.Static changes are independent and merge cleanly together.

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.

1 participant