Page is sent with Cache-Control: no-cache (closes #141) #170

Merged
clawbot merged 1 commits from issue-141-page-no-cache into next 2026-10-19 03:10:40 +02:00
Collaborator

configs/nginx.conf: location / adds Cache-Control: no-cache, so a browser that keeps a copy of the page checks it with its ETag before using it again and gets a 304 when it has not changed. Before, index.html went out with no Cache-Control; a browser could keep it after a deploy, ask for files under /assets/ that the new build no longer has, and show an empty page. A path that the same location answers with /index.html through its try_files fallback gets the same header. That location now includes security-headers.conf again, as /assets/ does, because its own add_header drops the server's. /assets/ and the paths passed to the backend (/api/, the health check, /metrics) do not get the new header.

script/frontend-viewport-test asks the nginx it starts for / and /no-such-page before the browser starts, and fails unless both carry Cache-Control: no-cache and Content-Security-Policy. It runs curl inside that container; the nginx image ships it.

README.md Deployment, and the script's line under Entrypoints, say what the image and the script now do.

Closes #141

Judgement call: the test checks Content-Security-Policy alone for the security headers, since all of them come from the one included file.

Model: opus-5-5

`configs/nginx.conf`: `location /` adds `Cache-Control: no-cache`, so a browser that keeps a copy of the page checks it with its `ETag` before using it again and gets a `304` when it has not changed. Before, `index.html` went out with no `Cache-Control`; a browser could keep it after a deploy, ask for files under `/assets/` that the new build no longer has, and show an empty page. A path that the same location answers with `/index.html` through its `try_files` fallback gets the same header. That location now includes `security-headers.conf` again, as `/assets/` does, because its own `add_header` drops the server's. `/assets/` and the paths passed to the backend (`/api/`, the health check, `/metrics`) do not get the new header. `script/frontend-viewport-test` asks the nginx it starts for `/` and `/no-such-page` before the browser starts, and fails unless both carry `Cache-Control: no-cache` and `Content-Security-Policy`. It runs `curl` inside that container; the nginx image ships it. `README.md` Deployment, and the script's line under Entrypoints, say what the image and the script now do. Closes https://git.eeqj.de/sneak/netwatch/issues/141 Judgement call: the test checks `Content-Security-Policy` alone for the security headers, since all of them come from the one included file. Model: opus-5-5
clawbot added the needs-review label 2026-10-19 01:52:40 +02:00
clawbot self-assigned this 2026-10-19 01:52:40 +02:00
Author
Collaborator
  1. README.md lines 439-441 (Deployment): "the files under /assets/, whose names change with every build" is not what the build does. Vite names each of those files after a hash of its contents, so a file keeps its name until its contents change; the stylesheet has the same name from one commit to the next. Acceptable: "whose names change whenever their contents do", or drop the clause.

  2. README.md lines 89-90 (Entrypoints) and TODO.md line 33 say the test checks that the page carries "the security headers". script/frontend-viewport-test checks only Content-Security-Policy. Acceptable: say what it checks (Cache-Control: no-cache and Content-Security-Policy, which comes from the same file as the other security headers), or have the script check every header configs/security-headers.conf sets.

  3. configs/nginx.conf lines 33-34: "a browser never keeps a copy that names assets a newer build no longer has" misstates no-cache: the browser may keep the copy, but must ask the server before using it again. Acceptable: something like "a browser never uses a copy that names assets a newer build no longer has without first checking it is current".

Model: opus-5-5

1. `README.md` lines 439-441 (Deployment): "the files under `/assets/`, whose names change with every build" is not what the build does. Vite names each of those files after a hash of its contents, so a file keeps its name until its contents change; the stylesheet has the same name from one commit to the next. Acceptable: "whose names change whenever their contents do", or drop the clause. 2. `README.md` lines 89-90 (Entrypoints) and `TODO.md` line 33 say the test checks that the page carries "the security headers". `script/frontend-viewport-test` checks only `Content-Security-Policy`. Acceptable: say what it checks (`Cache-Control: no-cache` and `Content-Security-Policy`, which comes from the same file as the other security headers), or have the script check every header `configs/security-headers.conf` sets. 3. `configs/nginx.conf` lines 33-34: "a browser never keeps a copy that names assets a newer build no longer has" misstates `no-cache`: the browser may keep the copy, but must ask the server before using it again. Acceptable: something like "a browser never uses a copy that names assets a newer build no longer has without first checking it is current". Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-19 02:16:02 +02:00
clawbot force-pushed issue-141-page-no-cache from 33859b1dc1 to 9e1e0c26e1 2026-10-19 02:21:38 +02:00 Compare
clawbot added needs-review and removed needs-rework labels 2026-10-19 02:21:56 +02:00
Author
Collaborator
  1. README.md Deployment now says the names under /assets/ change whenever their contents do.
  2. README.md Entrypoints and TODO.md now say the test checks Cache-Control: no-cache and Content-Security-Policy; the script's header comment and failure message say the same, and the script checks nothing new.
  3. The configs/nginx.conf comment now says a browser never uses a copy of the page that names assets a newer build no longer has without first checking with the server that it is current.

Also reworded, for the same overstatement: "revalidates it on every load" in README.md Deployment, TODO.md and the PR body, and "curl retries until nginx is listening" in the script, which tries up to ten more times.

Model: opus-5-5

1. `README.md` Deployment now says the names under `/assets/` change whenever their contents do. 2. `README.md` Entrypoints and `TODO.md` now say the test checks `Cache-Control: no-cache` and `Content-Security-Policy`; the script's header comment and failure message say the same, and the script checks nothing new. 3. The `configs/nginx.conf` comment now says a browser never uses a copy of the page that names assets a newer build no longer has without first checking with the server that it is current. Also reworded, for the same overstatement: "revalidates it on every load" in `README.md` Deployment, `TODO.md` and the PR body, and "curl retries until nginx is listening" in the script, which tries up to ten more times. Model: opus-5-5
Author
Collaborator
  1. script/frontend-viewport-test lines 87-89: the check asks for each path with curl -sS --retry 10 --retry-connrefused. The image's curl prints an error line for every attempt that fails, even when a later attempt succeeds, so a run where nginx takes a moment to start passes but shows curl: (7) Failed to connect to 127.0.0.1 port 8080 ... Could not connect to server. That reads as a failure in a green run, and in a run that fails later in the browser checks it points the reader at the wrong step. Acceptable: a passing run prints nothing from curl (for example -s without -S), while a run where nginx never answers still says so in the script's own failure message.

Model: opus-5-5

1. `script/frontend-viewport-test` lines 87-89: the check asks for each path with `curl -sS --retry 10 --retry-connrefused`. The image's curl prints an error line for every attempt that fails, even when a later attempt succeeds, so a run where nginx takes a moment to start passes but shows `curl: (7) Failed to connect to 127.0.0.1 port 8080 ... Could not connect to server`. That reads as a failure in a green run, and in a run that fails later in the browser checks it points the reader at the wrong step. Acceptable: a passing run prints nothing from curl (for example `-s` without `-S`), while a run where nginx never answers still says so in the script's own failure message. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-19 02:39:19 +02:00
clawbot force-pushed issue-141-page-no-cache from 9e1e0c26e1 to fe2deec5bb 2026-10-19 02:43:01 +02:00 Compare
clawbot added needs-review and removed needs-rework labels 2026-10-19 02:43:10 +02:00
Author
Collaborator
  1. The curl in script/frontend-viewport-test runs with -s and no -S, so it prints nothing while nginx starts; if nginx never answers, the script stops with its own message, frontend-viewport-test: nginx did not answer /.

Model: opus-5-5

1. The curl in `script/frontend-viewport-test` runs with `-s` and no `-S`, so it prints nothing while nginx starts; if nginx never answers, the script stops with its own message, `frontend-viewport-test: nginx did not answer /`. Model: opus-5-5
Author
Collaborator
  1. TODO.md lines 29-30: "A path with no file of its own falls back to the page and gets the same header" is not what the config does. A missing file under /assets/ gets a 404 and not the page, which is how the empty page in the sentence before it comes about. The paths passed to the backend never fall back either. The PR body says the same thing ("A path with no file of its own falls back to /index.html through the same location"). Acceptable: limit the sentence to the try_files fallback in location /, for example "Any other path with no file of its own, outside /assets/ and the paths passed to the backend, falls back to the page and gets the same header", or drop the sentence.

Model: opus-5-5

1. `TODO.md` lines 29-30: "A path with no file of its own falls back to the page and gets the same header" is not what the config does. A missing file under `/assets/` gets a 404 and not the page, which is how the empty page in the sentence before it comes about. The paths passed to the backend never fall back either. The PR body says the same thing ("A path with no file of its own falls back to `/index.html` through the same location"). Acceptable: limit the sentence to the `try_files` fallback in `location /`, for example "Any other path with no file of its own, outside `/assets/` and the paths passed to the backend, falls back to the page and gets the same header", or drop the sentence. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-19 02:50:36 +02:00
clawbot force-pushed issue-141-page-no-cache from fe2deec5bb to b42066c0b5 2026-10-19 02:55:18 +02:00 Compare
clawbot added needs-review and removed needs-rework labels 2026-10-19 02:55:46 +02:00
Author
Collaborator
  1. TODO.md and the PR body now say only that a path location / answers with the page through its try_files fallback gets the same header.

Also corrected:

  • The comment in script/frontend-viewport-test said the same of any path with no file of its own; it now names /no-such-page and the try_files fallback.
  • The commit message and PR body said "the locations passed to the backend"; they now say "the paths passed to the backend".

Model: opus-5-5

1. `TODO.md` and the PR body now say only that a path `location /` answers with the page through its `try_files` fallback gets the same header. Also corrected: - The comment in `script/frontend-viewport-test` said the same of any path with no file of its own; it now names `/no-such-page` and the `try_files` fallback. - The commit message and PR body said "the locations passed to the backend"; they now say "the paths passed to the backend". Model: opus-5-5
Author
Collaborator

Review passed.

Model: opus-5-5

Review passed. Model: opus-5-5
clawbot added 1 commit 2026-10-19 03:09:57 +02:00
nginx sent index.html with no Cache-Control, so a browser could keep
it after a deploy and ask for hashed assets the new build no longer
has, and show an empty page. location / now adds Cache-Control:
no-cache, which covers its try_files fallback to /index.html, and
includes security-headers.conf again, since its own add_header drops
the server's. /assets/ and the paths passed to the backend are
unchanged.

script/frontend-viewport-test fails unless / and a path that falls
back to the page carry Cache-Control: no-cache and
Content-Security-Policy, which comes from the same file as the other
security headers.

Model: opus-5-5
clawbot force-pushed issue-141-page-no-cache from b42066c0b5 to fb998b45d7 2026-10-19 03:09:57 +02:00 Compare
clawbot merged commit 6df743f7fa into next 2026-10-19 03:10:40 +02:00
clawbot deleted branch issue-141-page-no-cache 2026-10-19 03:10:40 +02:00
clawbot removed the needs-review label 2026-10-19 03:10:41 +02:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/netwatch#170