Skip to content

Commit 78e08c4

Browse files
authored
Handle checksum for unseekable 0-length s3 request body (#3086)
* Handle checksum for unseekable body with 0 content length
1 parent 6a7e8b5 commit 78e08c4

File tree

3 files changed

+21
-10
lines changed

3 files changed

+21
-10
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"id": "0e919f9c-00d1-4acd-87fc-f6c0f1de614f",
3+
"type": "bugfix",
4+
"description": "Handle checksum for unseekable body with 0 content length",
5+
"modules": [
6+
"service/internal/checksum"
7+
]
8+
}

service/internal/checksum/middleware_compute_input_checksum.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ func (m *ComputeInputPayloadChecksum) HandleFinalize(
179179

180180
// Only seekable streams are supported for non-trailing checksums, because
181181
// the stream needs to be rewound before the handler can continue.
182-
if stream != nil && !req.IsStreamSeekable() {
182+
if stream != nil && !req.IsStreamSeekable() && streamLength != 0 {
183183
return out, metadata, computeInputHeaderChecksumError{
184184
Msg: "unseekable stream is not supported without TLS and trailing checksum",
185185
}
@@ -194,11 +194,13 @@ func (m *ComputeInputPayloadChecksum) HandleFinalize(
194194
Err: err,
195195
}
196196
}
197-
198-
if err := req.RewindStream(); err != nil {
199-
return out, metadata, computeInputHeaderChecksumError{
200-
Msg: "failed to rewind stream",
201-
Err: err,
197+
// only attempt rewind if the stream length has been determined and is non-zero
198+
if streamLength > 0 {
199+
if err := req.RewindStream(); err != nil {
200+
return out, metadata, computeInputHeaderChecksumError{
201+
Msg: "failed to rewind stream",
202+
Err: err,
203+
}
202204
}
203205
}
204206

@@ -414,7 +416,7 @@ func computeStreamChecksum(algorithm Algorithm, stream io.Reader, computePayload
414416
}
415417

416418
func getRequestStreamLength(req *smithyhttp.Request) (int64, error) {
417-
if v := req.ContentLength; v > 0 {
419+
if v := req.ContentLength; v >= 0 {
418420
return v, nil
419421
}
420422

service/internal/checksum/middleware_compute_input_checksum_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package checksum
55

66
import (
7+
"bufio"
78
"bytes"
89
"context"
910
"fmt"
@@ -239,16 +240,16 @@ func TestComputeInputPayloadChecksum(t *testing.T) {
239240
r := smithyhttp.NewStackRequest().(*smithyhttp.Request)
240241
r.URL, _ = url.Parse("https://example.aws")
241242
r.ContentLength = 0
242-
r = requestMust(r.SetStream(&bytes.Buffer{}))
243+
r = requestMust(r.SetStream(bufio.NewReader(bytes.NewBuffer([]byte{}))))
243244
return r
244245
}(),
245246
},
246247
expectHeader: http.Header{
247248
"X-Amz-Checksum-Crc32": []string{"AAAAAA=="},
248249
},
249250
expectContentLength: 0,
250-
expectPayload: nil,
251-
expectPayloadHash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
251+
expectPayload: []byte{},
252+
// payload hash is set via a different middleware, so not checking it here
252253
expectChecksumMetadata: map[string]string{
253254
"CRC32": "AAAAAA==",
254255
},

0 commit comments

Comments
 (0)