Access accounting observed, not reported #45

Merged
mikluko merged 1 commit from refactor/observed-accounting into main 2026-10-26 22:10:58 +00:00
Owner

Candidate 3 of the architecture review.

Handlers pushed status and byte counts into the log context, ten calls across three handlers, and a handler that forgot one logged no status. That happened for errors multiproxy answered itself and for refused CONNECT requests.

  • Plain HTTP: the log middleware wraps the ResponseWriter with httpsnoop, which keeps its optional interfaces and Unwrap, and records status and body bytes itself. HTTPHandler loses its io.Pipe, WaitGroup, context key and ModifyResponse hook, which existed only to measure content length.
  • CONNECT sessions: recorded in the one accept step (connectAcceptor): status 200 on accept, bytes written to the client when the connection closes. A ConnectAcceptor sits behind Unwrap, out of reach of a ResponseWriter hook, so the middleware alone could not see SOCKS sessions.

Tunnel and MITM no longer report anything to the log. log.WithStatusCode and log.WithContentLength stay, and override what was observed.

TestAccessAccounting covers plain HTTP, tunnel, MITM and a refused CONNECT; the last fails on main. TestLogObservesTheResponse covers the middleware. The suite passes three times in a row under -race.

Candidate 3 of the architecture review. Handlers pushed status and byte counts into the log context, ten calls across three handlers, and a handler that forgot one logged no status. That happened for errors multiproxy answered itself and for refused `CONNECT` requests. - **Plain HTTP:** the log middleware wraps the ResponseWriter with httpsnoop, which keeps its optional interfaces and `Unwrap`, and records status and body bytes itself. `HTTPHandler` loses its `io.Pipe`, WaitGroup, context key and `ModifyResponse` hook, which existed only to measure content length. - **`CONNECT` sessions:** recorded in the one accept step (`connectAcceptor`): status 200 on accept, bytes written to the client when the connection closes. A `ConnectAcceptor` sits behind `Unwrap`, out of reach of a ResponseWriter hook, so the middleware alone could not see SOCKS sessions. Tunnel and MITM no longer report anything to the log. `log.WithStatusCode` and `log.WithContentLength` stay, and override what was observed. `TestAccessAccounting` covers plain HTTP, tunnel, MITM and a refused `CONNECT`; the last fails on `main`. `TestLogObservesTheResponse` covers the middleware. The suite passes three times in a row under `-race`.
Access accounting observed, not reported
All checks were successful
CI / changelog (pull_request) Successful in 7s
CI / test (pull_request) Successful in 2m3s
ef15a29349
The log middleware wraps the ResponseWriter with httpsnoop and records the
status and body bytes itself, so the HTTP handler drops its io.Pipe,
WaitGroup and ModifyResponse hook, which existed only to measure content
length. CONNECT sessions are recorded in the one accept step: status 200 on
accept, bytes written to the client when the connection closes. Tunnel and
MITM no longer report to the log; a ConnectAcceptor sits behind Unwrap, out
of reach of a ResponseWriter hook, which is why the accept step does it.

Errors multiproxy answers itself, and refused CONNECT requests, now carry a
status in the access record.
mikluko deleted branch refactor/observed-accounting 2026-10-26 22:10:59 +00:00
Sign in to join this conversation.
No description provided.