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
+51 -51
View File
@@ -12,11 +12,11 @@ import (
"strings"
"testing"
"sneak.berlin/go/smallwebwaf/internal/proxy"
"sneak.berlin/go/smallwebwaf/internal/servewaf"
)
// questionBodyMaxBytes is the most of a body a question carries.
const questionBodyMaxBytes = proxy.QuestionBodyMaxBytes
const questionBodyMaxBytes = servewaf.QuestionBodyMaxBytes
// chunked is the encoding of a body whose length the visitor did not announce.
const chunked = "chunked"
@@ -29,9 +29,9 @@ const pathGoReencodes = "/some%2Fpath/with%20space|pipe"
func TestQuestionIsTheVisitorsRequestWithRProxysHeaders(t *testing.T) {
t.Parallel()
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, greet)
addr, _ := startRProxy(t, servewaf.URL, app.URL, nil)
addr, _ := startRProxy(t, standIn.URL, app.URL, nil)
const target = pathGoReencodes + "?b=2&a=1&bad=%zz;x"
@@ -42,16 +42,16 @@ func TestQuestionIsTheVisitorsRequestWithRProxysHeaders(t *testing.T) {
req.Header.Set(forwardedForHeader, "198.51.100.1")
req.Header.Set(forwardedProtoHeader, "gopher")
req.Header.Set(requestIDHeader, "the-visitor's")
req.Header.Set(proxy.ClientHeader, "198.51.100.2")
req.Header.Set(proxy.PeerHeader, "198.51.100.3")
req.Header.Set(proxy.ContentLengthHeader, "12345")
req.Header.Set(servewaf.ClientHeader, "198.51.100.2")
req.Header.Set(servewaf.PeerHeader, "198.51.100.3")
req.Header.Set(servewaf.ContentLengthHeader, "12345")
// Go's client then sends no User-Agent, so that one in the question would be
// Go's own.
req.Header["User-Agent"] = nil
wantGreeting(t, visit(t, req))
asked := servewaf.question(t)
asked := standIn.question(t)
if asked.method != http.MethodDelete || asked.target != target ||
asked.host != site {
t.Errorf("asked about %s %s at %s", asked.method, asked.target, asked.host)
@@ -68,8 +68,8 @@ func TestQuestionIsTheVisitorsRequestWithRProxysHeaders(t *testing.T) {
want.Set(forwardedForHeader, "198.51.100.1")
want.Set(forwardedProtoHeader, "http")
want.Set(requestIDHeader, asked.header.Get(requestIDHeader))
want.Set(proxy.ClientHeader, localhost)
want.Set(proxy.PeerHeader, localhost)
want.Set(servewaf.ClientHeader, localhost)
want.Set(servewaf.PeerHeader, localhost)
if !maps.EqualFunc(asked.header, want, slices.Equal) {
t.Errorf("the question's headers are %v, want %v", asked.header, want)
@@ -93,14 +93,14 @@ func TestQuestionNamesTheVisitorATrustedProxySpeaksFor(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
forwarded := make(chan http.Header, 1)
app := startApp(t, func(w http.ResponseWriter, r *http.Request) {
forwarded <- r.Header.Clone()
greet(w, r)
})
addr, out := startRProxy(t, servewaf.URL, app.URL, map[string]string{
addr, out := startRProxy(t, standIn.URL, app.URL, map[string]string{
trustedProxies: tc.trusted,
})
@@ -109,9 +109,9 @@ func TestQuestionNamesTheVisitorATrustedProxySpeaksFor(t *testing.T) {
req.Header.Set(forwardedProtoHeader, "https")
wantGreeting(t, visit(t, req))
asked := servewaf.question(t)
if asked.header.Get(proxy.ClientHeader) != tc.client ||
asked.header.Get(proxy.PeerHeader) != localhost ||
asked := standIn.question(t)
if asked.header.Get(servewaf.ClientHeader) != tc.client ||
asked.header.Get(servewaf.PeerHeader) != localhost ||
asked.header.Get(forwardedForHeader) != visitor ||
asked.header.Get(forwardedProtoHeader) != tc.proto {
t.Errorf("the question's headers are %v", asked.header)
@@ -157,9 +157,9 @@ func TestQuestionNamesTheClientAsTheForwardedAddressesSay(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, _ := startRProxy(t, servewaf.URL, app.URL, map[string]string{
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
trustedProxies: localhost + "/32,10.0.0.0/8",
})
@@ -167,7 +167,7 @@ func TestQuestionNamesTheClientAsTheForwardedAddressesSay(t *testing.T) {
req.Header[forwardedForHeader] = tc.header
wantGreeting(t, visit(t, req))
if got := servewaf.question(t).header.Get(proxy.ClientHeader); got != tc.client {
if got := standIn.question(t).header.Get(servewaf.ClientHeader); got != tc.client {
t.Errorf("the question names %s, want %s", got, tc.client)
}
})
@@ -197,7 +197,7 @@ func TestFirst64KiBReachServeWAFAndTheWholeBodyTheApp(t *testing.T) {
t.Parallel()
body := randomBytes(size)
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
received := make(chan []byte, 1)
app := startApp(t, func(w http.ResponseWriter, r *http.Request) {
whole, _ := io.ReadAll(r.Body)
@@ -205,7 +205,7 @@ func TestFirst64KiBReachServeWAFAndTheWholeBodyTheApp(t *testing.T) {
greet(w, r)
})
addr, _ := startRProxy(t, servewaf.URL, app.URL, nil)
addr, _ := startRProxy(t, standIn.URL, app.URL, nil)
req := newRequest(t, http.MethodPost, addr, "/", bytes.NewReader(body))
if !announced {
@@ -215,7 +215,7 @@ func TestFirst64KiBReachServeWAFAndTheWholeBodyTheApp(t *testing.T) {
wantGreeting(t, visit(t, req))
asked := servewaf.question(t)
asked := standIn.question(t)
want := body[:min(size, questionBodyMaxBytes)]
wantQuestionBody(t, asked, want, size, announced)
@@ -223,7 +223,7 @@ func TestFirst64KiBReachServeWAFAndTheWholeBodyTheApp(t *testing.T) {
t.Error("the app did not get the whole body")
}
if report := servewaf.report(t); report.RequestBytes != int64(size) {
if report := standIn.report(t); report.RequestBytes != int64(size) {
t.Errorf("report %+v, of %d bytes", report, size)
}
})
@@ -243,7 +243,7 @@ func wantQuestionBody(
len(want))
}
values := asked.header.Values(proxy.ContentLengthHeader)
values := asked.header.Values(servewaf.ContentLengthHeader)
if announced {
if !slices.Equal(values, []string{strconv.Itoa(size)}) ||
@@ -264,9 +264,9 @@ func wantQuestionBody(
func TestDenyNeedsOnlyTheFirstPartOfALargeBody(t *testing.T) {
t.Parallel()
servewaf := startServeWAF(t, deny)
standIn := startServeWAF(t, deny)
app := startApp(t, greet)
addr, _ := startRProxy(t, servewaf.URL, app.URL, nil)
addr, _ := startRProxy(t, standIn.URL, app.URL, nil)
// Far more announced than sent. Go's server does not wait for that much, so
// the answer comes at once.
@@ -278,7 +278,7 @@ func TestDenyNeedsOnlyTheFirstPartOfALargeBody(t *testing.T) {
t.Errorf("status %d, want servewaf's 403", status)
}
if report := servewaf.report(t); report.RequestBytes != questionBodyMaxBytes {
if report := standIn.report(t); report.RequestBytes != questionBodyMaxBytes {
t.Errorf("report %+v, want the first part's bytes", report)
}
}
@@ -306,8 +306,8 @@ func TestAQuestionCarriesItsBodyWhateverTheMethod(t *testing.T) {
t.Run(method+" "+tc.name, func(t *testing.T) {
t.Parallel()
servewaf := startServeWAF(t, deny)
addr, _ := startRProxy(t, servewaf.URL, nowhere, nil)
standIn := startServeWAF(t, deny)
addr, _ := startRProxy(t, standIn.URL, nowhere, nil)
conn := dial(t, addr)
send(t, conn, method+" /x HTTP/1.1\r\nHost: site.example\r\n"+tc.framing)
@@ -316,7 +316,7 @@ func TestAQuestionCarriesItsBodyWhateverTheMethod(t *testing.T) {
t.Errorf("status %d, want servewaf's 403", status)
}
asked := servewaf.question(t)
asked := standIn.question(t)
if string(asked.body) != tc.body ||
!slices.Equal(asked.transferEncoding, tc.encoding) {
t.Errorf("the question carries %q, encoded %v, want %q, encoded %v",
@@ -334,11 +334,11 @@ func TestAMethodNotPassedOnIsAnswered405(t *testing.T) {
t.Run(method, 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, out := startRProxy(t, servewaf.URL, app.URL, nil)
addr, out := startRProxy(t, standIn.URL, app.URL, nil)
got := visit(t, newRequest(t, method, addr, "/", http.NoBody))
if got.status != http.StatusMethodNotAllowed ||
@@ -352,11 +352,11 @@ func TestAMethodNotPassedOnIsAnswered405(t *testing.T) {
t.Errorf("line %v, want status 405 and no disposition", line)
}
if len(servewaf.questions) != 0 {
if len(standIn.questions) != 0 {
t.Error("servewaf was asked")
}
servewaf.wantNoReport(t)
standIn.wantNoReport(t)
})
}
}
@@ -372,18 +372,18 @@ func TestEachMethodPassedOnReachesServeWAFAndTheApp(t *testing.T) {
t.Parallel()
reached := make(chan string, 1)
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, func(_ http.ResponseWriter, r *http.Request) {
reached <- r.Method
})
addr, _ := startRProxy(t, servewaf.URL, app.URL, nil)
addr, _ := startRProxy(t, standIn.URL, app.URL, nil)
got := visit(t, newRequest(t, method, addr, "/", http.NoBody))
if got.status != http.StatusOK {
t.Errorf("answered %+v, want the app's 200", got)
}
if asked := servewaf.question(t); asked.method != method {
if asked := standIn.question(t); asked.method != method {
t.Errorf("servewaf was asked about %s", asked.method)
}
@@ -416,9 +416,9 @@ func TestARequestThatCannotGoToServeWAFAsSentIsRefused(t *testing.T) {
t.Run(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, request)
@@ -433,11 +433,11 @@ func TestARequestThatCannotGoToServeWAFAsSentIsRefused(t *testing.T) {
t.Errorf("line %v, want status 400 and no disposition", line)
}
if len(servewaf.questions) != 0 {
if len(standIn.questions) != 0 {
t.Error("servewaf was asked")
}
servewaf.wantNoReport(t)
standIn.wantNoReport(t)
})
}
}
@@ -447,9 +447,9 @@ func TestAHostWithAPercentSignButNoBracketGoesToServeWAF(t *testing.T) {
const host = "a%b"
servewaf := startServeWAF(t, allow)
standIn := startServeWAF(t, allow)
app := startApp(t, greet)
addr, _ := startRProxy(t, servewaf.URL, app.URL, nil)
addr, _ := startRProxy(t, standIn.URL, app.URL, nil)
conn := dial(t, addr)
send(t, conn, "GET / HTTP/1.1\r\nHost: "+host+"\r\n\r\n")
@@ -458,7 +458,7 @@ func TestAHostWithAPercentSignButNoBracketGoesToServeWAF(t *testing.T) {
t.Errorf("status %d, want the app's 200", status)
}
if asked := servewaf.question(t); asked.host != host {
if asked := standIn.question(t); asked.host != host {
t.Errorf("asked about the host %q, want %q", asked.host, host)
}
}
@@ -468,15 +468,15 @@ func TestATrustedPeerWithNoForwardedProtoIsAskedAboutAsHTTP(t *testing.T) {
const want = "http"
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{
trustedProxies: localhost + "/32",
})
wantGreeting(t, get(t, addr, "/"))
asked := servewaf.question(t)
asked := standIn.question(t)
if got := asked.header.Get(forwardedProtoHeader); got != want {
t.Errorf("the question's %s is %q, want %s", forwardedProtoHeader, got, want)
}
@@ -497,9 +497,9 @@ func TestAQuestionNamesNoZone(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)
_, out, server := startServer(t, servewaf.URL, app.URL, map[string]string{
_, out, server := startServer(t, standIn.URL, app.URL, map[string]string{
trustedProxies: localhost + "/32",
})
@@ -509,9 +509,9 @@ func TestAQuestionNamesNoZone(t *testing.T) {
server.Handler.ServeHTTP(httptest.NewRecorder(), req)
asked := servewaf.question(t)
if asked.header.Get(proxy.ClientHeader) != tc.client ||
asked.header.Get(proxy.PeerHeader) != tc.peer {
asked := standIn.question(t)
if asked.header.Get(servewaf.ClientHeader) != tc.client ||
asked.header.Get(servewaf.PeerHeader) != tc.peer {
t.Errorf("the question's headers are %v", asked.header)
}