Public: anyone can read this; the crew can change it.
Browsing an origin names its Server-Timing phases: session, origin, render #5264
Check · Review · Land · Live done — Landed and live in production.
Every GET under `BROWSE` now sends a `Server-Timing` header that names `session`, `origin` and `render`. The new test and the existing `test/view-source.test.ts` pass, and `tsc --noEmit` is clean. I didn't run the whole check or the design lint, since I only changed the API routes.
shipped production is serving it deploy 7cfd21c
Every GET under BROWSE now sends a Server-Timing header that names session, origin and render. The new test and the existing test/view-source.test.ts pass, and tsc --noEmit is clean. I didn't run the whole check or the design lint, since I only changed the API routes.
session:browse()notes it before the account check, so every route gets it. A refused request still carries it, and its refusals are unchanged.origin: the call to the origin is wrapped intimePhaseAsync(…, "origin", …). That covers the sharedread()helper, the landing read (both itsdescribeand its branches/readme calls) andcommits(both itsdescribeand its page call).render: the shaping andjson(...)step is wrapped intimePhase(…, "render", …). A refusal skips it, so an error answer hasoriginbut norender.- Landing and
commits: each can noteorigintwice (once fordescribe, once for the rest). I didn't merge them, so the header can listorigintwice on those two routes. - Test:
test/browse-phases.test.tsuses the fake origin the origin tests use. It reads the landing page, branches, a blob and the issue list, and asserts each response namessession,originandrender. The issue named one new test file, and I added this one. - Not done: I didn't test every
BROWSEroute, only those four. Answers and cache behaviour are unchanged. There are no new dependencies.
To try it, connect an origin and run curl -si …/api/v1/user/origins/:id/browse/:owner/:name/branches, then read the server-timing line.
Approved. This change only adds timing to responses and is safe. It does what #5247 asked:
- Every GET under
BROWSEgets the timing. The 8 routes that useread()are covered through the shared helper, and the landing read andcommitsare wrapped by hand. sessionis noted inbrowse()beforerequireAccount, so refusals, answers and cache behaviour are unchanged.src/http/api.tsuses the same helpers it already uses for the profile and user routes.
Checked:
- At head,
bun test test/browse-phases.test.tspasses 4/4 andtsc --noEmitis clean. - With
api.tsreverted to the base, the same test fails 4/4. It would catch a regression. - The preview answers
/with 200. A guest GET on…/browse/a/b/branchesgets 401 withserver-timing: app;dur=…, session;dur=….
Security:
- Phase names are fixed constants that pass the
PHASE_NAMEcheck, so no user text reaches the header. - The
originandrendertimings are only written aftersourceForhas confirmed the caller connected the origin. A guest learns nothing new. - No new input, no write, no dependency.
The terminal and README don't apply: this is a response header on JSON API reads.
One small point, not blocking: the landing read and commits can list origin twice. Server-Timing allows that, but one summed entry would be easier to read in devtools.
Every GET under
BROWSEnow sends aServer-Timingheader that namessession,originandrender. The new test and the existingtest/view-source.test.tspass, andtsc --noEmitis clean. I didn't run the whole check or the design lint, since I only changed the API routes.session:browse()notes it before the account check, so every route gets it. A refused request still carries it, and its refusals are unchanged.origin: the call to the origin is wrapped intimePhaseAsync(…, "origin", …). That covers the sharedread()helper, the landing read (both itsdescribeand its branches/readme calls) andcommits(both itsdescribeand its page call).render: the shaping andjson(...)step is wrapped intimePhase(…, "render", …). A refusal skips it, so an error answer hasoriginbut norender.commits: each can noteorigintwice (once fordescribe, once for the rest). I didn't merge them, so the header can listorigintwice on those two routes.test/browse-phases.test.tsuses the fake origin the origin tests use. It reads the landing page, branches, a blob and the issue list, and asserts each response namessession,originandrender. The issue named one new test file, and I added this one.BROWSEroute, only those four. Answers and cache behaviour are unchanged. There are no new dependencies.To try it, connect an origin and run
curl -si …/api/v1/user/origins/:id/browse/:owner/:name/branches, then read theserver-timingline.Closes #5247