Return and pass on request IDs, and give /v1/e/ ETag, 304 and HEAD (closes #84) #179

Merged
clawbot merged 8 commits from issue-84-response-headers into next 2026-10-04 12:41:55 +02:00
8 Commits
Author SHA1 Message Date
clawbot c1c28204a1 Keep only a short, plain request ID; make others up at random
check / check (push) Failing after 2s
pixa's own RequestID middleware replaces chi's and the response-header
middleware. It keeps a request's own X-Request-Id only when it is at
most 64 letters, digits, '-', '_' or '.', so an over-long or odd value
is never sent back or upstream, and otherwise makes a random ID with
crypto/rand, which tells nothing about the host or how many requests
pixa served. It stores the ID under chi's RequestIDKey, where the
logging middleware, the handlers and the fetcher read it.

Model: opus-5-5
2026-10-04 09:44:47 +00:00
clawbot 6f7007a0ea Test that only a short, plain request ID is kept or passed on
check / check (push) Failing after 2s
A request's own X-Request-Id must be kept only when it is at most 64
letters, digits, '-', '_' or '.'; any other must be neither sent back
nor sent upstream, and the request gets a fresh ID instead. An ID made
up for a request must not hold the host name and must differ for every
request. pixa has no middleware of its own for this yet.

Model: opus-5-5
2026-10-04 09:43:47 +00:00
clawbot f507b6076d Give /v1/e/ ETag, 304 and HEAD as /v1/image/ has (closes #84)
check / check (push) Failing after 2s
The ETag and If-None-Match code of the /v1/image/ handler becomes
notModified, which both image handlers call; /v1/e/ answers HEAD with
the headers only and is routed for HEAD. HandleImageEnc was at the
80-line function limit, so its token checks move unchanged into
parseImageEncRequest, as parseImageRequest does for /v1/image/. No Vary
is added: only the image routes' CORS headers depend on a request
header, and go-chi/cors already sends Vary: Origin with them.

Model: opus-5-5
2026-10-04 08:40:15 +00:00
clawbot 20a46e96a2 Test ETag, 304 and HEAD on /v1/e/
An image served through an encrypted URL must carry an ETag, a request
whose If-None-Match is that ETag must get 304 with no body, HEAD must get
200 with the headers and no body, and the server must route HEAD on
/v1/e/ to its handler instead of answering 405.

Model: opus-5-5
2026-10-04 08:40:15 +00:00
clawbot 8d96bd710b Send the request ID upstream and log it with each image
The fetcher sends the request ID chi's RequestID middleware put in the
context as X-Request-Id, next to User-Agent and Accept, and the
"upstream fetched", "image converted" and "image served" lines carry it
as request_id, as the request log line does. A fetch shared by several
requests runs with the first request's context values, so it carries
that request's ID; README says so where it describes the shared fetch.

Model: opus-5-5
2026-10-04 08:40:15 +00:00
clawbot e00bf374cb Test that the upstream fetch and image log lines carry the request ID
A fetch must send the ID of the request it serves as X-Request-Id, and
the "upstream fetched", "image converted" and "image served" lines must
carry it as request_id, through either image route. newSignedHostServer
takes the logger its handlers and image service write to; its existing
callers pass a discarding one.

Model: opus-5-5
2026-10-04 08:40:15 +00:00
clawbot afe4b3bb70 Send the request's ID back as X-Request-Id
check / check (push) Failing after 2s
A middleware right after chi's RequestID sets the X-Request-Id response
header from the ID RequestID stored in the request context, so every
response carries it and a client can quote it when reporting a problem.
README "Routes" says where the ID comes from.

Model: opus-5-5
2026-10-04 08:31:17 +00:00
clawbot 3bcd032d37 Test that every response carries X-Request-Id
A response of any route and status must carry the request's ID: one pixa
made up when the request brought none, otherwise the request's own
X-Request-Id. No response carries it yet.

Model: opus-5-5
2026-10-04 08:30:58 +00:00