FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Inconsistent Vary/Cache-Control across conneg variants causes stale-render race on reload · Issue #315 · JavaScriptSolidServer/JavaScriptSolidServer · GitHub

Repository navigation

Inconsistent Vary/Cache-Control across conneg variants causes stale-render race on reload #315

Closed

Description

Symptom

Loading https://<pod>/profile/card.jsonld#me in a browser sometimes renders the mashlib data-browser view (expected), and sometimes renders raw RDF text (Turtle or JSON-LD) depending on cache state. A hard refresh always produces the mashlib view; a soft refresh can produce the raw text.

Root cause

Not a mashlib/webpack race — it's a JSS response-header inconsistency.

Variant (by Accept) Vary Cache-Control
text/html (mashlib HTML wrapper) Accept no-store
text/turtle Accept, Origin (missing)
application/ld+json Accept, Origin (missing)

Two problems:

  1. Vary mismatch across variants — some browser caches (observed in Brave/Chromium) get confused when variants of the same URL carry different Vary sets, and can serve the wrong variant on a matching request.
  2. Data variants have no Cache-Control — mashlib does an XHR for Turtle to populate the view; that response gets cached aggressively. On a soft refresh, the browser can serve the cached Turtle entry against the top-level HTML navigation.

Hard refresh sends Cache-Control: no-cache which bypasses the browser cache entirely → always goes upstream → gets the HTML wrapper → mashlib loads → view renders.

Security angle (why the fix matters beyond UX)

Solid responses vary with auth (WAC). Without client-side revalidation, a cached response from one auth state can leak into another (logged-in → logged-out body, or vice versa). The fix below addresses this in addition to the rendering race.

Proposed fix

  • Emit consistent Vary across all variants. Vary: Accept, Origin on every response (safer, covers CORS).
  • Emit Cache-Control: private, no-cache, must-revalidate on data variants (Turtle/JSON-LD/N3). Combined with the ETag we already send, this lets clients keep the body but always revalidate via If-None-Match → cheap 304s, no stale bodies, no auth-state leakage.
  • Keep Cache-Control: no-store on the HTML wrapper (it's a dynamic bootstrap template; no caching benefit).

Reproduction

for accept in "text/html,*/*;q=0.8" "text/turtle" "application/ld+json"; do
  echo "=== $accept ==="
  curl -s -D - -o /dev/null "https://<pod>/profile/card.jsonld" -H "Accept: $accept" \\
    | grep -Ei "vary|cache-control|content-type"
done

Shows the Vary/Cache-Control mismatch documented above.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    cachingHTTP caching, ETags, Cache-Control

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL