mirror of
https://github.com/versity/versitygw.git
synced 2026-08-18 21:26:27 +00:00
fix: connection early termination resulting in internal error
When the connection terminates before all bytes read, we were getting an io.ErrUnexpectedEOF that was not being handled as a standard io.EOF resulting in an internal error being raised. Translate io.ErrUnexpectedEOF to io.EOF so that we return the normal errors for unexpected content. Add a log message so that its clear the error is due to the connection being terminated before all data sent and not the fault of the gateway.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user