From 18b51253da3d001e4f776a837632442be99dda71 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Mon, 27 Apr 2026 01:16:41 -0700 Subject: [PATCH] treat client cancel as cancellation, not 503 If r.Context() is already canceled when the cache attempt returns no chunks, the cache failure is almost certainly a side-effect of the client disconnecting, not real backpressure. Surface the context error so GetObjectHandler logs at V(3) and skips writing a response, instead of synthesizing a 503 that nobody will read. Addresses Gemini review feedback on #9233. --- weed/s3api/s3api_object_handlers.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/weed/s3api/s3api_object_handlers.go b/weed/s3api/s3api_object_handlers.go index 012e982f17..de0fe5b311 100644 --- a/weed/s3api/s3api_object_handlers.go +++ b/weed/s3api/s3api_object_handlers.go @@ -1000,6 +1000,13 @@ func (s3a *S3ApiServer) streamFromVolumeServers(w http.ResponseWriter, r *http.R entry = cachedEntry glog.V(1).Infof("streamFromVolumeServers: successfully cached remote object, got %d chunks", len(chunks)) } else { + // If the client already went away (most common cause of a failed + // cache attempt here), surface the context error so the outer + // handler treats it as a cancellation instead of writing a 503 + // the client will never see. + if ctxErr := r.Context().Err(); ctxErr != nil { + return ctxErr + } // Cache attempt did not produce chunks in time. The cache may still // be filling in the background, so return 503 with Retry-After to // let S3 SDKs back off and retry transparently rather than treating