Follow-up to #155 (0.16.4).
Behavior
Since 0.16.4, the error document for a document request applies the headers of the `HttpError` it reports, including one thrown by a loader. That includes `Cache-Control`. The error document still carries the hydrated data of every loader that ran, such as a root loader's per-user state. So an error thrown with `Cache-Control: public, max-age=60` produces a publicly cacheable HTML page that contains per-request data. The same already applies to the deepest route's own loader headers on a normal document.
An app can defend against this in its own middleware, and udibo does. But the framework's defaults point the unsafe way, and #145/#150 made data responses private by default for exactly this reason.
Options
- Don't apply an error's (or a loader's) `Cache-Control` to a document that carries loader data. Or downgrade `public`/`s-maxage` to `private` there, matching the data-response default.
- Or keep applying it, but document clearly that a document's cache policy covers everything the document hydrates, and add an opt-in.
Acceptance
- By default, a document request never leaves with a shared-cache policy taken from an error or loader header while it hydrates loader data. Otherwise the behaviour is an explicit, documented opt-in.
- Tests cover a thrown `HttpError` and a loader-returned header.
Follow-up to #155 (0.16.4).
Behavior
Since 0.16.4, the error document for a document request applies the headers of the `HttpError` it reports, including one thrown by a loader. That includes `Cache-Control`. The error document still carries the hydrated data of every loader that ran, such as a root loader's per-user state. So an error thrown with `Cache-Control: public, max-age=60` produces a publicly cacheable HTML page that contains per-request data. The same already applies to the deepest route's own loader headers on a normal document.
An app can defend against this in its own middleware, and udibo does. But the framework's defaults point the unsafe way, and #145/#150 made data responses private by default for exactly this reason.
Options
Acceptance