README.md: rework against the review findings

The check sentence names HEAD for the S3 regions up front. The rate-limit
sentence states the safe rate plainly: an address that sends at most half
the limit in any 60 seconds is never refused. The upaas `TRUSTED_PROXIES`
entry again warns that a client connecting from a trusted address can
write its own `X-Forwarded-For`, that a connection through a published
Docker port can arrive from the Docker network's gateway, which the
default includes, and that set and empty, every client behind the proxy
shares one allowance. `TODO.md` gets the Completed Steps entry for
#189, now that
#196 has merged. For
#195.

Model: fable-5-1
This commit is contained in:
clawbot
2026-10-26 05:41:11 +00:00
committed by sneak
parent 09cc003a01
commit 5788ea43e3
2 changed files with 22 additions and 11 deletions
+18 -11
View File
@@ -82,12 +82,12 @@ The host list is written in `web/src/main.js`. There is no setting for it.
### What a figure measures
Each check is a GET request to the target's URL. The figure is the time from
sending the request until the response headers arrive, in milliseconds. Unlike
ping, it includes the time the server takes to answer. When the browser opens a
new connection, it also includes the DNS lookup, the connection setup and the
TLS handshake. Chrome opens a new connection for every check of the Hetzner
servers, and for more targets at longer intervals.
A check is a request to the target's URL: GET, or HEAD for the S3 regions. The
figure is the time from sending the request until the response headers arrive,
in milliseconds. Unlike ping, it includes the time the server takes to answer.
When the browser opens a new connection, it also includes the DNS lookup, the
connection setup and the TLS handshake. Chrome opens a new connection for every
check of the Hetzner servers, and for more targets at longer intervals.
Any answer counts as reachable, an error page included. The request is made in
the browser's `no-cors` mode, so the page cannot read the answer, only time it.
@@ -297,6 +297,13 @@ The [upaas](https://git.eeqj.de/sneak/upaas) app for netwatch needs:
leads out of `/data` is refused too.
- `TRUSTED_PROXIES` names the proxies nginx trusts, as IP addresses or CIDRs
separated by commas. The backend's own setting is fixed to `127.0.0.1/32`.
With `TRUSTED_PROXIES` set and empty, nginx trusts no proxy. Every client
behind the proxy then shares the proxy's one allowance of
`REPORTS_PER_MINUTE`. Any client that connects from an address in the set
can write its own `X-Forwarded-For`. A connection through a port Docker
publishes can arrive from the Docker network's gateway, such as
`172.17.0.1`. The default includes that address. Where that matters, name
only the addresses that nothing but the proxy connects from.
- Health: the image's `HEALTHCHECK`, described above.
A variable set to a value the container cannot use stops it at start, with the
@@ -418,11 +425,11 @@ bounded in four ways. Each refusal answers with the body `{"status":"error"}`.
- Rate limit. Each client address, resolved through `TRUSTED_PROXIES`, may send
`REPORTS_PER_MINUTE` reports a minute. Past that it gets 429 with
`Retry-After: 60`. The minute slides: reports from the minute before still
count, fading out over the current one. An address is sure never to be refused
only while it sends at most half the limit in any 60 seconds. The page sends
one report a minute from each open tab. So the default of 60 refuses nothing
from up to 30 tabs behind one address, however their reports bunch up. Every
answer to a report carries the headers `X-RateLimit-Limit`,
count, fading out over the current one. An address that sends at most half the
limit in any 60 seconds is never refused. Above that, it may be. The page
sends one report a minute from each open tab. So the default of 60 refuses
nothing from up to 30 tabs behind one address, however their reports bunch up.
Every answer to a report carries the headers `X-RateLimit-Limit`,
`X-RateLimit-Remaining` and `X-RateLimit-Reset`.
- Size cap. The report files in `DATA_DIR` may total at most
`DATA_DIR_MAX_BYTES`, counting the files already there at start. Reports
+4
View File
@@ -23,6 +23,10 @@ Run `make frontend-viewport-test` in CI as its own step; it is not part of
# Completed Steps
- 2026-10-26: `README.md`, `TODO.md` and `test/viewport/README.md` are rewritten
sentence by sentence ([#189](https://git.eeqj.de/sneak/netwatch/issues/189)).
Each sentence reads on the first pass: one idea, under about 30 words, the
verb early. Every statement matches the code on `next`.
- 2026-10-26: a target whose home page answers with a redirect is checked at
`/robots.txt` on the same host, which answers without one
([#194](https://git.eeqj.de/sneak/netwatch/issues/194)). These are the AWS