Rename internal/proxy to internal/servewaf (closes #173)
check / check (push) Successful in 3m57s
check / check (push) Successful in 3m57s
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:
@@ -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",
|
||||
})
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -16,9 +16,9 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"sneak.berlin/go/smallwebwaf/internal/proxy"
|
||||
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
||||
"sneak.berlin/go/smallwebwaf/internal/rules"
|
||||
"sneak.berlin/go/smallwebwaf/internal/servewaf"
|
||||
)
|
||||
|
||||
// flushAfterEachWrite has ReverseProxy pass on each part of the app's answer as
|
||||
@@ -129,7 +129,7 @@ func (rq *request) readFirstPartOfBody() bool {
|
||||
}
|
||||
|
||||
_ = rq.rc.SetReadDeadline(rq.requestDeadline())
|
||||
held, err := io.ReadAll(io.LimitReader(rq.body, proxy.QuestionBodyMaxBytes))
|
||||
held, err := io.ReadAll(io.LimitReader(rq.body, servewaf.QuestionBodyMaxBytes))
|
||||
// From here on, the request timer ends a read of the rest of the body, so that
|
||||
// the answer can name the side rproxy was waiting on.
|
||||
_ = rq.rc.SetReadDeadline(time.Time{})
|
||||
@@ -384,7 +384,7 @@ func (rq *request) finish(ctx context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
report := &proxy.Report{
|
||||
report := &servewaf.Report{
|
||||
RequestID: rq.id,
|
||||
Status: min(rq.out.status, reportStatusMax),
|
||||
RequestBytes: requestBytes,
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
"time"
|
||||
|
||||
"sneak.berlin/go/smallwebwaf/internal/config"
|
||||
"sneak.berlin/go/smallwebwaf/internal/proxy"
|
||||
"sneak.berlin/go/smallwebwaf/internal/servewaf"
|
||||
)
|
||||
|
||||
// How rproxy keeps connections to the app and to servewaf open between
|
||||
@@ -85,7 +85,7 @@ func New(params Params) *Server {
|
||||
transport: newTransport(),
|
||||
serveWAFTransport: newServeWAFTransport(),
|
||||
reportURL: (&url.URL{
|
||||
Scheme: backend.Scheme, Host: backend.Host, Path: proxy.ReportPath,
|
||||
Scheme: backend.Scheme, Host: backend.Host, Path: servewaf.ReportPath,
|
||||
}).String(),
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
rq := h.newRequest(w, r)
|
||||
defer rq.finish(r.Context())
|
||||
|
||||
if r.Method == http.MethodGet && r.URL.Path == proxy.HealthPath {
|
||||
if r.Method == http.MethodGet && r.URL.Path == servewaf.HealthPath {
|
||||
rq.answerHealth()
|
||||
|
||||
return
|
||||
@@ -199,9 +199,9 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
rq.noteAnswer(answer)
|
||||
|
||||
switch rq.disposition {
|
||||
case proxy.DispositionAllow:
|
||||
case servewaf.DispositionAllow:
|
||||
rq.passToApp(r.Context())
|
||||
case proxy.DispositionClose:
|
||||
case servewaf.DispositionClose:
|
||||
// This panic has Go's server close the connection without an answer,
|
||||
// and log nothing; the deferred finish still runs.
|
||||
panic(http.ErrAbortHandler)
|
||||
|
||||
@@ -19,9 +19,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"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -54,7 +54,7 @@ const (
|
||||
|
||||
// The headers the tests set and look at.
|
||||
const (
|
||||
dispositionHeader = proxy.DispositionHeader
|
||||
dispositionHeader = servewaf.DispositionHeader
|
||||
forwardedForHeader = "X-Forwarded-For"
|
||||
forwardedProtoHeader = "X-Forwarded-Proto"
|
||||
requestIDHeader = "X-Request-ID"
|
||||
@@ -70,9 +70,9 @@ const (
|
||||
|
||||
// What the stand-in for servewaf answers.
|
||||
const (
|
||||
dispositionAllow = proxy.DispositionAllow
|
||||
dispositionDeny = proxy.DispositionDeny
|
||||
dispositionClose = proxy.DispositionClose
|
||||
dispositionAllow = servewaf.DispositionAllow
|
||||
dispositionDeny = servewaf.DispositionDeny
|
||||
dispositionClose = servewaf.DispositionClose
|
||||
// deniedBody is the body of a deny.
|
||||
deniedBody = "refused by servewaf"
|
||||
)
|
||||
@@ -173,7 +173,7 @@ type serveWAF struct {
|
||||
*httptest.Server
|
||||
|
||||
questions chan question
|
||||
reports chan proxy.Report
|
||||
reports chan servewaf.Report
|
||||
}
|
||||
|
||||
// startServeWAF starts a stand-in for servewaf.
|
||||
@@ -182,11 +182,11 @@ func startServeWAF(t *testing.T, answer http.HandlerFunc) *serveWAF {
|
||||
|
||||
s := &serveWAF{
|
||||
questions: make(chan question, 10),
|
||||
reports: make(chan proxy.Report, 10),
|
||||
reports: make(chan servewaf.Report, 10),
|
||||
}
|
||||
s.Server = httptest.NewServer(http.HandlerFunc(
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get(proxy.ClientHeader) == "" {
|
||||
if r.Header.Get(servewaf.ClientHeader) == "" {
|
||||
s.takeReport(t, w, r)
|
||||
|
||||
return
|
||||
@@ -213,10 +213,10 @@ func startServeWAF(t *testing.T, answer http.HandlerFunc) *serveWAF {
|
||||
func (s *serveWAF) takeReport(t *testing.T, w http.ResponseWriter, r *http.Request) {
|
||||
t.Helper()
|
||||
|
||||
var report proxy.Report
|
||||
var report servewaf.Report
|
||||
|
||||
err := json.NewDecoder(r.Body).Decode(&report)
|
||||
if err != nil || r.Method != http.MethodPost || r.URL.Path != proxy.ReportPath {
|
||||
if err != nil || r.Method != http.MethodPost || r.URL.Path != servewaf.ReportPath {
|
||||
t.Errorf("%s %s is no report: %v", r.Method, r.URL.Path, err)
|
||||
}
|
||||
|
||||
@@ -237,7 +237,7 @@ func (s *serveWAF) wantNoReport(t *testing.T) {
|
||||
}
|
||||
|
||||
// report waits for a report.
|
||||
func (s *serveWAF) report(t *testing.T) proxy.Report {
|
||||
func (s *serveWAF) report(t *testing.T) servewaf.Report {
|
||||
t.Helper()
|
||||
|
||||
select {
|
||||
@@ -246,7 +246,7 @@ func (s *serveWAF) report(t *testing.T) proxy.Report {
|
||||
case <-time.After(waitLimit):
|
||||
t.Fatal("no report")
|
||||
|
||||
return proxy.Report{}
|
||||
return servewaf.Report{}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@ func startServeWAFAnsweringReports(
|
||||
|
||||
backend := httptest.NewServer(http.HandlerFunc(
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get(proxy.ClientHeader) != "" {
|
||||
if r.Header.Get(servewaf.ClientHeader) != "" {
|
||||
answer(w, r)
|
||||
|
||||
return
|
||||
@@ -498,7 +498,7 @@ func readStatus(t *testing.T, conn net.Conn) int {
|
||||
func TestPassesAnAllowedRequestToTheAppAndItsAnswerBack(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
servewaf := startServeWAF(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
standIn := startServeWAF(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set(asnHeader, "AS64496")
|
||||
w.Header().Set(countryHeader, "DE")
|
||||
allow(w, r)
|
||||
@@ -512,7 +512,7 @@ func TestPassesAnAllowedRequestToTheAppAndItsAnswerBack(t *testing.T) {
|
||||
w.WriteHeader(http.StatusTeapot)
|
||||
_, _ = io.WriteString(w, greeting)
|
||||
})
|
||||
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"
|
||||
|
||||
@@ -530,7 +530,7 @@ func TestPassesAnAllowedRequestToTheAppAndItsAnswerBack(t *testing.T) {
|
||||
}
|
||||
|
||||
received := <-seen
|
||||
asked := servewaf.question(t)
|
||||
asked := standIn.question(t)
|
||||
|
||||
if received.RequestURI != target || received.Host != site {
|
||||
t.Errorf("the app saw %s for %s", received.RequestURI, received.Host)
|
||||
@@ -557,14 +557,14 @@ func TestAPeerNotTrustedHasItsForwardedHeadersReplaced(t *testing.T) {
|
||||
"X-Forwarded-Tls-Client-Cert-Info", "X-Real-Ip",
|
||||
}
|
||||
|
||||
servewaf := startServeWAF(t, allow)
|
||||
standIn := startServeWAF(t, allow)
|
||||
seen := make(chan http.Header, 1)
|
||||
app := startApp(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
seen <- r.Header.Clone()
|
||||
|
||||
greet(w, r)
|
||||
})
|
||||
addr, _ := startRProxy(t, servewaf.URL, app.URL, map[string]string{
|
||||
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
|
||||
trustedProxies: "10.0.0.0/8",
|
||||
})
|
||||
|
||||
@@ -602,14 +602,14 @@ func TestAPeerNotTrustedHasItsForwardedHeadersReplaced(t *testing.T) {
|
||||
func TestATrustedProxysForwardedHeadersPassOn(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
servewaf := startServeWAF(t, allow)
|
||||
standIn := startServeWAF(t, allow)
|
||||
seen := make(chan http.Header, 1)
|
||||
app := startApp(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
seen <- r.Header.Clone()
|
||||
|
||||
greet(w, r)
|
||||
})
|
||||
addr, _ := startRProxy(t, servewaf.URL, app.URL, map[string]string{
|
||||
addr, _ := startRProxy(t, standIn.URL, app.URL, map[string]string{
|
||||
trustedProxies: localhost + "/32",
|
||||
})
|
||||
|
||||
@@ -641,12 +641,12 @@ func TestATrustedProxysForwardedHeadersPassOn(t *testing.T) {
|
||||
func TestAnAnswerWithoutAContentTypeGetsNone(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
servewaf := startServeWAF(t, allow)
|
||||
standIn := startServeWAF(t, allow)
|
||||
app := startApp(t, func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header()["Content-Type"] = nil
|
||||
_, _ = io.WriteString(w, "<html>")
|
||||
})
|
||||
_, _, server := startServer(t, servewaf.URL, app.URL, nil)
|
||||
_, _, server := startServer(t, standIn.URL, app.URL, nil)
|
||||
|
||||
req := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/", http.NoBody)
|
||||
w := httptest.NewRecorder()
|
||||
@@ -704,11 +704,11 @@ func TestRemovesTheVisitorsLookupHeadersWhenServeWAFGivesNone(t *testing.T) {
|
||||
func TestDenyGivesTheVisitorServeWAFsAnswer(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
servewaf := startServeWAF(t, deny)
|
||||
standIn := startServeWAF(t, deny)
|
||||
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 := get(t, addr, "/")
|
||||
if got.status != http.StatusForbidden || got.body != deniedBody ||
|
||||
@@ -720,7 +720,7 @@ func TestDenyGivesTheVisitorServeWAFsAnswer(t *testing.T) {
|
||||
t.Errorf("the visitor got %s", dispositionHeader)
|
||||
}
|
||||
|
||||
report := servewaf.report(t)
|
||||
report := standIn.report(t)
|
||||
if report.Status != http.StatusForbidden ||
|
||||
report.ResponseBytes != int64(len(deniedBody)) ||
|
||||
report.DurationUpstreamTotal != 0 {
|
||||
@@ -736,9 +736,9 @@ func TestDenyGivesTheVisitorServeWAFsAnswer(t *testing.T) {
|
||||
func TestADeniedHeadKeepsServeWAFsContentLength(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)
|
||||
|
||||
got := visit(t, newRequest(t, http.MethodHead, addr, "/", http.NoBody))
|
||||
if got.status != http.StatusForbidden ||
|
||||
@@ -758,15 +758,15 @@ func TestAnAnswerRProxyHoldsWholeIsSentBeforeItsLogLine(t *testing.T) {
|
||||
}{
|
||||
{"a deny", "GET /" + host, deniedBody, http.StatusForbidden},
|
||||
{"rproxy's own answer", "GET x:admin" + host, "Bad Request\n", http.StatusBadRequest},
|
||||
{"the health check", "GET " + proxy.HealthPath + host, "ok\n", http.StatusOK},
|
||||
{"the health check", "GET " + servewaf.HealthPath + host, "ok\n", http.StatusOK},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
log := heldLog{release: make(chan struct{})}
|
||||
servewaf := startServeWAF(t, deny)
|
||||
standIn := startServeWAF(t, deny)
|
||||
app := startApp(t, greet)
|
||||
addr, _ := startServerLogging(t, servewaf.URL, app.URL, nil, log, io.Discard)
|
||||
addr, _ := startServerLogging(t, standIn.URL, app.URL, nil, log, io.Discard)
|
||||
|
||||
t.Cleanup(func() { close(log.release) })
|
||||
|
||||
@@ -794,9 +794,9 @@ func TestAnAnswerRProxyHoldsWholeIsSentBeforeItsLogLine(t *testing.T) {
|
||||
func TestRProxysOwnAnswerIsPlainText(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)
|
||||
|
||||
conn := dial(t, addr)
|
||||
send(t, conn, "GET x:admin HTTP/1.1\r\nHost: site.example\r\n\r\n")
|
||||
@@ -817,14 +817,14 @@ func TestRProxysOwnAnswerIsPlainText(t *testing.T) {
|
||||
func TestCloseClosesTheConnectionWithoutAnAnswer(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
servewaf := startServeWAF(t, func(w http.ResponseWriter, _ *http.Request) {
|
||||
standIn := startServeWAF(t, func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header().Set(dispositionHeader, dispositionClose)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
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)
|
||||
|
||||
conn := dial(t, addr)
|
||||
send(t, conn, "GET / HTTP/1.1\r\nHost: site.example\r\n\r\n")
|
||||
@@ -835,7 +835,7 @@ func TestCloseClosesTheConnectionWithoutAnAnswer(t *testing.T) {
|
||||
text, err)
|
||||
}
|
||||
|
||||
report := servewaf.report(t)
|
||||
report := standIn.report(t)
|
||||
if report.Status != 0 || report.ResponseBytes != 0 {
|
||||
t.Errorf("report %+v, of a visitor sent nothing", report)
|
||||
}
|
||||
@@ -935,7 +935,7 @@ func TestAnAnswerOtherThanAllowGoesToTheVisitorAsServeWAFGaveIt(t *testing.T) {
|
||||
t.Run(tc.name+" with the default "+setting, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
servewaf := startServeWAF(t, func(w http.ResponseWriter, _ *http.Request) {
|
||||
standIn := startServeWAF(t, func(w http.ResponseWriter, _ *http.Request) {
|
||||
if tc.disposition != "" {
|
||||
w.Header().Set(dispositionHeader, tc.disposition)
|
||||
}
|
||||
@@ -947,7 +947,7 @@ func TestAnAnswerOtherThanAllowGoesToTheVisitorAsServeWAFGaveIt(t *testing.T) {
|
||||
app := startApp(t, func(http.ResponseWriter, *http.Request) {
|
||||
t.Error("the app was asked")
|
||||
})
|
||||
addr, out := startRProxy(t, servewaf.URL, app.URL, map[string]string{
|
||||
addr, out := startRProxy(t, standIn.URL, app.URL, map[string]string{
|
||||
defaultDisposition: setting,
|
||||
})
|
||||
|
||||
@@ -977,11 +977,11 @@ func TestAnAnswerOtherThanAllowGoesToTheVisitorAsServeWAFGaveIt(t *testing.T) {
|
||||
func TestAnAnswerWithoutAValidDispositionGetsNoReport(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
servewaf := startServeWAF(t, func(w http.ResponseWriter, _ *http.Request) {
|
||||
standIn := startServeWAF(t, func(w http.ResponseWriter, _ *http.Request) {
|
||||
http.Error(w, "refused", http.StatusBadRequest)
|
||||
})
|
||||
app := startApp(t, greet)
|
||||
addr, out := startRProxy(t, servewaf.URL, app.URL, nil)
|
||||
addr, out := startRProxy(t, standIn.URL, app.URL, nil)
|
||||
|
||||
if got := get(t, addr, "/"); got.status != http.StatusBadRequest {
|
||||
t.Errorf("answered %+v, want servewaf's 400", got)
|
||||
@@ -991,18 +991,18 @@ func TestAnAnswerWithoutAValidDispositionGetsNoReport(t *testing.T) {
|
||||
t.Errorf("line %v, want no disposition", line)
|
||||
}
|
||||
|
||||
servewaf.wantNoReport(t)
|
||||
standIn.wantNoReport(t)
|
||||
}
|
||||
|
||||
func TestAnAnswerWithoutAContentTypeGoesToTheVisitorWithNone(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
servewaf := startServeWAF(t, func(w http.ResponseWriter, _ *http.Request) {
|
||||
standIn := startServeWAF(t, func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header()["Content-Type"] = nil
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
_, _ = io.WriteString(w, "<html>broken")
|
||||
})
|
||||
addr, _ := startRProxy(t, servewaf.URL, nowhere, nil)
|
||||
addr, _ := startRProxy(t, standIn.URL, nowhere, nil)
|
||||
|
||||
got := get(t, addr, "/")
|
||||
if contentType, sent := got.header["Content-Type"]; sent {
|
||||
@@ -1015,11 +1015,11 @@ func TestAnAnswerOf1MiBGoesToTheVisitor(t *testing.T) {
|
||||
|
||||
const size = 1 << 20
|
||||
|
||||
servewaf := startServeWAF(t, func(w http.ResponseWriter, _ *http.Request) {
|
||||
standIn := startServeWAF(t, func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
_, _ = w.Write(make([]byte, size))
|
||||
})
|
||||
addr, _ := startRProxy(t, servewaf.URL, nowhere, nil)
|
||||
addr, _ := startRProxy(t, standIn.URL, nowhere, nil)
|
||||
|
||||
got := get(t, addr, "/")
|
||||
if got.status != http.StatusInternalServerError || len(got.body) != size {
|
||||
@@ -1135,15 +1135,15 @@ func TestAnAnswerThatCannotBePassedOnIsAnswered502(t *testing.T) {
|
||||
func TestAnAnswerThatCannotBePassedOnGetsNoReport(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
servewaf := startServeWAF(t, overOneMiB(dispositionDeny))
|
||||
addr, out := startRProxy(t, servewaf.URL, nowhere, nil)
|
||||
standIn := startServeWAF(t, overOneMiB(dispositionDeny))
|
||||
addr, out := startRProxy(t, standIn.URL, nowhere, nil)
|
||||
|
||||
if got := get(t, addr, "/"); got.status != http.StatusBadGateway {
|
||||
t.Errorf("answered %+v, want 502", got)
|
||||
}
|
||||
|
||||
out.requestLine(t)
|
||||
servewaf.wantNoReport(t)
|
||||
standIn.wantNoReport(t)
|
||||
}
|
||||
|
||||
func TestWithoutAnAnswerTheDefaultDispositionDecides(t *testing.T) {
|
||||
@@ -1199,20 +1199,20 @@ func TestAVisitorThatGoesAwayWhileServeWAFIsAskedGetsNoDefault(t *testing.T) {
|
||||
t.Run("with the default "+disposition, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
servewaf := startServeWAF(t, func(_ http.ResponseWriter, r *http.Request) {
|
||||
standIn := startServeWAF(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, servewaf.URL, app.URL, map[string]string{
|
||||
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")
|
||||
servewaf.question(t)
|
||||
standIn.question(t)
|
||||
|
||||
_ = conn.Close()
|
||||
|
||||
@@ -1226,7 +1226,7 @@ func TestAVisitorThatGoesAwayWhileServeWAFIsAskedGetsNoDefault(t *testing.T) {
|
||||
t.Error("rproxy warned that servewaf gave no answer")
|
||||
}
|
||||
|
||||
servewaf.wantNoReport(t)
|
||||
standIn.wantNoReport(t)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1244,17 +1244,17 @@ func TestRProxyWarnsWhenTheDefaultDecides(t *testing.T) {
|
||||
func TestSendsNoReportWithoutAnAnswer(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
servewaf := startServeWAF(t, func(_ http.ResponseWriter, r *http.Request) {
|
||||
standIn := startServeWAF(t, func(_ http.ResponseWriter, r *http.Request) {
|
||||
<-r.Context().Done()
|
||||
})
|
||||
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{
|
||||
timeoutSetting: "200",
|
||||
})
|
||||
|
||||
wantGreeting(t, get(t, addr, "/"))
|
||||
out.requestLine(t)
|
||||
servewaf.wantNoReport(t)
|
||||
standIn.wantNoReport(t)
|
||||
}
|
||||
|
||||
func TestAPathUnderOwnPrefixNeverReachesTheApp(t *testing.T) {
|
||||
@@ -1274,25 +1274,25 @@ func TestAPathUnderOwnPrefixNeverReachesTheApp(t *testing.T) {
|
||||
func TestHealthCheckIsAnsweredWhileServeWAFIsDown(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
servewaf := startServeWAF(t, allow)
|
||||
standIn := startServeWAF(t, allow)
|
||||
app := startApp(t, greet)
|
||||
addr, out := startRProxy(t, nowhere, app.URL, nil)
|
||||
|
||||
got := get(t, addr, proxy.HealthPath)
|
||||
got := get(t, addr, servewaf.HealthPath)
|
||||
if got.status != http.StatusOK || got.body != "ok\n" {
|
||||
t.Errorf("answered %+v, want ok", got)
|
||||
}
|
||||
|
||||
line := out.requestLine(t)
|
||||
if line["path"] != proxy.HealthPath || line["disposition"] != nil {
|
||||
if line["path"] != servewaf.HealthPath || line["disposition"] != nil {
|
||||
t.Errorf("line %v, want one with no disposition", line)
|
||||
}
|
||||
|
||||
// With servewaf up too, it is not asked.
|
||||
addr, _ = startRProxy(t, servewaf.URL, app.URL, nil)
|
||||
get(t, addr, proxy.HealthPath)
|
||||
addr, _ = startRProxy(t, standIn.URL, app.URL, nil)
|
||||
get(t, addr, servewaf.HealthPath)
|
||||
|
||||
if len(servewaf.questions) != 0 {
|
||||
if len(standIn.questions) != 0 {
|
||||
t.Error("servewaf was asked about the health check")
|
||||
}
|
||||
}
|
||||
@@ -1396,15 +1396,15 @@ func TestAReportAnswered101IsDroppedAtOnce(t *testing.T) {
|
||||
func TestAReportDueAfterWaitForReportsIsDropped(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
servewaf := startServeWAF(t, allow)
|
||||
standIn := startServeWAF(t, allow)
|
||||
app := startApp(t, greet)
|
||||
addr, out, server := startServer(t, servewaf.URL, app.URL, nil)
|
||||
addr, out, server := startServer(t, standIn.URL, app.URL, nil)
|
||||
|
||||
server.WaitForReports()
|
||||
|
||||
wantGreeting(t, get(t, addr, "/"))
|
||||
out.requestLine(t)
|
||||
servewaf.wantNoReport(t)
|
||||
standIn.wantNoReport(t)
|
||||
}
|
||||
|
||||
func TestReportGivesWhatHappened(t *testing.T) {
|
||||
@@ -1412,14 +1412,14 @@ func TestReportGivesWhatHappened(t *testing.T) {
|
||||
|
||||
const body = "the visitor's body"
|
||||
|
||||
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)
|
||||
|
||||
wantGreeting(t, visit(t, newRequest(t, http.MethodPost, addr, "/",
|
||||
strings.NewReader(body))))
|
||||
|
||||
report := servewaf.report(t)
|
||||
report := standIn.report(t)
|
||||
|
||||
if report.RequestID == "" || report.Status != http.StatusOK ||
|
||||
report.RequestBytes != int64(len(body)) ||
|
||||
@@ -1442,7 +1442,7 @@ func TestWaitForReportsWaitsForAReportBeingSent(t *testing.T) {
|
||||
release := make(chan struct{})
|
||||
backend := httptest.NewServer(http.HandlerFunc(
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get(proxy.ClientHeader) != "" {
|
||||
if r.Header.Get(servewaf.ClientHeader) != "" {
|
||||
allow(w, r)
|
||||
|
||||
return
|
||||
@@ -1497,9 +1497,9 @@ func TestWaitForReportsWaitsForAReportBeingSent(t *testing.T) {
|
||||
func TestReportOfAWebSocketCountsWhatItCarried(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
servewaf := startServeWAF(t, allow)
|
||||
standIn := startServeWAF(t, allow)
|
||||
app := startApp(t, echoAfterUpgrade)
|
||||
addr, out := startRProxy(t, servewaf.URL, app.URL, map[string]string{
|
||||
addr, out := startRProxy(t, standIn.URL, app.URL, map[string]string{
|
||||
maxRequestTime: "2000",
|
||||
maxResponseTime: "2000",
|
||||
})
|
||||
@@ -1535,7 +1535,7 @@ func TestReportOfAWebSocketCountsWhatItCarried(t *testing.T) {
|
||||
|
||||
_ = conn.Close()
|
||||
|
||||
report := servewaf.report(t)
|
||||
report := standIn.report(t)
|
||||
if report.Status != http.StatusSwitchingProtocols ||
|
||||
report.RequestBytes != int64(len(message)) ||
|
||||
report.ResponseBytes != int64(len(message)) {
|
||||
@@ -1552,7 +1552,7 @@ func TestAWebSocketPassesOnThatTheVisitorStoppedSending(t *testing.T) {
|
||||
|
||||
const goodbye = "sent after the visitor stopped sending\n"
|
||||
|
||||
servewaf := startServeWAF(t, allow)
|
||||
standIn := startServeWAF(t, allow)
|
||||
app := startApp(t, func(w http.ResponseWriter, _ *http.Request) {
|
||||
conn, buffered, err := http.NewResponseController(w).Hijack()
|
||||
if err != nil {
|
||||
@@ -1572,7 +1572,7 @@ func TestAWebSocketPassesOnThatTheVisitorStoppedSending(t *testing.T) {
|
||||
_, _ = buffered.WriteString(goodbye)
|
||||
_ = buffered.Flush()
|
||||
})
|
||||
addr, _ := startRProxy(t, servewaf.URL, app.URL, nil)
|
||||
addr, _ := startRProxy(t, standIn.URL, app.URL, nil)
|
||||
|
||||
conn := dial(t, addr)
|
||||
send(t, conn, "GET /socket HTTP/1.1\r\nHost: app\r\n"+
|
||||
@@ -1610,7 +1610,7 @@ func TestAWebSocketPassesOnThatTheVisitorStoppedSending(t *testing.T) {
|
||||
//nolint:paralleltest // see above
|
||||
func TestASwitchNotPassedOnClosesTheAppsConnection(t *testing.T) {
|
||||
closed := make(chan error, 1)
|
||||
servewaf := startServeWAF(t, allow)
|
||||
standIn := startServeWAF(t, allow)
|
||||
app := startApp(t, func(w http.ResponseWriter, _ *http.Request) {
|
||||
conn, buffered, err := http.NewResponseController(w).Hijack()
|
||||
if err != nil {
|
||||
@@ -1633,7 +1633,7 @@ func TestASwitchNotPassedOnClosesTheAppsConnection(t *testing.T) {
|
||||
_, err = buffered.ReadByte()
|
||||
closed <- err
|
||||
})
|
||||
addr, _ := startRProxy(t, servewaf.URL, app.URL, nil)
|
||||
addr, _ := startRProxy(t, standIn.URL, app.URL, nil)
|
||||
|
||||
conn := dial(t, addr)
|
||||
send(t, conn, "GET /socket HTTP/1.1\r\nHost: app\r\n"+
|
||||
@@ -1681,9 +1681,9 @@ func TestEachRequestGetsAFreshID(t *testing.T) {
|
||||
|
||||
const fromTraefik = "an-id-from-traefik"
|
||||
|
||||
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",
|
||||
})
|
||||
|
||||
@@ -1694,7 +1694,7 @@ func TestEachRequestGetsAFreshID(t *testing.T) {
|
||||
req.Header.Set(requestIDHeader, fromTraefik)
|
||||
wantGreeting(t, visit(t, req))
|
||||
|
||||
ids = append(ids, servewaf.question(t).header.Get(requestIDHeader))
|
||||
ids = append(ids, standIn.question(t).header.Get(requestIDHeader))
|
||||
}
|
||||
|
||||
if slices.Contains(ids, fromTraefik) || ids[0] == "" || ids[0] == ids[1] {
|
||||
@@ -1711,16 +1711,16 @@ func TestLogLineGivesTheRequestAsSent(t *testing.T) {
|
||||
body = "the visitor's body"
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
req := newRequest(t, http.MethodPost, addr, path+"?"+query, strings.NewReader(body))
|
||||
req.Host = site
|
||||
wantGreeting(t, visit(t, req))
|
||||
|
||||
line := out.requestLine(t)
|
||||
asked := servewaf.question(t)
|
||||
asked := standIn.question(t)
|
||||
|
||||
for name, want := range map[string]any{
|
||||
"type": "request",
|
||||
|
||||
+11
-11
@@ -11,7 +11,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"sneak.berlin/go/smallwebwaf/internal/proxy"
|
||||
"sneak.berlin/go/smallwebwaf/internal/servewaf"
|
||||
)
|
||||
|
||||
// answerBodyMaxBytes is the most of the body of servewaf's answer that is read.
|
||||
@@ -38,10 +38,10 @@ type servewafAnswer struct {
|
||||
// notes nothing, and no report is due for it: servewaf holds no decision to report
|
||||
// on.
|
||||
func (rq *request) noteAnswer(answer *servewafAnswer) {
|
||||
disposition := answer.header.Get(proxy.DispositionHeader)
|
||||
disposition := answer.header.Get(servewaf.DispositionHeader)
|
||||
|
||||
switch disposition {
|
||||
case proxy.DispositionAllow, proxy.DispositionDeny, proxy.DispositionClose:
|
||||
case servewaf.DispositionAllow, servewaf.DispositionDeny, servewaf.DispositionClose:
|
||||
rq.disposition = disposition
|
||||
rq.answered = true
|
||||
rq.asn = answer.header.Get(asnHeader)
|
||||
@@ -74,7 +74,7 @@ func (rq *request) handleNoUsableAnswer(ctx context.Context, err error) {
|
||||
rq.disposition = rq.h.config.DefaultDisposition
|
||||
rq.byDefault = true
|
||||
|
||||
if rq.disposition == proxy.DispositionAllow {
|
||||
if rq.disposition == servewaf.DispositionAllow {
|
||||
rq.passToApp(ctx)
|
||||
} else {
|
||||
rq.answer(http.StatusServiceUnavailable)
|
||||
@@ -169,13 +169,13 @@ func (rq *request) newQuestion(ctx context.Context) (*http.Request, error) {
|
||||
question.TransferEncoding = in.TransferEncoding
|
||||
|
||||
question.Header = in.Header.Clone()
|
||||
question.Header.Set(proxy.ClientHeader, rq.client.String())
|
||||
question.Header.Set(proxy.PeerHeader, rq.peer.String())
|
||||
question.Header.Del(proxy.ContentLengthHeader)
|
||||
question.Header.Set(servewaf.ClientHeader, rq.client.String())
|
||||
question.Header.Set(servewaf.PeerHeader, rq.peer.String())
|
||||
question.Header.Del(servewaf.ContentLengthHeader)
|
||||
|
||||
announced := in.Header.Get("Content-Length")
|
||||
if announced != "" {
|
||||
question.Header.Set(proxy.ContentLengthHeader, announced)
|
||||
question.Header.Set(servewaf.ContentLengthHeader, announced)
|
||||
}
|
||||
|
||||
question.Header.Set(requestIDHeader, rq.id)
|
||||
@@ -196,7 +196,7 @@ func (rq *request) answerWith(answer *servewafAnswer) {
|
||||
|
||||
header := rq.out.Header()
|
||||
maps.Copy(header, answer.header)
|
||||
header.Del(proxy.DispositionHeader)
|
||||
header.Del(servewaf.DispositionHeader)
|
||||
|
||||
// Go's server adds a Content-Type it guesses from the body to a response whose
|
||||
// headers have no Content-Type key. The key with no value sends none.
|
||||
@@ -210,7 +210,7 @@ func (rq *request) answerWith(answer *servewafAnswer) {
|
||||
// sendReport sends servewaf report on a goroutine of its own, so that the
|
||||
// visitor does not wait for it. The report goes on after ctx, the request's own
|
||||
// context, has ended.
|
||||
func (h *handler) sendReport(ctx context.Context, report *proxy.Report) {
|
||||
func (h *handler) sendReport(ctx context.Context, report *servewaf.Report) {
|
||||
h.reportsMu.Lock()
|
||||
defer h.reportsMu.Unlock()
|
||||
|
||||
@@ -228,7 +228,7 @@ func (h *handler) sendReport(ctx context.Context, report *proxy.Report) {
|
||||
|
||||
// postReport posts report to servewaf, and waits for its answer for up to
|
||||
// SWRP_TIMEOUT_MS.
|
||||
func (h *handler) postReport(ctx context.Context, report *proxy.Report) error {
|
||||
func (h *handler) postReport(ctx context.Context, report *servewaf.Report) error {
|
||||
body, err := json.Marshal(report)
|
||||
if err != nil {
|
||||
return fmt.Errorf("encode the report: %w", err)
|
||||
|
||||
Reference in New Issue
Block a user