Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a0788ba1ef |
@@ -2495,11 +2495,10 @@ client-chosen text in the path, in the query, and in each of
|
|||||||
including cases built from the characters the handlers escape, and
|
including cases built from the characters the handlers escape, and
|
||||||
against a 5xx that keeps its concrete path while all three header fields
|
against a 5xx that keeps its concrete path while all three header fields
|
||||||
are also at their budget and an `X-Forwarded-For` sent from a trusted
|
are also at their budget and an `X-Forwarded-For` sent from a trusted
|
||||||
proxy ends in an IPv6 client address at its longest followed by an 8 KB
|
proxy ends in an IPv6 client address at its longest. Every case runs
|
||||||
zone, where `clientIP` must name the address without the zone. Every
|
through both handlers `internal/logger` can select — the JSON one and
|
||||||
case runs through both handlers `internal/logger` can select — the JSON
|
the text one it installs on a tty — since the two do not escape alike
|
||||||
one and the text one it installs on a tty — since the two do not escape
|
and the ceiling is quoted unqualified.
|
||||||
alike and the ceiling is quoted unqualified.
|
|
||||||
|
|
||||||
Multiply that ceiling by the request rate to size log storage. Note
|
Multiply that ceiling by the request rate to size log storage. Note
|
||||||
that the rate is not bounded by the limits above on every route:
|
that the rate is not bounded by the limits above on every route:
|
||||||
|
|||||||
@@ -102,13 +102,6 @@ func TestWebhookDBManager_TotalsSurviveReopen(t *testing.T) {
|
|||||||
// seedExpiredEvents stores count events created at the given time,
|
// seedExpiredEvents stores count events created at the given time,
|
||||||
// each with a delivered delivery to one target and a failed delivery
|
// each with a delivered delivery to one target and a failed delivery
|
||||||
// to the other, and one attempt for each delivery.
|
// to the other, and one attempt for each delivery.
|
||||||
//
|
|
||||||
// It and seedBareEvents insert 50 rows per statement, not more. The
|
|
||||||
// SQLite driver looks up each parameter's value by scanning the
|
|
||||||
// statement's arguments from the first until it reaches that
|
|
||||||
// parameter's, so the time to bind a statement grows with the square of
|
|
||||||
// its parameter count: at 500 rows, several thousand parameters, the
|
|
||||||
// seeding took most of these tests' time under -race.
|
|
||||||
func seedExpiredEvents(
|
func seedExpiredEvents(
|
||||||
t *testing.T,
|
t *testing.T,
|
||||||
db *gorm.DB,
|
db *gorm.DB,
|
||||||
@@ -145,8 +138,8 @@ func seedExpiredEvents(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, db.CreateInBatches(events, 50).Error)
|
require.NoError(t, db.CreateInBatches(events, 500).Error)
|
||||||
require.NoError(t, db.CreateInBatches(deliveries, 50).Error)
|
require.NoError(t, db.CreateInBatches(deliveries, 500).Error)
|
||||||
|
|
||||||
results := make([]database.DeliveryResult, len(deliveries))
|
results := make([]database.DeliveryResult, len(deliveries))
|
||||||
for i := range deliveries {
|
for i := range deliveries {
|
||||||
@@ -155,7 +148,7 @@ func seedExpiredEvents(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, db.CreateInBatches(results, 50).Error)
|
require.NoError(t, db.CreateInBatches(results, 500).Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// seedBareEvents stores count events created at the given time, with
|
// seedBareEvents stores count events created at the given time, with
|
||||||
@@ -179,7 +172,7 @@ func seedBareEvents(
|
|||||||
events[i].CreatedAt = createdAt
|
events[i].CreatedAt = createdAt
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, db.CreateInBatches(events, 50).Error)
|
require.NoError(t, db.CreateInBatches(events, 500).Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestRetentionReaper_PrunesMoreThanOneBatch verifies that a prune
|
// TestRetentionReaper_PrunesMoreThanOneBatch verifies that a prune
|
||||||
|
|||||||
@@ -64,11 +64,10 @@ const (
|
|||||||
// lines into the returned buffer, so the access log can be asserted
|
// lines into the returned buffer, so the access log can be asserted
|
||||||
// on directly.
|
// on directly.
|
||||||
//
|
//
|
||||||
// It trusts 192.0.2.1, the peer address httptest.NewRequestWithContext
|
// It trusts 192.0.2.1, the peer httptest sends every request from, as
|
||||||
// gives a request, as a proxy, the way a deployment trusts its reverse
|
// a proxy, the way a deployment trusts its reverse proxy: a request
|
||||||
// proxy: a request built that way and carrying X-Forwarded-For is
|
// carrying X-Forwarded-For is logged with the client that header names
|
||||||
// logged with the client that header names as clientIP, and one
|
// as clientIP, and one without it with the peer.
|
||||||
// without it with the peer.
|
|
||||||
func capturingMiddleware(t *testing.T) (*middleware.Middleware, *bytes.Buffer) {
|
func capturingMiddleware(t *testing.T) (*middleware.Middleware, *bytes.Buffer) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
@@ -433,17 +432,14 @@ func lineSizeCases() map[string]sizeCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// From a trusted proxy, clientIP is read out of X-Forwarded-For,
|
// From a trusted proxy, clientIP is read out of X-Forwarded-For,
|
||||||
// which the client writes. What bounds the field is that only one
|
// which the client writes. Only the address the header ends in may
|
||||||
// address from the header is written, and it is written parsed, with
|
// reach the line, and an IPv6 address with all eight groups at four
|
||||||
// no zone. An IPv6 address with all eight groups at four digits is
|
// digits is that address at its longest. It goes on the 5xx line
|
||||||
// the longest such address; here it carries an 8 KB zone, which must
|
// with all three header fields at their budget.
|
||||||
// not reach the line. It goes on the 5xx line with all three header
|
|
||||||
// fields at their budget.
|
|
||||||
const longestIPv6 = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
|
const longestIPv6 = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
|
||||||
|
|
||||||
forwarded := oversizedHeaders(oversizedValue("h"))
|
forwarded := oversizedHeaders(oversizedValue("h"))
|
||||||
forwarded[headerXFF] = oversizedValue("h") + ", " +
|
forwarded[headerXFF] = oversizedValue("h") + ", " + longestIPv6
|
||||||
longestIPv6 + "%" + oversizedValue("h")
|
|
||||||
|
|
||||||
cases["oversized X-Forwarded-For from a trusted proxy "+
|
cases["oversized X-Forwarded-For from a trusted proxy "+
|
||||||
"with a 5xx concrete url"] = sizeCase{
|
"with a 5xx concrete url"] = sizeCase{
|
||||||
|
|||||||
+1
-5
@@ -27,11 +27,7 @@
|
|||||||
# Those figures predate tests hashing the admin password at 1 MB instead of
|
# Those figures predate tests hashing the admin password at 1 MB instead of
|
||||||
# 64 MB (https://git.eeqj.de/sneak/webhooker/pulls/404). After that change, in
|
# 64 MB (https://git.eeqj.de/sneak/webhooker/pulls/404). After that change, in
|
||||||
# a cache-defeated build at host load 44-109 (2026-10-02), internal/handlers
|
# a cache-defeated build at host load 44-109 (2026-10-02), internal/handlers
|
||||||
# took 8.5s and the slowest package was internal/database at 15.8s. Once its
|
# took 8.5s and the slowest package was internal/database at 15.8s.
|
||||||
# retention tests seeded 50 rows per insert instead of 500
|
|
||||||
# (https://git.eeqj.de/sneak/webhooker/issues/198), internal/database took
|
|
||||||
# 7.3s and the slowest package was internal/handlers at 8.1s to 10.0s, at host
|
|
||||||
# load 25-48 (2026-10-02).
|
|
||||||
#
|
#
|
||||||
# -p 4 -parallel 8 keep the run under 2 GB of memory: at most four test
|
# -p 4 -parallel 8 keep the run under 2 GB of memory: at most four test
|
||||||
# binaries build or run at once, each with at most eight parallel tests. Under
|
# binaries build or run at once, each with at most eight parallel tests. Under
|
||||||
|
|||||||
Reference in New Issue
Block a user