fix(storage): preserve ReadParts errors across keepalive responses

ReadPartsHandler completed its keepalive stream before reporting storage failures, then tried to write an ordinary error response after the body was already owned. Clients consequently decoded the error text as msgpack and lost the real failure.

Send failures through the keepalive completion channel and mark success only after ReadParts returns cleanly, preserving the existing wire framing and error identity.

Co-authored-by: ChatGPT <noreply@openai.com>
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Feng Ruohang
2026-08-04 22:42:56 +08:00
parent b6f70ab085
commit 1af351a702
4 changed files with 42 additions and 19 deletions
+5 -2
View File
@@ -597,11 +597,14 @@ func (s *storageRESTServer) ReadPartsHandler(w http.ResponseWriter, r *http.Requ
done := keepHTTPResponseAlive(w)
infos, err := s.getStorage().ReadParts(r.Context(), volume, preq.Paths...)
done(nil)
if err != nil {
s.writeErrorResponse(w, err)
// The keep-alive stream owns the response body from here on, so the
// error has to travel through done(); writing a header afterwards is
// too late and leaves the client decoding the error text as msgpack.
done(err)
return
}
done(nil)
presp := &ReadPartsResp{Infos: infos}
storageLogIf(r.Context(), msgp.Encode(w, presp))