script/fmt now runs golines -m 77 after gofmt, repeating golines until it changes nothing, since one pass can leave a line the next splits. script/fmt-check fails when either would change a file. script/bootstrap installs golines v0.13.0 with go install, pinned to its commit, and checks the installed version with go version -m. The tree is reformatted. The longer lines this makes are fixed by hand: nolint directives moved onto their own line above the statement, one string split, and 20 functions over funlen's 80 lines shortened or split, RunWAF and limitPercentages among them. Model: opus-5-5
This commit is contained in:
1 parent
63e58e326b
commit
7f8a59de04
118 files changed
+9447
-2670
No files matched your search
@@ -27,7 +27,11 @@ func TestHistoryKeepsEveryRequest(t *testing.T) {
|
||||
// refused.
|
||||
{Status: 404},
|
||||
} {
|
||||
limiter.AddToHistory(client, start.Add(time.Duration(i)*time.Minute), r)
|
||||
limiter.AddToHistory(
|
||||
client,
|
||||
start.Add(time.Duration(i)*time.Minute),
|
||||
r,
|
||||
)
|
||||
}
|
||||
|
||||
want := ratelimit.History{
|
||||
@@ -63,7 +67,13 @@ func TestLookupReachesTheHistoryOfAClientInTheTable(t *testing.T) {
|
||||
|
||||
// A later answer replaces it, and one for a client the table does not
|
||||
// hold adds no client.
|
||||
limiter.AddLookup(client, start.Add(time.Hour), "AS64497", "Other Net", "FR")
|
||||
limiter.AddLookup(
|
||||
client,
|
||||
start.Add(time.Hour),
|
||||
"AS64497",
|
||||
"Other Net",
|
||||
"FR",
|
||||
)
|
||||
limiter.AddLookup(other, start, "AS64496", "Example Net", "DE")
|
||||
|
||||
want := ratelimit.History{
|
||||
@@ -96,7 +106,11 @@ func TestResetKeepsTheHistory(t *testing.T) {
|
||||
|
||||
for range limit {
|
||||
wantCount(t, limiter, client, start, "")
|
||||
limiter.AddToHistory(client, start, ratelimit.Request{Forwarded: true})
|
||||
limiter.AddToHistory(
|
||||
client,
|
||||
start,
|
||||
ratelimit.Request{Forwarded: true},
|
||||
)
|
||||
}
|
||||
|
||||
limiter.Reset(client)
|
||||
|
||||
@@ -241,7 +241,8 @@ func (l *Limiter) OverARateLimit(client netip.Prefix, now time.Time) bool {
|
||||
buckets := c.buckets()
|
||||
|
||||
for i, w := range l.windows {
|
||||
if w.limit > 0 && buckets[i].Add(now, w.length, 0)+1 > float64(w.limit) {
|
||||
if w.limit > 0 &&
|
||||
buckets[i].Add(now, w.length, 0)+1 > float64(w.limit) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -271,7 +272,12 @@ func (l *Limiter) CountRefusal(
|
||||
defer l.mu.Unlock()
|
||||
|
||||
count := l.get(client).MinuteRefusals.Add(now, time.Minute, 1)
|
||||
hit := Hit{Kind: KindRefusals, Window: "minute", Limit: threshold, Count: count}
|
||||
hit := Hit{
|
||||
Kind: KindRefusals,
|
||||
Window: "minute",
|
||||
Limit: threshold,
|
||||
Count: count,
|
||||
}
|
||||
|
||||
return hit, count > float64(threshold)
|
||||
}
|
||||
@@ -292,7 +298,11 @@ func (l *Limiter) Reset(client netip.Prefix) {
|
||||
|
||||
// AddToHistory adds r, a request from client at now, to the client's
|
||||
// history.
|
||||
func (l *Limiter) AddToHistory(client netip.Prefix, now time.Time, r Request) {
|
||||
func (l *Limiter) AddToHistory(
|
||||
client netip.Prefix,
|
||||
now time.Time,
|
||||
r Request,
|
||||
) {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
|
||||
@@ -470,7 +480,13 @@ func (l *Limiter) count(
|
||||
for i, w := range l.windows {
|
||||
requestCounts[i] = requestBuckets[i].Add(now, w.length, requests)
|
||||
byteCounts[i] = byteBuckets[i].Add(now, w.length, bytes)
|
||||
limit, byteLimit := percentOf(w.limit, percent), percentOf(w.byteLimit, percent)
|
||||
limit, byteLimit := percentOf(
|
||||
w.limit,
|
||||
percent,
|
||||
), percentOf(
|
||||
w.byteLimit,
|
||||
percent,
|
||||
)
|
||||
|
||||
switch {
|
||||
case hit.Window != "":
|
||||
|
||||
@@ -26,13 +26,17 @@ const (
|
||||
hour = "hour"
|
||||
)
|
||||
|
||||
func TestOverARateLimitSaysWhatTheNextRequestWouldDoAndCountsNothing(t *testing.T) {
|
||||
func TestOverARateLimitSaysWhatTheNextRequestWouldDoAndCountsNothing(
|
||||
t *testing.T,
|
||||
) {
|
||||
t.Parallel()
|
||||
|
||||
client := netip.MustParsePrefix("203.0.113.9/32")
|
||||
now := midnight()
|
||||
limiter := ratelimit.New(ratelimit.Limits{PerMinute: limit, PerDay: limit + 1},
|
||||
tableSize)
|
||||
limiter := ratelimit.New(
|
||||
ratelimit.Limits{PerMinute: limit, PerDay: limit + 1},
|
||||
tableSize,
|
||||
)
|
||||
|
||||
if limiter.OverARateLimit(client, now) {
|
||||
t.Error("a client never seen is over a rate limit")
|
||||
@@ -44,7 +48,9 @@ func TestOverARateLimitSaysWhatTheNextRequestWouldDoAndCountsNothing(t *testing.
|
||||
|
||||
for range limit {
|
||||
if limiter.OverARateLimit(client, now) {
|
||||
t.Error("a client with room for another request is over a rate limit")
|
||||
t.Error(
|
||||
"a client with room for another request is over a rate limit",
|
||||
)
|
||||
}
|
||||
|
||||
wantCount(t, limiter, client, now, "")
|
||||
@@ -56,7 +62,11 @@ func TestOverARateLimitSaysWhatTheNextRequestWouldDoAndCountsNothing(t *testing.
|
||||
|
||||
held, _ := limiter.Client(client)
|
||||
if held.Minute.Current != limit {
|
||||
t.Errorf("the client's minute holds %d requests, want %d", held.Minute.Current, limit)
|
||||
t.Errorf(
|
||||
"the client's minute holds %d requests, want %d",
|
||||
held.Minute.Current,
|
||||
limit,
|
||||
)
|
||||
}
|
||||
|
||||
wantCount(t, limiter, client, now, minute)
|
||||
@@ -99,7 +109,13 @@ func TestEachWindowRefusesAtItsLimitAndLetsTheClientBack(t *testing.T) {
|
||||
// A quarter into the next bucket, the window still covers three
|
||||
// quarters of the bucket before, with its four requests: 3 + 1
|
||||
// is over the limit.
|
||||
wantCount(t, limiter, client, start.Add(tc.length+quarter), tc.window)
|
||||
wantCount(
|
||||
t,
|
||||
limiter,
|
||||
client,
|
||||
start.Add(tc.length+quarter),
|
||||
tc.window,
|
||||
)
|
||||
|
||||
// Three quarters into it, a quarter: 1 + 2 is within.
|
||||
wantCount(t, limiter, client, start.Add(tc.length+3*quarter), "")
|
||||
@@ -110,7 +126,10 @@ func TestEachWindowRefusesAtItsLimitAndLetsTheClientBack(t *testing.T) {
|
||||
func TestHitGivesTheLimitAndTheRequestsCounted(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
limiter := ratelimit.New(ratelimit.Limits{PerMinute: limit, PerHour: limit}, tableSize)
|
||||
limiter := ratelimit.New(
|
||||
ratelimit.Limits{PerMinute: limit, PerHour: limit},
|
||||
tableSize,
|
||||
)
|
||||
client := netip.MustParsePrefix("203.0.113.9/32")
|
||||
start := midnight()
|
||||
|
||||
@@ -128,16 +147,22 @@ func TestHitGivesTheLimitAndTheRequestsCounted(t *testing.T) {
|
||||
Kind: ratelimit.KindRequests, Window: minute, Limit: limit, Count: limit + 1,
|
||||
}
|
||||
if !over || hit != want {
|
||||
t.Errorf("request over the limit gives %+v and %t, want %+v and true",
|
||||
hit, over, want)
|
||||
t.Errorf(
|
||||
"request over the limit gives %+v and %t, want %+v and true",
|
||||
hit,
|
||||
over,
|
||||
want,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientGetsItsPercentageOfEachLimitRoundedDown(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
limiter := ratelimit.New(ratelimit.Limits{PerMinute: 5, BytesPerDay: math.MaxInt64},
|
||||
tableSize)
|
||||
limiter := ratelimit.New(
|
||||
ratelimit.Limits{PerMinute: 5, BytesPerDay: math.MaxInt64},
|
||||
tableSize,
|
||||
)
|
||||
client := netip.MustParsePrefix("203.0.113.9/32")
|
||||
start := midnight()
|
||||
|
||||
@@ -151,9 +176,19 @@ func TestClientGetsItsPercentageOfEachLimitRoundedDown(t *testing.T) {
|
||||
|
||||
_, hit, over := limiter.Count(client, start, 50)
|
||||
|
||||
want := ratelimit.Hit{Kind: ratelimit.KindRequests, Window: minute, Limit: 2, Count: 3}
|
||||
want := ratelimit.Hit{
|
||||
Kind: ratelimit.KindRequests,
|
||||
Window: minute,
|
||||
Limit: 2,
|
||||
Count: 3,
|
||||
}
|
||||
if !over || hit != want {
|
||||
t.Errorf("the third request gives %+v and %t, want %+v and true", hit, over, want)
|
||||
t.Errorf(
|
||||
"the third request gives %+v and %t, want %+v and true",
|
||||
hit,
|
||||
over,
|
||||
want,
|
||||
)
|
||||
}
|
||||
|
||||
// Half of the largest byte limit is still far above a TiB: working it
|
||||
@@ -168,8 +203,10 @@ func TestZeroPercentIsAZeroAllowanceAndALimitOffStaysOff(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Only the hour has limits: the minute's and the day's are off.
|
||||
limiter := ratelimit.New(ratelimit.Limits{PerHour: limit, BytesPerHour: 1000},
|
||||
tableSize)
|
||||
limiter := ratelimit.New(
|
||||
ratelimit.Limits{PerHour: limit, BytesPerHour: 1000},
|
||||
tableSize,
|
||||
)
|
||||
client := netip.MustParsePrefix("203.0.113.9/32")
|
||||
start := midnight()
|
||||
|
||||
@@ -177,14 +214,24 @@ func TestZeroPercentIsAZeroAllowanceAndALimitOffStaysOff(t *testing.T) {
|
||||
// hour's limits, which are 0; the minute's, which are off, stay off.
|
||||
_, hit, _ := limiter.Count(client, start, 0)
|
||||
|
||||
want := ratelimit.Hit{Kind: ratelimit.KindRequests, Window: hour, Limit: 0, Count: 1}
|
||||
want := ratelimit.Hit{
|
||||
Kind: ratelimit.KindRequests,
|
||||
Window: hour,
|
||||
Limit: 0,
|
||||
Count: 1,
|
||||
}
|
||||
if hit != want {
|
||||
t.Errorf("the first request gives %+v, want %+v", hit, want)
|
||||
}
|
||||
|
||||
_, hit, _ = limiter.CountBytes(client, start, 1, 0)
|
||||
|
||||
want = ratelimit.Hit{Kind: ratelimit.KindBytes, Window: hour, Limit: 0, Count: 1}
|
||||
want = ratelimit.Hit{
|
||||
Kind: ratelimit.KindBytes,
|
||||
Window: hour,
|
||||
Limit: 0,
|
||||
Count: 1,
|
||||
}
|
||||
if hit != want {
|
||||
t.Errorf("the first byte gives %+v, want %+v", hit, want)
|
||||
}
|
||||
@@ -215,13 +262,23 @@ func TestEachByteLimitIsBrokenByTheBytesCounted(t *testing.T) {
|
||||
t.Fatal("600 bytes are over the limit of 1000")
|
||||
}
|
||||
|
||||
_, hit, over := limiter.CountBytes(client, midnight(), 600, whole)
|
||||
_, hit, over := limiter.CountBytes(
|
||||
client,
|
||||
midnight(),
|
||||
600,
|
||||
whole,
|
||||
)
|
||||
|
||||
want := ratelimit.Hit{
|
||||
Kind: ratelimit.KindBytes, Window: tc.window, Limit: byteLimit, Count: 1200,
|
||||
}
|
||||
if !over || hit != want {
|
||||
t.Errorf("1200 bytes give %+v and %t, want %+v and true", hit, over, want)
|
||||
t.Errorf(
|
||||
"1200 bytes give %+v and %t, want %+v and true",
|
||||
hit,
|
||||
over,
|
||||
want,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -230,8 +287,10 @@ func TestEachByteLimitIsBrokenByTheBytesCounted(t *testing.T) {
|
||||
func TestALimitIsBrokenOnlyByWhatIsAddedToIt(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
limiter := ratelimit.New(ratelimit.Limits{PerMinute: 2, BytesPerMinute: 1000},
|
||||
tableSize)
|
||||
limiter := ratelimit.New(
|
||||
ratelimit.Limits{PerMinute: 2, BytesPerMinute: 1000},
|
||||
tableSize,
|
||||
)
|
||||
client := netip.MustParsePrefix("203.0.113.9/32")
|
||||
other := netip.MustParsePrefix("203.0.113.10/32")
|
||||
start := midnight()
|
||||
@@ -301,7 +360,10 @@ func TestRefusalsOverTheThresholdInAMinuteBreakTheErrorBurst(t *testing.T) {
|
||||
|
||||
for range limit {
|
||||
if _, over := limiter.CountRefusal(client, start, limit); over {
|
||||
t.Fatalf("a refusal within the threshold of %d broke the error burst", limit)
|
||||
t.Fatalf(
|
||||
"a refusal within the threshold of %d broke the error burst",
|
||||
limit,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,13 +373,21 @@ func TestRefusalsOverTheThresholdInAMinuteBreakTheErrorBurst(t *testing.T) {
|
||||
Kind: ratelimit.KindRefusals, Window: minute, Limit: limit, Count: limit + 1,
|
||||
}
|
||||
if !over || hit != want {
|
||||
t.Errorf("one over the threshold broke it: %t, with %+v; want %+v", over, hit,
|
||||
want)
|
||||
t.Errorf(
|
||||
"one over the threshold broke it: %t, with %+v; want %+v",
|
||||
over,
|
||||
hit,
|
||||
want,
|
||||
)
|
||||
}
|
||||
|
||||
// Half a minute into the next, half of those four still count, 2, and
|
||||
// this one: 3, within the threshold.
|
||||
hit, over = limiter.CountRefusal(client, start.Add(time.Minute+time.Minute/2), limit)
|
||||
hit, over = limiter.CountRefusal(
|
||||
client,
|
||||
start.Add(time.Minute+time.Minute/2),
|
||||
limit,
|
||||
)
|
||||
if over || hit.Count != 3 {
|
||||
t.Errorf("half a minute on, %v refusals broke it: %t; want 3, false",
|
||||
hit.Count, over)
|
||||
@@ -326,7 +396,11 @@ func TestRefusalsOverTheThresholdInAMinuteBreakTheErrorBurst(t *testing.T) {
|
||||
// A ban sets them back to zero.
|
||||
limiter.Reset(client)
|
||||
|
||||
hit, _ = limiter.CountRefusal(client, start.Add(time.Minute+time.Minute/2), limit)
|
||||
hit, _ = limiter.CountRefusal(
|
||||
client,
|
||||
start.Add(time.Minute+time.Minute/2),
|
||||
limit,
|
||||
)
|
||||
if hit.Count != 1 {
|
||||
t.Errorf("after a reset, %v refusals, want 1", hit.Count)
|
||||
}
|
||||
@@ -347,7 +421,11 @@ func TestCountGivesTheRequestsInEachWindow(t *testing.T) {
|
||||
// hour still covers three quarters of the bucket before, with its three
|
||||
// requests, which count 2.25, and this one: 3.25. The day covers all
|
||||
// four.
|
||||
counts, _, _ := limiter.Count(client, start.Add(time.Hour+time.Hour/4), whole)
|
||||
counts, _, _ := limiter.Count(
|
||||
client,
|
||||
start.Add(time.Hour+time.Hour/4),
|
||||
whole,
|
||||
)
|
||||
|
||||
want := ratelimit.Counts{Minute: 1, Hour: 3.25, Day: 4}
|
||||
if counts != want {
|
||||
@@ -358,7 +436,10 @@ func TestCountGivesTheRequestsInEachWindow(t *testing.T) {
|
||||
func TestResetSetsTheCountsBackToZero(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
limiter := ratelimit.New(ratelimit.Limits{PerMinute: limit, PerDay: limit}, tableSize)
|
||||
limiter := ratelimit.New(
|
||||
ratelimit.Limits{PerMinute: limit, PerDay: limit},
|
||||
tableSize,
|
||||
)
|
||||
client := netip.MustParsePrefix("203.0.113.9/32")
|
||||
start := midnight()
|
||||
|
||||
@@ -399,8 +480,10 @@ func TestClientBackAfterAWholeBucketIsWithinTheLimitAtOnce(t *testing.T) {
|
||||
func TestRefusedRequestsCount(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
limiter := ratelimit.New(ratelimit.Limits{PerMinute: limit, PerHour: 2 * limit},
|
||||
tableSize)
|
||||
limiter := ratelimit.New(
|
||||
ratelimit.Limits{PerMinute: limit, PerHour: 2 * limit},
|
||||
tableSize,
|
||||
)
|
||||
refused := netip.MustParsePrefix("203.0.113.9/32")
|
||||
within := netip.MustParsePrefix("203.0.113.10/32")
|
||||
start := midnight()
|
||||
@@ -501,7 +584,11 @@ func TestKeepsAtMostMaxClientsDroppingTheLeastRecentlySeen(t *testing.T) {
|
||||
wantCount(t, limiter, clients[maxClients], now, "")
|
||||
|
||||
if limiter.Len() != maxClients {
|
||||
t.Errorf("the table holds %d clients, want %d", limiter.Len(), maxClients)
|
||||
t.Errorf(
|
||||
"the table holds %d clients, want %d",
|
||||
limiter.Len(),
|
||||
maxClients,
|
||||
)
|
||||
}
|
||||
|
||||
wantCount(t, limiter, clients[1], now, "")
|
||||
@@ -516,7 +603,10 @@ func midnight() time.Time {
|
||||
// wantCount counts a request from client at now, and checks the window
|
||||
// whose limit it goes over, "" for none.
|
||||
func wantCount(
|
||||
t *testing.T, limiter *ratelimit.Limiter, client netip.Prefix, now time.Time,
|
||||
t *testing.T,
|
||||
limiter *ratelimit.Limiter,
|
||||
client netip.Prefix,
|
||||
now time.Time,
|
||||
want string,
|
||||
) {
|
||||
t.Helper()
|
||||
@@ -531,8 +621,12 @@ func wantCount(
|
||||
// wantBytesCount counts bytes from client at now, and checks the kind of
|
||||
// the limit they break, "" for none.
|
||||
func wantBytesCount(
|
||||
t *testing.T, limiter *ratelimit.Limiter, client netip.Prefix, now time.Time,
|
||||
bytes int64, want string,
|
||||
t *testing.T,
|
||||
limiter *ratelimit.Limiter,
|
||||
client netip.Prefix,
|
||||
now time.Time,
|
||||
bytes int64,
|
||||
want string,
|
||||
) {
|
||||
t.Helper()
|
||||
|
||||
|
||||
@@ -12,7 +12,12 @@ import (
|
||||
func TestSnapshotListsTheClientsByAddress(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
want := []string{"192.0.2.1/32", "203.0.113.9/32", "203.0.113.10/32", "2001:db8::/64"}
|
||||
want := []string{
|
||||
"192.0.2.1/32",
|
||||
"203.0.113.9/32",
|
||||
"203.0.113.10/32",
|
||||
"2001:db8::/64",
|
||||
}
|
||||
|
||||
limiter := ratelimit.New(ratelimit.Limits{}, tableSize)
|
||||
for _, i := range []int{2, 3, 0, 1} {
|
||||
@@ -32,8 +37,12 @@ func TestSnapshotListsTheClientsByAddress(t *testing.T) {
|
||||
|
||||
counted := ratelimit.Buckets{Start: midnight(), Current: 1}
|
||||
if snapshot[0].Minute != counted || snapshot[0].Day != counted {
|
||||
t.Errorf("buckets %+v and %+v, want %+v", snapshot[0].Minute, snapshot[0].Day,
|
||||
counted)
|
||||
t.Errorf(
|
||||
"buckets %+v and %+v, want %+v",
|
||||
snapshot[0].Minute,
|
||||
snapshot[0].Day,
|
||||
counted,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,10 +95,15 @@ func TestLoadEmptiesBucketsWhoseTimeHasPassed(t *testing.T) {
|
||||
t.Errorf("loaded two minutes on as %+v", got)
|
||||
}
|
||||
|
||||
if got.MinuteBytes != (ratelimit.Buckets{}) || got.HourBytes.Current != 5 ||
|
||||
if got.MinuteBytes != (ratelimit.Buckets{}) ||
|
||||
got.HourBytes.Current != 5 ||
|
||||
got.DayBytes.Current != 5 {
|
||||
t.Errorf("loaded two minutes on with buckets of bytes %+v, %+v and %+v",
|
||||
got.MinuteBytes, got.HourBytes, got.DayBytes)
|
||||
t.Errorf(
|
||||
"loaded two minutes on with buckets of bytes %+v, %+v and %+v",
|
||||
got.MinuteBytes,
|
||||
got.HourBytes,
|
||||
got.DayBytes,
|
||||
)
|
||||
}
|
||||
|
||||
if got.MinuteRefusals != (ratelimit.Buckets{}) {
|
||||
@@ -101,8 +115,13 @@ func TestLoadEmptiesBucketsWhoseTimeHasPassed(t *testing.T) {
|
||||
got = loaded(start.Add(2*time.Minute - time.Nanosecond))
|
||||
if got.Minute.Current != 1 || got.MinuteBytes.Current != 5 ||
|
||||
got.MinuteRefusals.Current != 1 {
|
||||
t.Errorf("loaded just under two minutes on with minute buckets %+v, %+v "+
|
||||
"and %+v", got.Minute, got.MinuteBytes, got.MinuteRefusals)
|
||||
t.Errorf(
|
||||
"loaded just under two minutes on with minute buckets %+v, %+v "+
|
||||
"and %+v",
|
||||
got.Minute,
|
||||
got.MinuteBytes,
|
||||
got.MinuteRefusals,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user