Compare commits

..
1 Commits
Author SHA1 Message Date
sneak 08b05907a5 sww tests: wait for every starting line as long as the start takes (closes #331)
check / check (push) Successful in 3m29s
Each test in internal/sww that waits for the starting line now waits until
the line is written or sww exits, so a slow Core Rule Set compile on a
loaded host no longer fails it. The two tests that run sww as a child
process get its exit status from a goroutine that waits on it, and no
longer kill it after 30 seconds; the waits after SIGTERM still end after
waitLimit. startRProxyProcess returns a stop function in place of the
process and its output.

Model: opus-5-5
2026-11-11 07:00:26 +00:00
5 changed files with 31 additions and 43 deletions

No files matched your search

+1 -2
View File
@@ -2326,8 +2326,7 @@ but for these headers:
claims and are replaced. `X-Forwarded-For` names the peer, `X-Forwarded-Host`
the host it asked for, and `X-Forwarded-Proto` plain `http`. Every other
header whose name starts with `X-Forwarded-` is removed, and so are
`Forwarded` and `X-Real-IP`. A name spelt with `_` for `-`, such as
`X_Forwarded_Ssl`, counts as the same name.
`Forwarded` and `X-Real-IP`.
- `X-Request-ID`, which carries the fresh id.
- `X-Client-ASN` and `X-Client-Country`, which carry what `waf` answered. A
header it did not give is left out. Any of the two the visitor sent is
+6 -5
View File
@@ -105,16 +105,17 @@ func setForwardedHeaders(in, out *http.Request, peer netip.Addr, trusted bool) {
return
}
// An app behind CGI or FastCGI reads X_Forwarded_Ssl as X-Forwarded-Ssl, so
// a name is matched with each _ read as - and in any letter case.
// ReverseProxy has removed Forwarded and the three set below. Go's server
// gives header names in canonical form, so the prefix matches the name in
// any letter case.
for name := range out.Header {
spelt := strings.ToLower(strings.ReplaceAll(name, "_", "-"))
if strings.HasPrefix(spelt, "x-forwarded-") ||
spelt == "forwarded" || spelt == "x-real-ip" {
if strings.HasPrefix(name, "X-Forwarded-") {
delete(out.Header, name)
}
}
out.Header.Del("X-Real-IP")
out.Header.Set("X-Forwarded-For", forwardedFor)
out.Header.Set("X-Forwarded-Host", in.Host)
out.Header.Set("X-Forwarded-Proto", "http")
-2
View File
@@ -561,7 +561,6 @@ func TestAPeerNotTrustedHasItsForwardedHeadersReplaced(t *testing.T) {
"X-Forwarded-Tls-Client-Cert-Info", "X-Real-Ip",
"X-Forwarded-Scheme", "X-Forwarded-Ssl", "X-Forwarded-Protocol",
"X-Forwarded-Path", "X-Forwarded-Client-Cert",
"X_Forwarded_Ssl", "X_Forwarded_Proto", "X_Real_IP",
}
standIn := startWAF(t, allow)
@@ -629,7 +628,6 @@ func TestATrustedProxysForwardedHeadersPassOn(t *testing.T) {
forwardedProtoHeader: "https",
"X-Real-Ip": "198.51.100.1",
"X-Forwarded-Ssl": "on",
"X_Forwarded_Ssl": "on",
}
req := newRequest(t, http.MethodGet, addr, "/", http.NoBody)
+13 -4
View File
@@ -507,9 +507,8 @@ func TestAStatusWAFDoesNotTakeIsReportedAs599(t *testing.T) {
}
// startRProxyProcess runs `sww rproxy` in a process of its own, with the
// settings in env, each as NAME=value. It returns where rproxy listens and a
// function that sends rproxy SIGTERM and fails the test unless it exits with
// status 0 within waitLimit.
// settings in env, each as NAME=value. It returns where rproxy listens, and
// what stops it as SIGTERM does, which checks that it stopped in order.
func startRProxyProcess(t *testing.T, env ...string) (string, func()) {
t.Helper()
@@ -527,7 +526,17 @@ func startRProxyProcess(t *testing.T, env ...string) (string, func()) {
"SWRP_LISTEN_ADDR="+localhost+":0")
cmd.Env = append(cmd.Env, env...)
exited := startProcess(t, cmd)
err = cmd.Start()
if err != nil {
t.Fatalf("start: %v", err)
}
exited := make(chan int, 1)
go func() {
_ = cmd.Wait()
exited <- cmd.ProcessState.ExitCode()
}()
addr, _ := out.lineBeforeExit(t, "starting", exited)["address"].(string)
+11 -30
View File
@@ -38,35 +38,6 @@ func TestMain(m *testing.M) {
os.Exit(sww.Main(testVersion))
}
// startProcess starts cmd and returns a channel that gets its exit status. As
// the test ends, cmd is killed and the test waits for it to exit.
func startProcess(t *testing.T, cmd *exec.Cmd) <-chan int {
t.Helper()
err := cmd.Start()
if err != nil {
t.Fatalf("start: %v", err)
}
exited := make(chan int, 1)
waitReturned := make(chan struct{})
go func() {
_ = cmd.Wait()
exited <- cmd.ProcessState.ExitCode()
close(waitReturned)
}()
t.Cleanup(func() {
_ = cmd.Process.Kill()
<-waitReturned
})
return exited
}
func TestMainRunsWAF(t *testing.T) {
t.Parallel()
@@ -96,7 +67,17 @@ func TestMainRunsWAF(t *testing.T) {
rulesDir+"="+t.TempDir(),
lookupSource+"=off")
exited := startProcess(t, cmd)
err = cmd.Start()
if err != nil {
t.Fatalf("start: %v", err)
}
exited := make(chan int, 1)
go func() {
_ = cmd.Wait()
exited <- cmd.ProcessState.ExitCode()
}()
starting := out.lineBeforeExit(t, "starting", exited)
addr, _ := starting["address"].(string)