seaweedfs/weed/operation
Chris Lu 0716577ec8
fix(upload): rewind request body when retrying on connection reset (#9139) (#9222)
* fix(upload): rewind request body when retrying on connection reset (#9139)

When httpClient.Do() returned "connection reset by peer" or "use of
closed network connection", upload_content retried with the same
*http.Request. But the body is a *bytes.Reader the first attempt
already consumed, so the retry sent 0 bytes and Go's transport
surfaced "http: ContentLength=N with Body length 0".

http.NewRequestWithContext populates req.GetBody for *bytes.Reader
bodies; use it to attach a fresh body before retrying.

Reproduces the issue with a unit test (asserts both attempts see
the same payload bytes); the test fails without the fix.

* upload: skip inner retry when body cannot be rewound

Per review feedback: if req.GetBody is nil or returns an error, the
inner retry would call Do(req) with an already-consumed body and the
"connection reset" error would be replaced by the misleading
"ContentLength=N with Body length 0" — the very symptom this PR set
out to fix. Skip the inner retry on rewind failure and let the outer
retriedUploadData loop reissue with a fresh request, and log when
GetBody is unavailable for observability.

* upload: log the actual transport error in the inner retry log line

Per review feedback: the diagnostic glog at the top of the inner
retry branch was logging postErr — the request-construction error
from http.NewRequestWithContext, which is necessarily nil there
because the function returns early at line 423 if it isn't.
Operators were seeing "<nil>" instead of the transient transport
error that triggered the rewind. Reference post_err so the
connection-reset / closed-connection cause is actually visible.
2026-04-26 02:17:55 -07:00
..
assign_file_id_retry_test.go master: return 503/Unavailable during topology warmup after leader change (#8529) 2026-03-08 16:05:45 -07:00
assign_file_id.go fix(filer): drop stale master gRPC cache on stream death (#9102) (#9107) 2026-04-16 12:10:25 -07:00
buffer_pool.go chore: execute goimports to format the code (#7983) 2026-01-07 13:06:08 -08:00
chunked_file.go Filer: batch deletion operations to return individual error results (#7382) 2025-10-25 00:09:18 -07:00
data_struts.go cleanup security.Secret 2019-02-09 21:56:32 -08:00
delete_content.go Filer: batch deletion operations to return individual error results (#7382) 2025-10-25 00:09:18 -07:00
grpc_client.go grpc connection to filer add sw-client-id header 2023-01-20 01:48:12 -08:00
lookup_vid_cache_test.go directory structure change to work with glide 2016-06-02 18:09:14 -07:00
lookup_vid_cache.go move to https://github.com/seaweedfs/seaweedfs 2022-07-29 00:17:28 -07:00
lookup.go master: return 503/Unavailable during topology warmup after leader change (#8529) 2026-03-08 16:05:45 -07:00
needle_parse_test.go Add context with request (#6824) 2025-05-28 11:34:02 -07:00
submit.go fix(mount): remove fid pool to stop master over-allocating volumes (#9111) 2026-04-16 15:51:13 -07:00
sync_volume.go chore: execute goimports to format the code (#7983) 2026-01-07 13:06:08 -08:00
tail_volume.go add default value when reading needle version 2025-06-16 23:35:03 -07:00
upload_chunked_test.go fix(mount): remove fid pool to stop master over-allocating volumes (#9111) 2026-04-16 15:51:13 -07:00
upload_chunked.go chore(upload): log offset/bytes-read context on chunk ReadFrom errors (#9169) 2026-04-20 21:26:34 -07:00
upload_content_test.go fix(upload): rewind request body when retrying on connection reset (#9139) (#9222) 2026-04-26 02:17:55 -07:00
upload_content.go fix(upload): rewind request body when retrying on connection reset (#9139) (#9222) 2026-04-26 02:17:55 -07:00