-
Notifications
You must be signed in to change notification settings - Fork 3
fix: stop 404s/redirects from being publicly CDN-cached #2526
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: stage
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -75,17 +75,11 @@ export async function getServerSideProps({ req, res, resolvedUrl }) { | |
| // does not display with npm run dev | ||
|
|
||
| res.setHeader('set-cookie', `PRODUCTION=${process.env.PRODUCTION}`); | ||
| isProd && | ||
| res.setHeader( | ||
| 'Cache-Control', | ||
| 'public, max-age=3600, stale-while-revalidate=7200 ', | ||
| ); | ||
| isProd && res.setHeader('Surrogate-Control', 'max-age=3600'); | ||
|
|
||
| res.setHeader( | ||
| 'Surrogate-Key', | ||
| `${process.env.zesty.instance_zuid}, zesty.io`, | ||
| ); | ||
| // Default to non-cacheable; cache headers are set only on the 200 path below | ||
| // so 404s/redirects can't be pinned at the CDN edge and served to everyone. | ||
| res.setHeader('Cache-Control', 'private, no-store'); | ||
|
|
||
| // Fetch the page data using the cache function | ||
| let data = await fetchPage(resolvedUrl); | ||
| // attempt to get page data relative to zesty | ||
|
|
@@ -160,6 +154,19 @@ export async function getServerSideProps({ req, res, resolvedUrl }) { | |
| }; | ||
| } | ||
|
|
||
| // Real 200 page: safe to cache and tag with the instance Surrogate-Key. | ||
| if (isProd) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice side effect worth noting: the two auth-driven redirects above (
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea, same bug class as the 404. these 307s carried |
||
| res.setHeader( | ||
| 'Cache-Control', | ||
| 'public, max-age=3600, stale-while-revalidate=7200', | ||
| ); | ||
| res.setHeader('Surrogate-Control', 'max-age=3600'); | ||
| res.setHeader( | ||
| 'Surrogate-Key', | ||
| `${process.env.zesty.instance_zuid}, zesty.io`, | ||
| ); | ||
| } | ||
|
|
||
| // Pass data to the page via props | ||
| return { props: { ...data } }; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small behavior change worth calling out explicitly: previously
Surrogate-Keywas set unconditionally (outside theisProd &&guards), so dev/stage responses also carried it. With this refactor,Surrogate-Keyis only emitted on the successfulisProd200 path. That's very likely intentional (surrogate keys are only meaningful behind Fastly), but if any stage-facing tooling or purge script currently relies on the header being present in stage, it will silently stop working. Worth a quick confirm.Also, per your own verification table, Next.js overrides the header on the
notFoundpath tono-store, must-revalidate— so theprivate, no-storedefault here is really only observed on the redirect path and any thrown-500 path. Still correct, just noting the default set here isn't what actually goes out for 404s.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct and intentional. As I mentiond in the PR desc:
Surrogate-Control/Surrogate-Keyare the operative headers here. On Fastly,Surrogate-Controlcontrols the shared edge cache and overridesCache-Control. Next already forcedCache-Control: no-storeon the 404, but it doesn't touch the surrogate headers, so Fastly obeyedSurrogate-Controland edge-cached the 404 anyway. The fix's key effect is dropping the surrogate headers on non-200 paths, not the Cache-Control default.On stage it's inert:
isProdalready gated thepublicCache-Control, so stage responses were never shared-cacheable regardless of the key