Format Go with gofmt, then golines -m 77 (closes #215)
check / check (push) Waiting to run

script/fmt now runs golines -m 77 after gofmt, repeating golines until
it changes nothing, since one pass can leave a line the next splits.
script/fmt-check fails when either would change a file.
script/bootstrap installs golines v0.13.0 with go install, pinned to
its commit, and checks the installed version with go version -m.

The tree is reformatted. The longer lines this makes are fixed by
hand: nolint directives moved onto their own line above the statement,
one string split, and 20 functions over funlen's 80 lines shortened or
split, RunWAF and limitPercentages among them.

Model: opus-5-5
This commit was merged in pull request #363.
This commit is contained in:
clawbot committed 2026-11-11 17:29:12 +01:00
1 parent 63e58e326b
commit 0b23352767
118 files changed
+9447 -2670

No files matched your search

+219 -76
View File
@@ -358,11 +358,13 @@ func startServerLogging(
}
maps.Copy(settings, env)
cfg, err := config.RProxyFromEnvironment(func(name string) (string, bool) {
value, ok := settings[name]
cfg, err := config.RProxyFromEnvironment(
func(name string) (string, bool) {
value, ok := settings[name]
return value, ok
})
return value, ok
},
)
if err != nil {
t.Fatalf("settings %v: %v", settings, err)
}
@@ -370,10 +372,18 @@ func startServerLogging(
server := rproxy.New(rproxy.Params{
Config: cfg,
RequestLog: requestLog,
ProcessLog: requestlog.NewProcessLogger(processLog, "test", slog.LevelInfo),
ProcessLog: requestlog.NewProcessLogger(
processLog,
"test",
slog.LevelInfo,
),
})
listener, err := (&net.ListenConfig{}).Listen(t.Context(), "tcp", localhost+":0")
listener, err := (&net.ListenConfig{}).Listen(
t.Context(),
"tcp",
localhost+":0",
)
if err != nil {
t.Fatalf("listen: %v", err)
}
@@ -403,7 +413,10 @@ type answered struct {
func visit(t *testing.T, req *http.Request) answered {
t.Helper()
transport := &http.Transport{DisableKeepAlives: true, DisableCompression: true}
transport := &http.Transport{
DisableKeepAlives: true,
DisableCompression: true,
}
defer transport.CloseIdleConnections()
res, err := transport.RoundTrip(req)
@@ -429,8 +442,12 @@ func newRequest(
) *http.Request {
t.Helper()
req, err := http.NewRequestWithContext(t.Context(), method, "http://"+addr+target,
body)
req, err := http.NewRequestWithContext(
t.Context(),
method,
"http://"+addr+target,
body,
)
if err != nil {
t.Fatalf("new request: %v", err)
}
@@ -450,7 +467,11 @@ func wantGreeting(t *testing.T, got answered) {
t.Helper()
if got.status != http.StatusOK || got.body != greeting {
t.Errorf("answered %d %q, want the app's greeting", got.status, got.body)
t.Errorf(
"answered %d %q, want the app's greeting",
got.status,
got.body,
)
}
}
@@ -547,7 +568,12 @@ func TestPassesAnAllowedRequestToTheAppAndItsAnswerBack(t *testing.T) {
requestIDHeader: asked.header.Get(requestIDHeader),
} {
if received.Header.Get(name) != want {
t.Errorf("the app saw %s %q, want %q", name, received.Header.Get(name), want)
t.Errorf(
"the app saw %s %q, want %q",
name,
received.Header.Get(name),
want,
)
}
}
}
@@ -660,7 +686,12 @@ func TestAnAnswerWithoutAContentTypeGetsNone(t *testing.T) {
})
_, _, server := startServer(t, standIn.URL, app.URL, nil)
req := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/", http.NoBody)
req := httptest.NewRequestWithContext(
t.Context(),
http.MethodGet,
"/",
http.NoBody,
)
w := httptest.NewRecorder()
server.Handler.ServeHTTP(w, req)
@@ -670,8 +701,11 @@ func TestAnAnswerWithoutAContentTypeGetsNone(t *testing.T) {
// stops it: the key with no value.
values, there := w.Header()["Content-Type"]
if !there || len(values) != 0 {
t.Errorf("the answer's Content-Type is %q, there: %v, want the key with no value",
values, there)
t.Errorf(
"the answer's Content-Type is %q, there: %v, want the key with no value",
values,
there,
)
}
}
@@ -706,8 +740,12 @@ func TestRemovesTheVisitorsLookupHeadersWhenWAFGivesNone(t *testing.T) {
wantGreeting(t, visit(t, req))
header := <-seen
if len(header.Values(asnHeader)) != 0 || len(header.Values(countryHeader)) != 0 {
t.Errorf("the app saw the visitor's lookup headers: %v", header)
if len(header.Values(asnHeader)) != 0 ||
len(header.Values(countryHeader)) != 0 {
t.Errorf(
"the app saw the visitor's lookup headers: %v",
header,
)
}
})
}
@@ -740,7 +778,8 @@ func TestDenyGivesTheVisitorWAFsAnswer(t *testing.T) {
}
line := out.requestLine(t)
if line["disposition"] != dispositionDeny || line["default_disposition"] != nil {
if line["disposition"] != dispositionDeny ||
line["default_disposition"] != nil {
t.Errorf("line %v, want waf's deny", line)
}
}
@@ -754,7 +793,11 @@ func TestADeniedHeadKeepsWAFsContentLength(t *testing.T) {
got := visit(t, newRequest(t, http.MethodHead, addr, "/", http.NoBody))
if got.status != http.StatusForbidden ||
got.header.Get(contentLengthHeader) != strconv.Itoa(len(deniedBody)) {
got.header.Get(
contentLengthHeader,
) != strconv.Itoa(
len(deniedBody),
) {
t.Errorf("answered %+v, want waf's 403 and its length", got)
}
}
@@ -778,7 +821,14 @@ func TestAnAnswerRProxyHoldsWholeIsSentBeforeItsLogLine(t *testing.T) {
log := heldLog{release: make(chan struct{})}
standIn := startWAF(t, deny)
app := startApp(t, greet)
addr, _ := startServerLogging(t, standIn.URL, app.URL, nil, log, io.Discard)
addr, _ := startServerLogging(
t,
standIn.URL,
app.URL,
nil,
log,
io.Discard,
)
t.Cleanup(func() { close(log.release) })
@@ -795,9 +845,16 @@ func TestAnAnswerRProxyHoldsWholeIsSentBeforeItsLogLine(t *testing.T) {
}()
body, err := io.ReadAll(res.Body)
if err != nil || res.StatusCode != tc.status || string(body) != tc.body {
t.Errorf("answered %d %q (%v), want %d %q", res.StatusCode, body, err,
tc.status, tc.body)
if err != nil || res.StatusCode != tc.status ||
string(body) != tc.body {
t.Errorf(
"answered %d %q (%v), want %d %q",
res.StatusCode,
body,
err,
tc.status,
tc.body,
)
}
})
}
@@ -843,8 +900,11 @@ func TestCloseClosesTheConnectionWithoutAnAnswer(t *testing.T) {
text, err := io.ReadAll(conn)
if err != nil || len(text) != 0 {
t.Errorf("read %q (%v), want the connection closed without an answer",
text, err)
t.Errorf(
"read %q (%v), want the connection closed without an answer",
text,
err,
)
}
report := standIn.report(t)
@@ -858,7 +918,9 @@ func TestCloseClosesTheConnectionWithoutAnAnswer(t *testing.T) {
}
}
func TestALineForARequestClosedWithoutAnAnswerHasNoNegativeTime(t *testing.T) {
func TestALineForARequestClosedWithoutAnAnswerHasNoNegativeTime(
t *testing.T,
) {
t.Parallel()
backend := startWAFAnsweringReports(t,
@@ -881,7 +943,10 @@ func TestALineForARequestClosedWithoutAnAnswerHasNoNegativeTime(t *testing.T) {
duration, ok := line["duration_response_ms"].(float64)
if !ok || duration < 0 {
t.Errorf("line %v, want a duration_response_ms that is not negative", line)
t.Errorf(
"line %v, want a duration_response_ms that is not negative",
line,
)
}
}
}
@@ -900,12 +965,16 @@ func answeringWith(answer http.HandlerFunc) func(t *testing.T) string {
func noAnswers() map[string]func(t *testing.T) string {
return map[string]func(t *testing.T) string{
"no connection": func(*testing.T) string { return nowhere },
"no answer at all": answeringWith(func(http.ResponseWriter, *http.Request) {
panic(http.ErrAbortHandler)
}),
"a slow start": answeringWith(func(_ http.ResponseWriter, r *http.Request) {
<-r.Context().Done()
}),
"no answer at all": answeringWith(
func(http.ResponseWriter, *http.Request) {
panic(http.ErrAbortHandler)
},
),
"a slow start": answeringWith(
func(_ http.ResponseWriter, r *http.Request) {
<-r.Context().Done()
},
),
"headers followed by a stalled body": answeringWith(
func(w http.ResponseWriter, r *http.Request) {
w.Header().Set(dispositionHeader, dispositionDeny)
@@ -947,21 +1016,29 @@ func TestAnAnswerOtherThanAllowGoesToTheVisitorAsWAFGaveIt(t *testing.T) {
t.Run(tc.name+" with the default "+setting, func(t *testing.T) {
t.Parallel()
standIn := startWAF(t, func(w http.ResponseWriter, _ *http.Request) {
if tc.disposition != "" {
w.Header().Set(dispositionHeader, tc.disposition)
}
standIn := startWAF(
t,
func(w http.ResponseWriter, _ *http.Request) {
if tc.disposition != "" {
w.Header().Set(dispositionHeader, tc.disposition)
}
w.Header().Set(fromWAFHeader, addedHeaderValue)
w.WriteHeader(tc.status)
_, _ = io.WriteString(w, tc.body)
})
w.Header().Set(fromWAFHeader, addedHeaderValue)
w.WriteHeader(tc.status)
_, _ = io.WriteString(w, tc.body)
},
)
app := startApp(t, func(http.ResponseWriter, *http.Request) {
t.Error("the app was asked")
})
addr, out := startRProxy(t, standIn.URL, app.URL, map[string]string{
defaultDisposition: setting,
})
addr, out := startRProxy(
t,
standIn.URL,
app.URL,
map[string]string{
defaultDisposition: setting,
},
)
got := get(t, addr, "/")
if got.status != tc.status || got.body != tc.body ||
@@ -974,8 +1051,13 @@ func TestAnAnswerOtherThanAllowGoesToTheVisitorAsWAFGaveIt(t *testing.T) {
}
line := out.requestLine(t)
if line["status"] != float64(tc.status) || line["default_disposition"] != nil {
t.Errorf("line %v, want status %d and no default", line, tc.status)
if line["status"] != float64(tc.status) ||
line["default_disposition"] != nil {
t.Errorf(
"line %v, want status %d and no default",
line,
tc.status,
)
}
if out.has("waf gave no answer") {
@@ -1036,7 +1118,8 @@ func TestAnAnswerOf1MiBGoesToTheVisitor(t *testing.T) {
})
got := get(t, addr, "/")
if got.status != http.StatusInternalServerError || len(got.body) != size {
if got.status != http.StatusInternalServerError ||
len(got.body) != size {
t.Errorf("answered %d with %d bytes, want waf's 500 with %d",
got.status, len(got.body), size)
}
@@ -1048,7 +1131,11 @@ func TestAnAnswerOf1MiBGoesToTheVisitor(t *testing.T) {
func startWAFWriting(t *testing.T, text string) string {
t.Helper()
listener, err := (&net.ListenConfig{}).Listen(t.Context(), "tcp", localhost+":0")
listener, err := (&net.ListenConfig{}).Listen(
t.Context(),
"tcp",
localhost+":0",
)
if err != nil {
t.Fatalf("listen: %v", err)
}
@@ -1126,10 +1213,15 @@ func TestAnAnswerThatCannotBePassedOnIsAnswered502(t *testing.T) {
app := startApp(t, func(http.ResponseWriter, *http.Request) {
t.Error("the app was asked")
})
addr, out := startRProxy(t, backend(t), app.URL, map[string]string{
timeoutSetting: "60000",
defaultDisposition: setting,
})
addr, out := startRProxy(
t,
backend(t),
app.URL,
map[string]string{
timeoutSetting: "60000",
defaultDisposition: setting,
},
)
if got := get(t, addr, "/"); got.status != http.StatusBadGateway {
t.Errorf("answered %+v, want 502", got)
@@ -1138,7 +1230,10 @@ func TestAnAnswerThatCannotBePassedOnIsAnswered502(t *testing.T) {
line := out.requestLine(t)
if line["status"] != float64(http.StatusBadGateway) ||
line["disposition"] != nil || line["default_disposition"] != nil {
t.Errorf("line %v, want status 502 and no disposition", line)
t.Errorf(
"line %v, want status 502 and no disposition",
line,
)
}
out.waitFor(t, "waf's answer is dropped")
@@ -1171,9 +1266,14 @@ func TestWithoutAnAnswerTheDefaultDispositionDecides(t *testing.T) {
t.Parallel()
app := startApp(t, greet)
addr, out := startRProxy(t, backend(t), app.URL, map[string]string{
timeoutSetting: "200",
})
addr, out := startRProxy(
t,
backend(t),
app.URL,
map[string]string{
timeoutSetting: "200",
},
)
wantGreeting(t, get(t, addr, "/"))
@@ -1190,10 +1290,15 @@ func TestWithoutAnAnswerTheDefaultDispositionDecides(t *testing.T) {
app := startApp(t, func(http.ResponseWriter, *http.Request) {
t.Error("the app was asked")
})
addr, out := startRProxy(t, backend(t), app.URL, map[string]string{
timeoutSetting: "200",
defaultDisposition: dispositionDeny,
})
addr, out := startRProxy(
t,
backend(t),
app.URL,
map[string]string{
timeoutSetting: "200",
defaultDisposition: dispositionDeny,
},
)
got := get(t, addr, "/")
if got.status != http.StatusServiceUnavailable {
@@ -1216,16 +1321,24 @@ func TestAVisitorThatGoesAwayWhileWAFIsAskedGetsNoDefault(t *testing.T) {
t.Run("with the default "+disposition, func(t *testing.T) {
t.Parallel()
standIn := startWAF(t, func(_ http.ResponseWriter, r *http.Request) {
<-r.Context().Done()
})
standIn := startWAF(
t,
func(_ http.ResponseWriter, r *http.Request) {
<-r.Context().Done()
},
)
app := startApp(t, func(http.ResponseWriter, *http.Request) {
t.Error("the app was asked")
})
addr, out := startRProxy(t, standIn.URL, app.URL, map[string]string{
timeoutSetting: "60000",
defaultDisposition: disposition,
})
addr, out := startRProxy(
t,
standIn.URL,
app.URL,
map[string]string{
timeoutSetting: "60000",
defaultDisposition: disposition,
},
)
conn := dial(t, addr)
send(t, conn, "GET / HTTP/1.1\r\nHost: site.example\r\n\r\n")
@@ -1443,12 +1556,21 @@ func TestReportGivesWhatHappened(t *testing.T) {
report.ResponseBytes != int64(len(greeting)) ||
report.DurationTotalMS <= 0 || report.DurationUpstreamTotalMS <= 0 ||
report.DurationUpstreamTotalMS > report.DurationTotalMS {
t.Errorf("report %+v, of %d bytes up and %d back", report, len(body), len(greeting))
t.Errorf(
"report %+v, of %d bytes up and %d back",
report,
len(body),
len(greeting),
)
}
line := out.requestLine(t)
if line["request_id"] != report.RequestID {
t.Errorf("line %v, report %+v, want the same request id", line, report)
t.Errorf(
"line %v, report %+v, want the same request id",
line,
report,
)
}
}
@@ -1477,9 +1599,14 @@ func TestWaitForReportsWaitsForAReportBeingSent(t *testing.T) {
t.Cleanup(backend.Close)
app := startApp(t, greet)
addr, _, server := startServer(t, backend.URL, app.URL, map[string]string{
timeoutSetting: "5000",
})
addr, _, server := startServer(
t,
backend.URL,
app.URL,
map[string]string{
timeoutSetting: "5000",
},
)
wantGreeting(t, get(t, addr, "/"))
@@ -1535,7 +1662,11 @@ func TestReportOfAWebSocketCountsWhatItCarried(t *testing.T) {
_ = res.Body.Close()
if res.StatusCode != http.StatusSwitchingProtocols {
t.Fatalf("status %d, want %d", res.StatusCode, http.StatusSwitchingProtocols)
t.Fatalf(
"status %d, want %d",
res.StatusCode,
http.StatusSwitchingProtocols,
)
}
// Past both time limits, the connection still carries what is sent.
@@ -1559,7 +1690,9 @@ func TestReportOfAWebSocketCountsWhatItCarried(t *testing.T) {
t.Errorf("report %+v, of %d bytes each way", report, len(message))
}
if line := out.requestLine(t); line["status"] != float64(res.StatusCode) {
if line := out.requestLine(t); line["status"] != float64(
res.StatusCode,
) {
t.Errorf("line %v, want status 101", line)
}
}
@@ -1714,7 +1847,8 @@ func TestEachRequestGetsAFreshID(t *testing.T) {
ids = append(ids, standIn.question(t).header.Get(requestIDHeader))
}
if slices.Contains(ids, fromTraefik) || ids[0] == "" || ids[0] == ids[1] {
if slices.Contains(ids, fromTraefik) || ids[0] == "" ||
ids[0] == ids[1] {
t.Errorf("ids %v, want two fresh ones", ids)
}
}
@@ -1732,7 +1866,13 @@ func TestLogLineGivesTheRequestAsSent(t *testing.T) {
app := startApp(t, greet)
addr, out := startRProxy(t, standIn.URL, app.URL, nil)
req := newRequest(t, http.MethodPost, addr, path+"?"+query, strings.NewReader(body))
req := newRequest(
t,
http.MethodPost,
addr,
path+"?"+query,
strings.NewReader(body),
)
req.Host = site
wantGreeting(t, visit(t, req))
@@ -1758,7 +1898,10 @@ func TestLogLineGivesTheRequestAsSent(t *testing.T) {
}
if line["default_disposition"] != nil {
t.Errorf("default_disposition is %v, want it left out", line["default_disposition"])
t.Errorf(
"default_disposition is %v, want it left out",
line["default_disposition"],
)
}
for _, name := range []string{"duration_request_ms", "duration_response_ms"} {