Per-client request rate limits over a minute, an hour and a day (closes #43)
check / check (push) Successful in 2m20s

Each client, one IPv4 address or one IPv6 /64, is counted in two buckets
per window, the earlier weighted by how much of it the window covers; at
most 20,000 clients are kept, least recently seen dropped first. A
request over SWWAF_RATE_LIMIT_PER_MINUTE, _HOUR or _DAY (1000, 10000,
50000, or off) gets 429 before reaching the app. Refused requests count,
413s included. A clock set back over a second behind a bucket's start
restarts that window. The log line gains limit_hit and the action
rate_limited.

Deviation from SPEC.md, per the issue: the 20,000 bound and /64 are fixed.
Judgement call: golang-lru/v2 holds the table; httprate does not count refused requests.
Deviation: go.mod and go.sum hand-written; no make target tidies them.

Model: opus-5-5
This commit is contained in:
2026-10-04 01:57:57 +00:00
committed by sneak
parent bedd324f3c
commit 669524cf8e
15 changed files with 581 additions and 32 deletions
+3 -1
View File
@@ -49,7 +49,9 @@ func TestWriteWritesOneJSONLineMarkedRequest(t *testing.T) {
}
}
unset := []string{"upstream_status", "aborted", "duration_upstream_total"}
unset := []string{
"upstream_status", "limit_hit", "aborted", "duration_upstream_total",
}
for _, name := range unset {
_, present := fields[name]
if present {