Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
235ff0707f |
@@ -316,8 +316,7 @@ in `bin/state` unless `SWWAF_STATE_DIR` is set, and the default rule file of
|
|||||||
Each setting is an environment variable, or a file one names (see "Settings
|
Each setting is an environment variable, or a file one names (see "Settings
|
||||||
given as files" below), and each has a default, so none has to be set. A setting
|
given as files" below), and each has a default, so none has to be set. A setting
|
||||||
that is set but invalid stops the start with a message naming it, and the
|
that is set but invalid stops the start with a message naming it, and the
|
||||||
effective settings are logged at start, unless `SWWAF_LOG_LEVEL` is `warn` or
|
effective settings are logged at start.
|
||||||
`error`, which hold that line back.
|
|
||||||
|
|
||||||
- `SWWAF_LISTEN_ADDR` (default `:8080`): where `smallwebwaf` listens.
|
- `SWWAF_LISTEN_ADDR` (default `:8080`): where `smallwebwaf` listens.
|
||||||
- `SWWAF_UPSTREAM_URL` (default `http://127.0.0.1:8081`): the app, as `http` or
|
- `SWWAF_UPSTREAM_URL` (default `http://127.0.0.1:8081`): the app, as `http` or
|
||||||
|
|||||||
@@ -399,25 +399,6 @@ func TestAnswers502WhenTheAppCannotBeReached(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLogLevelHoldsBackNoRequestLine(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
// At error the warning that the request to the app failed is held back,
|
|
||||||
// and is written before the answer is.
|
|
||||||
addr, out := startProxy(t, "http://"+localhost+":1", map[string]string{
|
|
||||||
"SWWAF_LOG_LEVEL": "error",
|
|
||||||
})
|
|
||||||
|
|
||||||
wantStatus(t, get(t, addr, "/"), http.StatusBadGateway)
|
|
||||||
wantLine(t, out.requestLine(t), http.StatusBadGateway, requestlog.ActionUpstreamError)
|
|
||||||
|
|
||||||
for _, line := range out.lines(t) {
|
|
||||||
if line["type"] == "process" {
|
|
||||||
t.Errorf("process line %v, want none at error", line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLogsAnAnswerThatBrokeOff(t *testing.T) {
|
func TestLogsAnAnswerThatBrokeOff(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|||||||
@@ -249,16 +249,14 @@ func TestServesUntilToldToStop(t *testing.T) {
|
|||||||
out.line(t, "msg", "stopped")
|
out.line(t, "msg", "stopped")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLogLevelHoldsBackTheLessSevereProcessLines(t *testing.T) {
|
func TestLogLevelHoldsBackProcessLinesAndNoRequestLine(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// A list that cannot be fetched has a warning written once smallwebwaf
|
// At warn no starting line gives the address, so the test picks one.
|
||||||
// serves, after its starting line.
|
// The app cannot be reached, so that a request has a warning written:
|
||||||
lists := httptest.NewServer(http.HandlerFunc(
|
// no test can listen on port 1.
|
||||||
func(w http.ResponseWriter, _ *http.Request) {
|
addr := freeAddress(t)
|
||||||
w.WriteHeader(http.StatusServiceUnavailable)
|
url := "http://" + addr + "/"
|
||||||
}))
|
|
||||||
t.Cleanup(lists.Close)
|
|
||||||
|
|
||||||
ctx, stop := context.WithCancel(t.Context())
|
ctx, stop := context.WithCancel(t.Context())
|
||||||
out := &output{}
|
out := &output{}
|
||||||
@@ -266,15 +264,18 @@ func TestLogLevelHoldsBackTheLessSevereProcessLines(t *testing.T) {
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
exited <- run(ctx, map[string]string{
|
exited <- run(ctx, map[string]string{
|
||||||
listenAddr: localhost + ":0",
|
listenAddr: addr,
|
||||||
|
upstreamURL: "http://" + localhost + ":1",
|
||||||
stateDir: t.TempDir(),
|
stateDir: t.TempDir(),
|
||||||
rulesDir: t.TempDir(),
|
rulesDir: t.TempDir(),
|
||||||
"SWWAF_BLOCKLIST_URLS": lists.URL + "/tor.txt",
|
|
||||||
"SWWAF_LOG_LEVEL": "warn",
|
"SWWAF_LOG_LEVEL": "warn",
|
||||||
}, out)
|
}, out)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
out.line(t, "msg", "fetching a list failed")
|
waitUntilServing(t, url)
|
||||||
|
wantStatus(t, url, localhost, http.StatusBadGateway)
|
||||||
|
out.line(t, "action", "upstream_error")
|
||||||
|
out.line(t, "msg", "request to the app failed")
|
||||||
stop()
|
stop()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
@@ -286,7 +287,8 @@ func TestLogLevelHoldsBackTheLessSevereProcessLines(t *testing.T) {
|
|||||||
t.Fatal("still running after being told to stop")
|
t.Fatal("still running after being told to stop")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not one of the info lines from the start to the stop.
|
// Not one of the info lines from the start to the stop; a request line
|
||||||
|
// has no level.
|
||||||
for line := range strings.Lines(out.text()) {
|
for line := range strings.Lines(out.text()) {
|
||||||
var fields map[string]any
|
var fields map[string]any
|
||||||
|
|
||||||
@@ -1145,6 +1147,52 @@ func runUntilStopped(
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// freeAddress returns an address on localhost that nothing listens on as
|
||||||
|
// it returns, for a test that cannot learn smallwebwaf's own address from
|
||||||
|
// its starting line.
|
||||||
|
func freeAddress(t *testing.T) string {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
listener, err := (&net.ListenConfig{}).Listen(t.Context(), "tcp", localhost+":0")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("listen: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
addr := listener.Addr().String()
|
||||||
|
_ = listener.Close()
|
||||||
|
|
||||||
|
return addr
|
||||||
|
}
|
||||||
|
|
||||||
|
// waitUntilServing waits until smallwebwaf at url answers its health
|
||||||
|
// check, for a test that has no starting line to wait for.
|
||||||
|
func waitUntilServing(t *testing.T, url string) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
transport := &http.Transport{}
|
||||||
|
defer transport.CloseIdleConnections()
|
||||||
|
|
||||||
|
deadline := time.Now().Add(waitLimit)
|
||||||
|
for time.Now().Before(deadline) {
|
||||||
|
req, err := http.NewRequestWithContext(t.Context(), http.MethodGet,
|
||||||
|
url+"_smallwebwaf/healthz", http.NoBody)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("new request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := (&http.Client{Transport: transport}).Do(req)
|
||||||
|
if err == nil {
|
||||||
|
_ = res.Body.Close()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(pollInterval)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Fatalf("no answer at %s after %s", url, waitLimit)
|
||||||
|
}
|
||||||
|
|
||||||
// wantStartingLine checks that the line at start gives the version and
|
// wantStartingLine checks that the line at start gives the version and
|
||||||
// every setting's value.
|
// every setting's value.
|
||||||
func wantStartingLine(t *testing.T, line map[string]any, appURL, dir string) {
|
func wantStartingLine(t *testing.T, line map[string]any, appURL, dir string) {
|
||||||
|
|||||||
Reference in New Issue
Block a user