Rename internal/proxy to internal/servewaf (closes #173)
check / check (push) Waiting to run

The package passes nothing to an app since rproxy took that over, so it
is named after the command it serves. The rproxy tests call their
stand-in for servewaf standIn, since a local servewaf would hide the
package. No change of behaviour.

Model: opus-5-5
This commit is contained in:
2026-11-06 18:00:32 +00:00
parent 6deb9d7581
commit 6acde5c3bc
50 changed files with 488 additions and 484 deletions
+61 -61
View File
@@ -16,9 +16,9 @@ import (
"time"
"sneak.berlin/go/smallwebwaf/internal/config"
"sneak.berlin/go/smallwebwaf/internal/proxy"
"sneak.berlin/go/smallwebwaf/internal/requestlog"
"sneak.berlin/go/smallwebwaf/internal/rproxy"
"sneak.berlin/go/smallwebwaf/internal/servewaf"
)
// post is the start of a POST whose headers end with what follows it.
@@ -71,11 +71,11 @@ func TestABodyAnnouncedOverItsLimitIsRefusedOnceServeWAFAllowsIt(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, func(http.ResponseWriter, *http.Request) {
t.Error("the app was asked")
})
addr, _ := startRProxy(t, servewaf.URL, app.URL, map[string]string{
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
maxRequestSize: tc.limit,
})
@@ -85,11 +85,11 @@ func TestABodyAnnouncedOverItsLimitIsRefusedOnceServeWAFAllowsIt(t *testing.T) {
t.Errorf("answered %+v, want 413", got)
}
if asked := servewaf.question(t); len(asked.body) != tc.asked {
if asked := standIn.question(t); len(asked.body) != tc.asked {
t.Errorf("the question carries %d bytes, want %d", len(asked.body), tc.asked)
}
report := servewaf.report(t)
report := standIn.report(t)
if report.Status != http.StatusRequestEntityTooLarge {
t.Errorf("report %+v, want status 413", report)
}
@@ -100,9 +100,9 @@ func TestABodyAnnouncedOverItsLimitIsRefusedOnceServeWAFAllowsIt(t *testing.T) {
func TestADenyOutranksTheBodySizeLimit(t *testing.T) {
t.Parallel()
servewaf := startServeWAF(t, deny)
standIn := startServeWAF(t, deny)
app := startApp(t, greet)
addr, _ := startRProxy(t, servewaf.URL, app.URL, map[string]string{
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
maxRequestSize: "1K",
})
@@ -132,12 +132,12 @@ func TestABodyNotAnnouncedOverItsLimitIsRefused(t *testing.T) {
var asked atomic.Bool
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, func(w http.ResponseWriter, r *http.Request) {
asked.Store(true)
greet(w, r)
})
addr, _ := startRProxy(t, servewaf.URL, app.URL, map[string]string{
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
maxRequestSize: tc.limit,
})
@@ -165,12 +165,12 @@ func TestAResponseOverItsLimit(t *testing.T) {
t.Run("announced, is refused", func(t *testing.T) {
t.Parallel()
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set(contentLengthHeader, strconv.Itoa(len(large)))
_, _ = io.WriteString(w, large)
})
addr, _ := startRProxy(t, servewaf.URL, app.URL, map[string]string{
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
maxResponseSize: "1K",
})
@@ -179,7 +179,7 @@ func TestAResponseOverItsLimit(t *testing.T) {
t.Errorf("answered %d, want 502", got.status)
}
if report := servewaf.report(t); report.Status != http.StatusBadGateway {
if report := standIn.report(t); report.Status != http.StatusBadGateway {
t.Errorf("report %+v, want status 502", report)
}
})
@@ -187,13 +187,13 @@ func TestAResponseOverItsLimit(t *testing.T) {
t.Run("not announced, is cut off", func(t *testing.T) {
t.Parallel()
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, func(w http.ResponseWriter, _ *http.Request) {
_, _ = io.WriteString(w, large[:1])
_ = http.NewResponseController(w).Flush()
_, _ = io.WriteString(w, large[1:])
})
addr, _ := startRProxy(t, servewaf.URL, app.URL, map[string]string{
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
maxResponseSize: "1K",
})
@@ -205,7 +205,7 @@ func TestAResponseOverItsLimit(t *testing.T) {
t.Errorf("read %d bytes (%v), want the answer cut off", len(text), err)
}
report := servewaf.report(t)
report := standIn.report(t)
if report.Status != http.StatusOK || report.ResponseBytes > 1<<10 {
t.Errorf("report %+v, want status 200 and at most 1K of the answer", report)
}
@@ -217,11 +217,11 @@ func TestAHeadWhoseAnswerAnnouncesMoreThanTheResponseLimitIsPassedOn(t *testing.
const announced = "2048"
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set(contentLengthHeader, announced)
})
addr, _ := startRProxy(t, servewaf.URL, app.URL, map[string]string{
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
maxResponseSize: "1K",
})
@@ -240,9 +240,9 @@ func TestASettingOfOffSetsNoLimit(t *testing.T) {
t.Run(setting, func(t *testing.T) {
t.Parallel()
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, greet)
addr, _ := startRProxy(t, servewaf.URL, app.URL, map[string]string{
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
setting: "off",
})
@@ -251,7 +251,7 @@ func TestASettingOfOffSetsNoLimit(t *testing.T) {
wantGreeting(t, visit(t, newRequest(t, http.MethodPost, addr, "/",
strings.NewReader("a body"))))
if got := get(t, addr, proxy.HealthPath); got.status != http.StatusOK {
if got := get(t, addr, servewaf.HealthPath); got.status != http.StatusOK {
t.Errorf("answered %+v, want rproxy's own 200", got)
}
})
@@ -270,9 +270,9 @@ func TestAVisitorTooSlowToSendTheFirstPartIsAnswered408(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, greet)
addr, out := startRProxy(t, servewaf.URL, app.URL, map[string]string{
addr, out := startRProxy(t, standIn.URL, app.URL, map[string]string{
maxRequestTime: "500",
})
@@ -288,11 +288,11 @@ func TestAVisitorTooSlowToSendTheFirstPartIsAnswered408(t *testing.T) {
t.Errorf("line %v, want no disposition and 10 bytes", line)
}
if len(servewaf.questions) != 0 {
if len(standIn.questions) != 0 {
t.Error("servewaf was asked")
}
servewaf.wantNoReport(t)
standIn.wantNoReport(t)
})
}
}
@@ -300,9 +300,9 @@ func TestAVisitorTooSlowToSendTheFirstPartIsAnswered408(t *testing.T) {
func TestAVisitorThatGoesAwayBeforeTheFirstPartIsNotAsked(t *testing.T) {
t.Parallel()
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, greet)
addr, out := startRProxy(t, servewaf.URL, app.URL, nil)
addr, out := startRProxy(t, standIn.URL, app.URL, nil)
conn := dial(t, addr)
send(t, conn, post+announcedLength(100)+"some of it")
@@ -313,7 +313,7 @@ func TestAVisitorThatGoesAwayBeforeTheFirstPartIsNotAsked(t *testing.T) {
t.Errorf("line %v, want no answer and no disposition", line)
}
if len(servewaf.questions) != 0 {
if len(standIn.questions) != 0 {
t.Error("servewaf was asked")
}
}
@@ -334,9 +334,9 @@ func TestABodyThatCannotBeReadClosesTheConnectionWithoutAnAnswer(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, greet)
addr, out := startRProxy(t, servewaf.URL, app.URL, nil)
addr, out := startRProxy(t, standIn.URL, app.URL, nil)
conn := dial(t, addr)
send(t, conn, tc.request)
@@ -364,7 +364,7 @@ func TestABodyThatCannotBeReadClosesTheConnectionWithoutAnAnswer(t *testing.T) {
t.Errorf("line %v, want no answer and no disposition", line)
}
if len(servewaf.questions) != 0 {
if len(standIn.questions) != 0 {
t.Error("servewaf was asked")
}
})
@@ -404,11 +404,11 @@ func TestABodyLeftUnreadIsReadOnlyUntilTheRequestTimeLimit(t *testing.T) {
announced = 100 * questionBodyMaxBytes
)
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusNoContent)
})
_, _, server := startServer(t, servewaf.URL, app.URL, map[string]string{
_, _, server := startServer(t, standIn.URL, app.URL, map[string]string{
maxRequestTime: strconv.FormatInt(limit.Milliseconds(), 10),
})
@@ -454,9 +454,9 @@ func TestAnAnswerRProxyGivesItselfHasTheResponseTimeToBeSent(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
servewaf := startServeWAF(t, deny)
standIn := startServeWAF(t, deny)
app := startApp(t, greet)
_, _, server := startServer(t, servewaf.URL, app.URL, map[string]string{
_, _, server := startServer(t, standIn.URL, app.URL, map[string]string{
maxResponseTime: strconv.FormatInt(limit.Milliseconds(), 10),
})
@@ -484,9 +484,9 @@ func TestAnAnswerRProxyGivesItselfHasTheResponseTimeToBeSent(t *testing.T) {
func TestAVisitorTooSlowToSendTheRestIsAnswered408(t *testing.T) {
t.Parallel()
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, greet)
addr, _ := startRProxy(t, servewaf.URL, app.URL, map[string]string{
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
maxRequestTime: "3000",
})
@@ -498,11 +498,11 @@ func TestAVisitorTooSlowToSendTheRestIsAnswered408(t *testing.T) {
t.Errorf("status %d, want 408", status)
}
if asked := servewaf.question(t); len(asked.body) != questionBodyMaxBytes {
if asked := standIn.question(t); len(asked.body) != questionBodyMaxBytes {
t.Errorf("the question carries %d bytes", len(asked.body))
}
if report := servewaf.report(t); report.Status != http.StatusRequestTimeout {
if report := standIn.report(t); report.Status != http.StatusRequestTimeout {
t.Errorf("report %+v, want status 408", report)
}
}
@@ -553,8 +553,8 @@ func TestAnAppTooSlowToTakeTheRequestIsAnswered504(t *testing.T) {
writeSize = 32 << 10
)
servewaf := startServeWAF(t, allow)
addr, _ := startRProxy(t, servewaf.URL, startAppThatTakesNothing(t),
standIn := startServeWAF(t, allow)
addr, _ := startRProxy(t, standIn.URL, startAppThatTakesNothing(t),
map[string]string{maxRequestTime: "3000"})
conn := dial(t, addr)
@@ -580,14 +580,14 @@ func TestAnAppTooSlowToAnswerIsAnswered504(t *testing.T) {
t.Parallel()
release := make(chan struct{})
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, func(http.ResponseWriter, *http.Request) {
<-release
})
t.Cleanup(func() { close(release) })
addr, _ := startRProxy(t, servewaf.URL, app.URL, map[string]string{
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
maxResponseTime: "300",
})
@@ -596,7 +596,7 @@ func TestAnAppTooSlowToAnswerIsAnswered504(t *testing.T) {
t.Errorf("answered %d, want 504", got.status)
}
if report := servewaf.report(t); report.Status != http.StatusGatewayTimeout {
if report := standIn.report(t); report.Status != http.StatusGatewayTimeout {
t.Errorf("report %+v, want status 504", report)
}
}
@@ -607,7 +607,7 @@ func TestAnAppTooSlowToFinishItsAnswerIsCutOff(t *testing.T) {
const start = "the start"
release := make(chan struct{})
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, func(w http.ResponseWriter, _ *http.Request) {
_, _ = io.WriteString(w, start)
_ = http.NewResponseController(w).Flush()
@@ -619,7 +619,7 @@ func TestAnAppTooSlowToFinishItsAnswerIsCutOff(t *testing.T) {
// The time limit is long enough for a loaded host to pass on the start of the
// answer before it runs out.
addr, _ := startRProxy(t, servewaf.URL, app.URL, map[string]string{
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
maxResponseTime: "3000",
})
@@ -642,7 +642,7 @@ func TestAnAppTooSlowToFinishItsAnswerIsCutOff(t *testing.T) {
res.StatusCode, body, err, start)
}
if report := servewaf.report(t); report.Status != http.StatusOK {
if report := standIn.report(t); report.Status != http.StatusOK {
t.Errorf("report %+v, want the status the visitor got", report)
}
}
@@ -656,7 +656,7 @@ func TestAVisitorTooSlowToTakeTheAnswerIsCutOff(t *testing.T) {
writeSize = 32 << 10
)
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, func(w http.ResponseWriter, _ *http.Request) {
part := make([]byte, writeSize)
@@ -669,7 +669,7 @@ func TestAVisitorTooSlowToTakeTheAnswerIsCutOff(t *testing.T) {
})
// The time limit is long enough for a loaded host to start passing on the
// answer before it runs out.
addr, out := startRProxy(t, servewaf.URL, app.URL, map[string]string{
addr, out := startRProxy(t, standIn.URL, app.URL, map[string]string{
maxResponseTime: "3000",
})
@@ -684,7 +684,7 @@ func TestAVisitorTooSlowToTakeTheAnswerIsCutOff(t *testing.T) {
t.Errorf("line %v, want status 200 and the answer cut off", line)
}
report := servewaf.report(t)
report := standIn.report(t)
if report.Status != http.StatusOK || report.ResponseBytes >= bodySize {
t.Errorf("report %+v, want status 200 and the answer cut off", report)
}
@@ -693,15 +693,15 @@ func TestAVisitorTooSlowToTakeTheAnswerIsCutOff(t *testing.T) {
func TestAnAppThatCannotBeReachedIsAnswered502WithAReport(t *testing.T) {
t.Parallel()
servewaf := startServeWAF(t, allow)
addr, _ := startRProxy(t, servewaf.URL, nowhere, nil)
standIn := startServeWAF(t, allow)
addr, _ := startRProxy(t, standIn.URL, nowhere, nil)
got := get(t, addr, "/")
if got.status != http.StatusBadGateway {
t.Errorf("answered %d, want 502", got.status)
}
if report := servewaf.report(t); report.Status != http.StatusBadGateway {
if report := standIn.report(t); report.Status != http.StatusBadGateway {
t.Errorf("report %+v, want status 502", report)
}
}
@@ -709,11 +709,11 @@ func TestAnAppThatCannotBeReachedIsAnswered502WithAReport(t *testing.T) {
func TestAVisitorThatStopsSendingAfterTheAppHasAnsweredGetsTheAnswer(t *testing.T) {
t.Parallel()
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, func(w http.ResponseWriter, _ *http.Request) {
_, _ = io.WriteString(w, greeting)
})
addr, _ := startRProxy(t, servewaf.URL, app.URL, map[string]string{
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
maxRequestTime: "3000",
})
@@ -732,12 +732,12 @@ func TestAVisitorThatStopsSendingWhileTheAppWorksGetsNoAnswer(t *testing.T) {
t.Parallel()
working := make(chan struct{})
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, func(_ http.ResponseWriter, r *http.Request) {
close(working)
<-r.Context().Done()
})
addr, out := startRProxy(t, servewaf.URL, app.URL, nil)
addr, out := startRProxy(t, standIn.URL, app.URL, nil)
conn := dial(t, addr)
send(t, conn, "GET / HTTP/1.1\r\nHost: site.example\r\n\r\n")
@@ -773,7 +773,7 @@ func TestTheRequestTimeLimitDoesNotCutAnAnswerOnceTheAppHasTheRequest(t *testing
const answer = "the end of a long answer"
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, func(w http.ResponseWriter, r *http.Request) {
_, _ = io.Copy(io.Discard, r.Body)
_ = http.NewResponseController(w).Flush()
@@ -782,7 +782,7 @@ func TestTheRequestTimeLimitDoesNotCutAnAnswerOnceTheAppHasTheRequest(t *testing
_, _ = io.WriteString(w, answer)
})
addr, _ := startRProxy(t, servewaf.URL, app.URL, map[string]string{
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
maxRequestTime: "2000",
})
@@ -802,18 +802,18 @@ func TestAVisitorThatStopsSendingGetsAnAnswerRProxyGivesByTheDeadline(t *testing
{"a deny", post, http.StatusForbidden},
{
"the health check",
"GET " + proxy.HealthPath + " HTTP/1.1\r\nHost: site.example\r\n",
"GET " + servewaf.HealthPath + " HTTP/1.1\r\nHost: site.example\r\n",
http.StatusOK,
},
} {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
servewaf := startServeWAF(t, deny)
standIn := startServeWAF(t, deny)
app := startApp(t, greet)
// The time limit is long enough for a loaded host to read the first part of
// the body before it runs out.
addr, _ := startRProxy(t, servewaf.URL, app.URL, map[string]string{
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
maxRequestTime: "3000",
})