The header size and the idle time as settings (closes #70)
check / check (push) Successful in 4m57s
check / check (push) Successful in 4m57s
SWWAF_CLIENT_REQUEST_HEADER_MAX_BYTES (default 32K) and SWWAF_CLIENT_IDLE_TIMEOUT (default 120s) replace the two values the proxy fixed, and are read like the other size and duration settings. Go's server reads 4K past the header limit it is given before it refuses, so it is still given the setting less 4K, and a header size of 4K or less, or off, stops the start. The idle time can be off. README.md lists both settings and no longer calls them fixed. Model: opus-5-5
This commit is contained in:
@@ -297,7 +297,7 @@ func echoAfterUpgrade(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerHasTheFixedLimits(t *testing.T) {
|
||||
func TestServerHasTheDefaultLimits(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cfg, err := config.FromEnvironment(func(string) (string, bool) { return "", false })
|
||||
@@ -319,37 +319,48 @@ func TestServerHasTheFixedLimits(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRefusesHeadersOver32KiB(t *testing.T) {
|
||||
func TestRefusesHeadersOverTheLimit(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var calls atomic.Int32
|
||||
|
||||
app := startApp(t, func(http.ResponseWriter, *http.Request) {
|
||||
calls.Add(1)
|
||||
})
|
||||
addr, _ := startProxy(t, app.URL, nil)
|
||||
|
||||
// size counts every byte of the request: the request line, the
|
||||
// headers and the blank line that ends them.
|
||||
const (
|
||||
start = "GET / HTTP/1.1\r\nHost: app\r\nX-Large: "
|
||||
end = "\r\n\r\n"
|
||||
)
|
||||
|
||||
for _, tc := range []struct {
|
||||
size int
|
||||
want int
|
||||
name string
|
||||
env map[string]string
|
||||
limit int
|
||||
}{
|
||||
{size: 32 << 10, want: http.StatusOK},
|
||||
{size: 32<<10 + 1, want: http.StatusRequestHeaderFieldsTooLarge},
|
||||
{"by default", nil, 32 << 10},
|
||||
{"as set", map[string]string{clientHeaderMaxBytes: "8K"}, 8 << 10},
|
||||
} {
|
||||
conn := dial(t, addr)
|
||||
send(t, conn, start+strings.Repeat("a", tc.size-len(start)-len(end))+end)
|
||||
wantStatus(t, readResponse(t, conn), tc.want)
|
||||
}
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if calls.Load() != 1 {
|
||||
t.Errorf("the app was called %d times, want once", calls.Load())
|
||||
var calls atomic.Int32
|
||||
|
||||
app := startApp(t, func(http.ResponseWriter, *http.Request) {
|
||||
calls.Add(1)
|
||||
})
|
||||
addr, _ := startProxy(t, app.URL, tc.env)
|
||||
|
||||
// size counts every byte of the request: the request line,
|
||||
// the headers and the blank line that ends them.
|
||||
const (
|
||||
start = "GET / HTTP/1.1\r\nHost: app\r\nX-Large: "
|
||||
end = "\r\n\r\n"
|
||||
)
|
||||
|
||||
for _, sent := range []struct{ size, want int }{
|
||||
{tc.limit, http.StatusOK},
|
||||
{tc.limit + 1, http.StatusRequestHeaderFieldsTooLarge},
|
||||
} {
|
||||
conn := dial(t, addr)
|
||||
send(t, conn,
|
||||
start+strings.Repeat("a", sent.size-len(start)-len(end))+end)
|
||||
wantStatus(t, readResponse(t, conn), sent.want)
|
||||
}
|
||||
|
||||
if calls.Load() != 1 {
|
||||
t.Errorf("the app was called %d times, want once", calls.Load())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user