Prefer parsed server body limit over raw sentBytes when ratcheting budget · Entire
Prefer parsed server body limit over raw sentBytes when ratcheting budget
ea5f20c→main·
Soph·2mo ago·2 files·+112 added/-14 removed
When a server rejects a push with an explicit "body exceeded size limit N" message, that N is authoritative. The earlier code ratcheted selfImposedBudget down to raw sentBytes on every non-self-aborted failure, ignoring the parsed limit. With reverse proxies that reject the request after only a few MiB even though the actual cap is much higher (e.g. 100 MiB), the budget would lock onto that early-cutoff floor and over-subdivide on every subsequent run.
Extract the budget-ratchet decision into nextSelfImposedBudget and prefer the parsed server limit when available, falling back to sentBytes only when no parseable number was provided (e.g. Cloudflare HTML 413 pages). Budget still only ratchets down — never up.
Sessions
566f7af7d862View transcript
Changes
2
internal/strategy/bootstrap
Mbootstrap.go+36/-14
Mbootstrap_test.go+76
441 unmodified lines
// rejection arrived comfortably under the limit (a server with
// stricter limits announcing the failure early), 2× is enough since
// sentBytes is closer to the real pack size.
// nextSelfImposedBudget refines the in-flight self-imposed upload
// ceiling after a server-rejected push (i.e. not one the client
// aborted itself). It prefers the explicit body limit when the server
// announced one — that's authoritative — and falls back to the
// empirical sent-bytes cutoff only when no parseable limit is
// available (e.g. Cloudflare's HTML 413). Reverse proxies sometimes
// reject after only a few MiB even though the actual cap is much
// higher; ratcheting to that early-cutoff would cause subsequent runs
// to over-subdivide for no reason.
//
// The budget only ratchets down: if the new candidate isn't smaller
// than the current ceiling, the current value stays.
func nextSelfImposedBudget(current, parsedLimit, sentBytes int64, abortedEarly bool) int64 {
if abortedEarly {
return current
}
candidate := int64(0)
switch {
case parsedLimit > 0:
candidate = parsedLimit
case sentBytes > 0:
candidate = sentBytes
}
if candidate <= 0 {
return current
}
if current == 0 || candidate < current {
return candidate
}
return current
}
func observedSubdivisionFactor(sentBytes, limit int64) int {
if sentBytes <= 0 || limit <= 0 {
return 2
}