Compare commits
1
Commits
next
..
2e000624f4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e000624f4 |
@@ -413,12 +413,10 @@ Local hosts are tracked separately from WAN stats.
|
|||||||
|
|
||||||
### Latency measurement
|
### Latency measurement
|
||||||
|
|
||||||
GET requests to each target's URL as written, with `mode: 'no-cors'`,
|
GET requests to each target's URL as written, with `mode: 'no-cors'` and
|
||||||
`cache: 'no-store'` and `referrerPolicy: 'no-referrer'`, timed with
|
`cache: 'no-store'`, timed with `performance.now()`. No query string is added:
|
||||||
`performance.now()`. The Hetzner speed-test servers close the connection without
|
the Hetzner speed-test servers close the connection without an answer when the
|
||||||
an answer when the URL has a query string or the request has a `Referer` header.
|
URL has one, and `no-store` keeps the browser's cache out of the measurement.
|
||||||
So no query string is added, and no `Referer` header is sent, wherever the page
|
|
||||||
is served from. `no-store` keeps the browser's cache out of the measurement.
|
|
||||||
Each check times out after 80% of the refresh interval (24 seconds at 30
|
Each check times out after 80% of the refresh interval (24 seconds at 30
|
||||||
seconds) and is then recorded as a timeout, so a round's checks have all
|
seconds) and is then recorded as a timeout, so a round's checks have all
|
||||||
finished before the next round is due. When no WAN host answers, a recovery
|
finished before the next round is due. When no WAN host answers, a recovery
|
||||||
|
|||||||
@@ -23,12 +23,6 @@ Run `make frontend-viewport-test` in CI as its own step; it is not part of
|
|||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
- 2026-10-26: the six Hetzner targets answer wherever the page is served from
|
|
||||||
([#191](https://git.eeqj.de/sneak/netwatch/issues/191)). They close the
|
|
||||||
connection without an answer when the request has a `Referer` header. The
|
|
||||||
browser sent one unless the page came with the image's
|
|
||||||
`Referrer-Policy: no-referrer` header, which a static host and `make dev` do
|
|
||||||
not send. Each check now sets `referrerPolicy: 'no-referrer'`
|
|
||||||
- 2026-10-19: the server's `OnStart` hook in `internal/server/server.go` starts
|
- 2026-10-19: the server's `OnStart` hook in `internal/server/server.go` starts
|
||||||
`listenAndServe` with `go func() { s.listenAndServe() }()`, as the Go style
|
`listenAndServe` with `go func() { s.listenAndServe() }()`, as the Go style
|
||||||
guide asks ([#162](https://git.eeqj.de/sneak/netwatch/issues/162)); it was
|
guide asks ([#162](https://git.eeqj.de/sneak/netwatch/issues/162)); it was
|
||||||
|
|||||||
@@ -180,17 +180,6 @@ test("a check fetches the target's URL as written, with no query string added",
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("a check sends no Referer header, wherever the page is served from", async (t) => {
|
|
||||||
mockTargets(t, () => 10);
|
|
||||||
const check = measureLatency("https://fsn1-speed.hetzner.com");
|
|
||||||
t.mock.timers.tick(10);
|
|
||||||
assert.notEqual(await settled(check), "still waiting");
|
|
||||||
assert.equal(
|
|
||||||
fetch.mock.calls[0].arguments[1].referrerPolicy,
|
|
||||||
"no-referrer",
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("at a 30000ms interval, a target answering after 1000ms shows in its row while another target's check is still waiting", async (t) => {
|
test("at a 30000ms interval, a target answering after 1000ms shows in its row while another target's check is still waiting", async (t) => {
|
||||||
CONFIG.updateInterval = 30000;
|
CONFIG.updateInterval = 30000;
|
||||||
const state = new AppState([
|
const state = new AppState([
|
||||||
|
|||||||
+4
-6
@@ -572,11 +572,10 @@ export class Reporter {
|
|||||||
// it as a timeout. A failed check's reason says what went wrong and after
|
// it as a timeout. A failed check's reason says what went wrong and after
|
||||||
// how long; a check that answered has none.
|
// how long; a check that answered has none.
|
||||||
//
|
//
|
||||||
// The Hetzner speed-test servers close the connection without an answer
|
// The URL is fetched as written, with nothing added to it: the Hetzner
|
||||||
// when the URL has a query string or the request has a Referer header. So
|
// speed-test servers close the connection without an answer when the URL
|
||||||
// the URL is fetched as written, and referrerPolicy: "no-referrer" sends
|
// has a query string, and cache: "no-store" keeps the browser's cache out
|
||||||
// no Referer header, wherever the page is served from. cache: "no-store"
|
// of the measurement.
|
||||||
// keeps the browser's cache out of the measurement.
|
|
||||||
export async function measureLatency(url, signal) {
|
export async function measureLatency(url, signal) {
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
const timeoutId = setTimeout(
|
const timeoutId = setTimeout(
|
||||||
@@ -592,7 +591,6 @@ export async function measureLatency(url, signal) {
|
|||||||
method: "GET",
|
method: "GET",
|
||||||
mode: "no-cors",
|
mode: "no-cors",
|
||||||
cache: "no-store",
|
cache: "no-store",
|
||||||
referrerPolicy: "no-referrer",
|
|
||||||
signal: controller.signal,
|
signal: controller.signal,
|
||||||
});
|
});
|
||||||
const latency = Math.round(performance.now() - start);
|
const latency = Math.round(performance.now() - start);
|
||||||
|
|||||||
Reference in New Issue
Block a user