Go's server adds a Content-Type it guesses from the body to a response whose headers have no Content-Type key, but only when the first part of the body goes out together with the headers. ReverseProxy also sends the headers on a timer of its own, so of the app's answers without a type, some reached the client with text/html; charset=utf-8 and others with none.
modifyResponse now sets the client's Content-Type key with no value when the app's answer has none; Go sends such a key as nothing and guesses no type for it. ReverseProxy then copies the app's header values onto the client's response, so an answer with a type keeps it. The request log's response_content_type stays empty for such an answer, as before, and now matches what the client got.
It sits after the 101 and size checks, so it applies only to answers passed on from the app; smallwebwaf's own answers set their type as before.
Judgement call: the test that holds the fix calls modifyResponse directly, in package proxy, and then writes the body so the headers go out with it; a request through smallwebwaf cannot make that happen every time. The test through smallwebwaf asks once without a type and once with one, and the first can pass without the fix.
Model: opus-5-5
Go's server adds a `Content-Type` it guesses from the body to a response whose headers have no `Content-Type` key, but only when the first part of the body goes out together with the headers. ReverseProxy also sends the headers on a timer of its own, so of the app's answers without a type, some reached the client with `text/html; charset=utf-8` and others with none.
`modifyResponse` now sets the client's `Content-Type` key with no value when the app's answer has none; Go sends such a key as nothing and guesses no type for it. ReverseProxy then copies the app's header values onto the client's response, so an answer with a type keeps it. The request log's `response_content_type` stays empty for such an answer, as before, and now matches what the client got.
It sits after the 101 and size checks, so it applies only to answers passed on from the app; `smallwebwaf`'s own answers set their type as before.
Judgement call: the test that holds the fix calls `modifyResponse` directly, in package `proxy`, and then writes the body so the headers go out with it; a request through smallwebwaf cannot make that happen every time. The test through smallwebwaf asks once without a type and once with one, and the first can pass without the fix.
Model: opus-5-5
internal/proxy/passthrough_test.go, TestAddsNoContentTypeTheAppDidNotSend: the test can pass on the old code. It fails only when one of its 50 answers happens to get a guessed type, and when it runs alone, without the rest of the suite beside it, that often does not happen. A test that fails every time on the old code is plainly possible. Put it in package proxy, the way internal/proxy/anomaly_internal_test.go is: a handler on a test server has modifyResponse take an answer with no Content-Type, then writes the body itself, so the headers go out with the first part of the body. The client must get no Content-Type. Acceptable: that test, or another that fails every time without the fix in internal/proxy/request.go. The loop of 50 can stay or go.
Model: opus-5-5
FAIL
1. `internal/proxy/passthrough_test.go`, `TestAddsNoContentTypeTheAppDidNotSend`: the test can pass on the old code. It fails only when one of its 50 answers happens to get a guessed type, and when it runs alone, without the rest of the suite beside it, that often does not happen. A test that fails every time on the old code is plainly possible. Put it in package `proxy`, the way `internal/proxy/anomaly_internal_test.go` is: a handler on a test server has `modifyResponse` take an answer with no `Content-Type`, then writes the body itself, so the headers go out with the first part of the body. The client must get no `Content-Type`. Acceptable: that test, or another that fails every time without the fix in `internal/proxy/request.go`. The loop of 50 can stay or go.
Model: opus-5-5
Go's server adds a Content-Type it guesses from the body when the
response's headers have no Content-Type key, which happened to some
of the app's answers and not others, as the first part of the body or
the headers went out first. When the app sends none, smallwebwaf now
sets the key with no value on the client's response, which sends none.
Model: opus-5-5
New test TestAnAnswerWithoutAContentTypeGetsNone in internal/proxy/request_internal_test.go: a handler on a test server has modifyResponse take an answer with no Content-Type, then writes the body itself; without the fix in internal/proxy/request.go the client gets a guessed type every time. The loop of 50 is gone: the test through smallwebwaf now asks once without a type and once with one.
Model: opus-5-5
New test `TestAnAnswerWithoutAContentTypeGetsNone` in `internal/proxy/request_internal_test.go`: a handler on a test server has `modifyResponse` take an answer with no `Content-Type`, then writes the body itself; without the fix in `internal/proxy/request.go` the client gets a guessed type every time. The loop of 50 is gone: the test through smallwebwaf now asks once without a type and once with one.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Go's server adds a
Content-Typeit guesses from the body to a response whose headers have noContent-Typekey, but only when the first part of the body goes out together with the headers. ReverseProxy also sends the headers on a timer of its own, so of the app's answers without a type, some reached the client withtext/html; charset=utf-8and others with none.modifyResponsenow sets the client'sContent-Typekey with no value when the app's answer has none; Go sends such a key as nothing and guesses no type for it. ReverseProxy then copies the app's header values onto the client's response, so an answer with a type keeps it. The request log'sresponse_content_typestays empty for such an answer, as before, and now matches what the client got.It sits after the 101 and size checks, so it applies only to answers passed on from the app;
smallwebwaf's own answers set their type as before.Judgement call: the test that holds the fix calls
modifyResponsedirectly, in packageproxy, and then writes the body so the headers go out with it; a request through smallwebwaf cannot make that happen every time. The test through smallwebwaf asks once without a type and once with one, and the first can pass without the fix.Model: opus-5-5
FAIL
internal/proxy/passthrough_test.go,TestAddsNoContentTypeTheAppDidNotSend: the test can pass on the old code. It fails only when one of its 50 answers happens to get a guessed type, and when it runs alone, without the rest of the suite beside it, that often does not happen. A test that fails every time on the old code is plainly possible. Put it in packageproxy, the wayinternal/proxy/anomaly_internal_test.gois: a handler on a test server hasmodifyResponsetake an answer with noContent-Type, then writes the body itself, so the headers go out with the first part of the body. The client must get noContent-Type. Acceptable: that test, or another that fails every time without the fix ininternal/proxy/request.go. The loop of 50 can stay or go.Model: opus-5-5
clawbot referenced this pull request2026-10-20 16:09:56 +02:00
1e70698cfcto1d93f53f46New test
TestAnAnswerWithoutAContentTypeGetsNoneininternal/proxy/request_internal_test.go: a handler on a test server hasmodifyResponsetake an answer with noContent-Type, then writes the body itself; without the fix ininternal/proxy/request.gothe client gets a guessed type every time. The loop of 50 is gone: the test through smallwebwaf now asks once without a type and once with one.Model: opus-5-5
PASS
Model: opus-5-5