test(uploads): pin the idle bound an unset App resolves to (#56)
Round-2 gatekeeper finding: production never sets UploadIdleTimeout, so it
always runs the zero-means-default branch, and nothing asserted what that
branch resolved to (`idle = time.Hour` kept the suite green).
Extract the resolution into App.uploadIdleTimeout(), expose it via
export_test.go, and assert (&web.App{}) resolves to exactly 60s, a
negative value too, and a set value is honoured. Verified red against the
time.Hour mutant before implementing.
Rename the socket test to what it observes:
...AnUnsetIdleTimeoutDoesNotCutABodyWithSubSecondGaps.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+10
-4
@@ -142,6 +142,15 @@ func (a *App) handleUploadPost(w http.ResponseWriter, r *http.Request) {
|
||||
// hostile one; a legitimate upload, however slow, keeps delivering bytes.
|
||||
const defaultUploadIdleTimeout = 60 * time.Second
|
||||
|
||||
// uploadIdleTimeout is the idle bound this App applies: UploadIdleTimeout when set, else
|
||||
// defaultUploadIdleTimeout. cmd/tapir leaves it unset, so production runs the default.
|
||||
func (a *App) uploadIdleTimeout() time.Duration {
|
||||
if a.UploadIdleTimeout <= 0 {
|
||||
return defaultUploadIdleTimeout
|
||||
}
|
||||
return a.UploadIdleTimeout
|
||||
}
|
||||
|
||||
// idleBoundedBody bounds the SILENCE in an upload body, not its total duration (#56): every
|
||||
// read first pushes the connection's read deadline idle into the future, so a body that
|
||||
// keeps moving is never cut, and one that stops fails its read with a timeout. That read
|
||||
@@ -152,10 +161,7 @@ const defaultUploadIdleTimeout = 60 * time.Second
|
||||
// the body is returned unbounded and that is logged: a control that silently does not
|
||||
// apply is worse than one that says so.
|
||||
func (a *App) idleBoundedBody(w http.ResponseWriter, body io.ReadCloser) io.ReadCloser {
|
||||
idle := a.UploadIdleTimeout
|
||||
if idle <= 0 {
|
||||
idle = defaultUploadIdleTimeout
|
||||
}
|
||||
idle := a.uploadIdleTimeout()
|
||||
rc := http.NewResponseController(w)
|
||||
if err := rc.SetReadDeadline(time.Now().Add(idle)); err != nil {
|
||||
a.logger().Warn("upload idle bound unavailable", "err", err)
|
||||
|
||||
Reference in New Issue
Block a user