Merge pull request #2160 from versity/ben/eof-err

fix: connection early termination resulting in internal error
This commit is contained in:
Ben McClelland
2026-06-01 14:02:21 -07:00
committed by GitHub
2 changed files with 16 additions and 0 deletions
+8
View File
@@ -30,6 +30,7 @@ import (
"github.com/aws/aws-sdk-go-v2/service/s3/types"
"github.com/cespare/xxhash/v2"
"github.com/versity/versitygw/debuglogger"
"github.com/versity/versitygw/s3err"
"github.com/zeebo/xxh3"
)
@@ -127,6 +128,13 @@ func NewHashReader(r io.Reader, expectedSum string, ht HashType) (*HashReader, e
// Read allows *HashReader to be used as an io.Reader
func (hr *HashReader) Read(p []byte) (int, error) {
n, readerr := hr.r.Read(p)
// Treat ErrUnexpectedEOF as EOF so a truncated body triggers checksum
// validation (which will fail on partial data) rather than leaking a
// raw Go error as an internal server error.
if readerr == io.ErrUnexpectedEOF {
debuglogger.Logf("client connection terminated early")
readerr = io.EOF
}
_, err := hr.hash.Write(p[:n])
if err != nil {
return n, err
+8
View File
@@ -124,6 +124,14 @@ func NewSignedChunkReader(r io.Reader, authdata AuthData, canonicalString, secre
// Read satisfies the io.Reader for this type
func (cr *ChunkReader) Read(p []byte) (int, error) {
n, err := cr.r.Read(p)
// Treat ErrUnexpectedEOF as EOF so a connection that closes before
// all Content-Length bytes arrive follows the normal EOF path and
// returns a proper S3 error (e.g. ErrContentLengthMismatch or
// SignatureDoesNotMatch) instead of leaking an internal Go error.
if err == io.ErrUnexpectedEOF {
debuglogger.Logf("client connection terminated early")
err = io.EOF
}
if err != nil && err != io.EOF {
return 0, err
}