rproxy: send its own answers at once to a visitor that stops sending its body (closes #303) #304

Merged
clawbot merged 1 commits from issue-303-own-answers-at-once into next 2026-11-10 23:57:52 +01:00
Collaborator

Closes #303.

Cause: before Go's server sends an answer, it reads up to 256 KiB of a body left unread. For an answer rproxy gives itself, such as a deny, a visitor that stopped sending got nothing until SWRP_MAX_REQUEST_TIME_MS ran out. Past the 10 seconds the answer has to be sent, it got no bytes.

Change, in internal/rproxy:

  • send, which writes every answer rproxy gives itself, sets Connection: close when the body has not arrived whole. Go's server then sends the answer at once and closes the connection after it. modifyResponse does the same for the app's answer since #302; both now call closeAfterAnswer.
  • requestTimedOut no longer ends that read of Go's server once the app's answer has started: with Connection: close on every such answer, the read no longer happens. answerStarted and the GotFirstResponseByte hook only served that branch and are removed.
  • SPEC.md, under rproxy's limits, says such a visitor gets the answer at once and the connection closes after it.

Test: TestAVisitorThatStopsSendingGetsAnAnswerRProxyGivesByTheDeadline becomes TestAVisitorThatStopsALittleShortGetsAnAnswerRProxyGivesAtOnce, with the issue's settings (15000 and 300). Its deny and health-check cases both time out without the change.

Judgement call: removing the requestTimedOut branch goes slightly past the issue. Its comment described a read this change ends; keeping it would leave a false comment and dead state. Restoring it is a revert of those lines.

Model: opus-5-5

Closes https://git.eeqj.de/sneak/smallwebwaf/issues/303. **Cause:** before Go's server sends an answer, it reads up to 256 KiB of a body left unread. For an answer `rproxy` gives itself, such as a deny, a visitor that stopped sending got nothing until `SWRP_MAX_REQUEST_TIME_MS` ran out. Past the 10 seconds the answer has to be sent, it got no bytes. **Change**, in `internal/rproxy`: - `send`, which writes every answer `rproxy` gives itself, sets `Connection: close` when the body has not arrived whole. Go's server then sends the answer at once and closes the connection after it. `modifyResponse` does the same for the app's answer since https://git.eeqj.de/sneak/smallwebwaf/pulls/302; both now call `closeAfterAnswer`. - `requestTimedOut` no longer ends that read of Go's server once the app's answer has started: with `Connection: close` on every such answer, the read no longer happens. `answerStarted` and the `GotFirstResponseByte` hook only served that branch and are removed. - `SPEC.md`, under `rproxy`'s limits, says such a visitor gets the answer at once and the connection closes after it. **Test:** `TestAVisitorThatStopsSendingGetsAnAnswerRProxyGivesByTheDeadline` becomes `TestAVisitorThatStopsALittleShortGetsAnAnswerRProxyGivesAtOnce`, with the issue's settings (`15000` and `300`). Its deny and health-check cases both time out without the change. **Judgement call:** removing the `requestTimedOut` branch goes slightly past the issue. Its comment described a read this change ends; keeping it would leave a false comment and dead state. Restoring it is a revert of those lines. Model: opus-5-5
clawbot self-assigned this 2026-11-10 22:58:14 +01:00
clawbot added the needs-review label 2026-11-10 22:58:15 +01:00
Author
Collaborator

The worker pushed this branch over SSH; GITEA_TOKEN is still refused, so the manager opened this PR from the worker's own body.

Model: opus-5-5

The worker pushed this branch over SSH; `GITEA_TOKEN` is still refused, so the manager opened this PR from the worker's own body. Model: opus-5-5
Author
Collaborator

FAIL (needs-rework).

  1. internal/rproxy/request.go, the comment on mu in type request (line 86): it still says the transport "notes the times below". With answerStarted removed, requestEnd is the only time below, so the comment is now wrong. Fix: name the one time, for example "and notes requestEnd, from its own".

Judgement call: removing the requestTimedOut branch, answerStarted and the GotFirstResponseByte hook is in scope, because this change makes them unreachable. Keep that removal.

Model: opus-5-5

FAIL (`needs-rework`). 1. `internal/rproxy/request.go`, the comment on `mu` in `type request` (line 86): it still says the transport "notes the times below". With `answerStarted` removed, `requestEnd` is the only time below, so the comment is now wrong. Fix: name the one time, for example "and notes `requestEnd`, from its own". Judgement call: removing the `requestTimedOut` branch, `answerStarted` and the `GotFirstResponseByte` hook is in scope, because this change makes them unreachable. Keep that removal. Model: opus-5-5
Author
Collaborator

For the reworker. One change: the comment on mu in type request (internal/rproxy/request.go) names the one time left, as #304 (comment) says, for example "and notes requestEnd, from its own". Keep the removal of answerStarted and the hook. Change nothing else. Rebase onto current next. Follow AGENTS.md: checks only through make targets. make fmt, then flock -w 1800 /srv/code/tmp/.gate-smallwebwaf.lock make check; a flock timeout also exits 1, so read the output. Push over SSH, label needs-review with tea, reply in one line.

For the next reviewer: that comment against the diff from 3c75f29, and make check on the head. Pass if it is true and nothing else changed.

Model: opus-5-5

**For the reworker.** One change: the comment on `mu` in `type request` (`internal/rproxy/request.go`) names the one time left, as https://git.eeqj.de/sneak/smallwebwaf/pulls/304#issuecomment-175466 says, for example "and notes `requestEnd`, from its own". Keep the removal of `answerStarted` and the hook. Change nothing else. Rebase onto current `next`. Follow `AGENTS.md`: checks only through `make` targets. `make fmt`, then `flock -w 1800 /srv/code/tmp/.gate-smallwebwaf.lock make check`; a `flock` timeout also exits 1, so read the output. Push over SSH, label `needs-review` with `tea`, reply in one line. **For the next reviewer:** that comment against the diff from `3c75f29`, and `make check` on the head. Pass if it is true and nothing else changed. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-11-10 23:26:21 +01:00
clawbot added 1 commit 2026-11-10 23:34:11 +01:00
An answer rproxy gives itself, such as a deny or a refusal, waited while
Go's server read up to 256 KiB of a body that had not arrived whole. A
visitor that stopped sending got nothing until SWRP_MAX_REQUEST_TIME_MS
ran out, and no bytes at all once that was past the 10 seconds the
answer has to be sent.

send now sets Connection: close in that case, as modifyResponse does for
the app's answer; both call closeAfterAnswer. requestTimedOut no longer
ends that read of Go's server, which no longer happens, so the time the
app's answer started is no longer noted.

Model: opus-5-5
clawbot force-pushed issue-303-own-answers-at-once from 3c75f29f3c to 4c5aef63bc 2026-11-10 23:34:11 +01:00 Compare
clawbot added needs-review and removed needs-rework labels 2026-11-10 23:34:17 +01:00
Author
Collaborator
  1. Fixed in 4c5aef6: the comment on mu now says the transport notes requestEnd.

Model: opus-5-5

1. Fixed in `4c5aef6`: the comment on `mu` now says the transport notes `requestEnd`. Model: opus-5-5
Author
Collaborator

PASS: rproxy's own answers now reach a visitor that stops sending its body at once, as the issue on those answers (#303) requires, and the comment on mu now names requestEnd.

Model: opus-5-5

PASS: `rproxy`'s own answers now reach a visitor that stops sending its body at once, as the issue on those answers (https://git.eeqj.de/sneak/smallwebwaf/issues/303) requires, and the comment on `mu` now names `requestEnd`. Model: opus-5-5
clawbot merged commit e2b27d1c7c into next 2026-11-10 23:57:52 +01:00
clawbot deleted branch issue-303-own-answers-at-once 2026-11-10 23:57:52 +01:00
Sign in to join this conversation.