[#642] Fix streaming empty body
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
parent
e184b333e4
commit
e0a54fcbd3
4 changed files with 141 additions and 0 deletions
|
@ -489,6 +489,58 @@ func TestPutObjectWithStreamEmptyBodyAWSExample(t *testing.T) {
|
|||
require.Empty(t, res.Contents[0].Size)
|
||||
}
|
||||
|
||||
func TestPutObjectWithStreamEmptyBody(t *testing.T) {
|
||||
hc := prepareHandlerContext(t)
|
||||
|
||||
bktName := "bucket"
|
||||
createTestBucket(hc, bktName)
|
||||
|
||||
t.Run("unsigned", func(t *testing.T) {
|
||||
t.Run("trailer", func(t *testing.T) {
|
||||
objName := "unsigned trailer"
|
||||
|
||||
w, req := getEmptyChunkedRequestUnsigned(hc.context, t, bktName, objName)
|
||||
req.Header.Del(api.ContentType)
|
||||
hc.Handler().PutObjectHandler(w, req)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
d, h := getObject(hc, bktName, objName)
|
||||
require.Empty(t, d)
|
||||
require.Equal(t, "0", h.Get(api.ContentLength))
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("sigv4", func(t *testing.T) {
|
||||
t.Run("no trailer", func(t *testing.T) {
|
||||
objName := "sigv4 no trailer"
|
||||
|
||||
w, req := getEmptyChunkedRequest(hc.context, t, bktName, objName)
|
||||
req.Header.Del(api.ContentType)
|
||||
hc.Handler().PutObjectHandler(w, req)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
d, h := getObject(hc, bktName, objName)
|
||||
require.Empty(t, d)
|
||||
require.Equal(t, "0", h.Get(api.ContentLength))
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("sigv4a", func(t *testing.T) {
|
||||
t.Run("trailer", func(t *testing.T) {
|
||||
objName := "sigv4a trailer"
|
||||
|
||||
w, req := getEmptyChunkedRequestSigv4a(hc.context, t, bktName, objName)
|
||||
req.Header.Del(api.ContentType)
|
||||
hc.Handler().PutObjectHandler(w, req)
|
||||
assertStatus(t, w, http.StatusOK)
|
||||
|
||||
d, h := getObject(hc, bktName, objName)
|
||||
require.Empty(t, d)
|
||||
require.Equal(t, "0", h.Get(api.ContentLength))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestPutChunkedTestContentEncoding(t *testing.T) {
|
||||
hc := prepareHandlerContext(t)
|
||||
|
||||
|
@ -818,6 +870,83 @@ func getEmptyChunkedRequest(ctx context.Context, t *testing.T, bktName, objName
|
|||
return w, req
|
||||
}
|
||||
|
||||
func getEmptyChunkedRequestUnsigned(ctx context.Context, t *testing.T, bktName, objName string) (*httptest.ResponseRecorder, *http.Request) {
|
||||
AWSAccessKeyID := "3jNrmDtHtuj1uLcixaSMA4KNUhNYhv1EpUNdFnbTXgUP071pGdSZfHSLtoC8gzjF5HoD6sC3Scq33t1WvvEvjmPnt"
|
||||
AWSSecretAccessKey := "f1a0d650b650149f1a83140418e88a3c5572a0103e912e326492a91c19c4488a"
|
||||
|
||||
reqBody := bytes.NewBufferString("0\r\nx-amz-checksum-crc64nvme:AAAAAAAAAAA=\r\n\r\n")
|
||||
|
||||
req, err := http.NewRequest("PUT", "http://localhost:8084/"+bktName+"/"+objName, reqBody)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set(api.Authorization, "AWS4-HMAC-SHA256 Credential=3jNrmDtHtuj1uLcixaSMA4KNUhNYhv1EpUNdFnbTXgUP071pGdSZfHSLtoC8gzjF5HoD6sC3Scq33t1WvvEvjmPnt/20250213/ru/s3/aws4_request, SignedHeaders=content-encoding;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-sdk-checksum-algorithm;x-amz-trailer, Signature=1231b012c0ac313770c5a95ccf77b95b6c9b1c3760d6aa24cb8309801d56eb4a")
|
||||
req.Header.Set(api.ContentEncoding, api.AwsChunked)
|
||||
req.Header.Set(api.AmzDate, "20250213T124858Z")
|
||||
req.Header.Set(api.AmzContentSha256, api.StreamingUnsignedPayloadTrailer)
|
||||
req.Header.Set(api.AmzDecodedContentLength, "0")
|
||||
req.Header.Set("X-Amz-Trailer", "x-amz-checksum-crc64nvme")
|
||||
req.Header.Set("X-Amz-Sdk-Checksum-Algorithm", "CRC64NVME")
|
||||
|
||||
signTime, err := time.Parse("20060102T150405Z", req.Header.Get(api.AmzDate))
|
||||
require.NoError(t, err)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
reqInfo := middleware.NewReqInfo(w, req, middleware.ObjectRequest{Bucket: bktName, Object: objName}, "")
|
||||
req = req.WithContext(middleware.SetReqInfo(ctx, reqInfo))
|
||||
req = req.WithContext(middleware.SetBox(req.Context(), &middleware.Box{
|
||||
ClientTime: signTime,
|
||||
AuthHeaders: &middleware.AuthHeader{
|
||||
AccessKeyID: AWSAccessKeyID,
|
||||
SignatureV4: "1231b012c0ac313770c5a95ccf77b95b6c9b1c3760d6aa24cb8309801d56eb4a",
|
||||
Region: "ru",
|
||||
},
|
||||
AccessBox: &accessbox.Box{Gate: &accessbox.GateData{SecretKey: AWSSecretAccessKey}},
|
||||
}))
|
||||
|
||||
return w, req
|
||||
}
|
||||
|
||||
func getEmptyChunkedRequestSigv4a(ctx context.Context, t *testing.T, bktName, objName string) (*httptest.ResponseRecorder, *http.Request) {
|
||||
AWSAccessKeyID := "3jNrmDtHtuj1uLcixaSMA4KNUhNYhv1EpUNdFnbTXgUP071pGdSZfHSLtoC8gzjF5HoD6sC3Scq33t1WvvEvjmPnt"
|
||||
AWSSecretAccessKey := "f1a0d650b650149f1a83140418e88a3c5572a0103e912e326492a91c19c4488a"
|
||||
|
||||
body := "0;chunk-signature=3046022100ab9229a80d70f4d004768992881821a441a4ad4102e18de567e68216659bf497022100ec47a7a445351683557eedf893e6ed250c97af4b0415814671770b83766d69be\r\n" +
|
||||
"x-amz-checksum-crc32:AAAAAA==\r\n" +
|
||||
"x-amz-trailer-signature:3046022100a0a66c1adcee8d99460b4631b23c95fbad9eb4e6c56f1afb9e255715ba141169022100b2cfc8adc8036eb985f1ab0e770b575284c5fc8ca75c226558d3142cbaab83ce\r\n\r\n"
|
||||
|
||||
req, err := http.NewRequest("PUT", "http://localhost:8084/"+bktName+"/"+objName, bytes.NewBufferString(body))
|
||||
require.NoError(t, err)
|
||||
req.Header.Set(api.Authorization, "AWS4-ECDSA-P256-SHA256 Credential=3jNrmDtHtuj1uLcixaSMA4KNUhNYhv1EpUNdFnbTXgUP071pGdSZfHSLtoC8gzjF5HoD6sC3Scq33t1WvvEvjmPnt/20250213/s3/aws4_request, SignedHeaders=amz-sdk-invocation-id;amz-sdk-request;content-length;content-type;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-region-set;x-amz-sdk-checksum-algorithm;x-amz-trailer, Signature=304402202e1f1efcc56c588d9a94a3d8f20368686df8bfd5e8aad01fc4eff569ff38f1800220215198e3f1ba785492fe6703c4722872909ce8a09e8c9a13da90a9230c7a24b7")
|
||||
req.Header.Set("Amz-Sdk-Invocation-Id", "d42dc16d-7899-55fb-5b72-a654bd482f4f")
|
||||
req.Header.Set("Amz-Sdk-Request", "attempt=1; max=2")
|
||||
req.Header.Set(api.ContentEncoding, api.AwsChunked)
|
||||
req.Header.Set(api.AmzDate, "20250213T132401Z")
|
||||
req.Header.Set(api.AmzContentSha256, api.StreamingContentV4aSHA256Trailer)
|
||||
req.Header.Set(api.AmzDecodedContentLength, "0")
|
||||
req.Header.Set(api.ContentLength, "367")
|
||||
req.Header.Set(api.ContentType, "text/plain: charset=UTF-8")
|
||||
req.Header.Set("X-Amz-Region-Set", "use-east-1")
|
||||
req.Header.Set("X-Amz-Trailer", "x-amz-checksum-crc32")
|
||||
req.Header.Set("X-Amz-Sdk-Checksum-Algorithm", "CRC32")
|
||||
|
||||
signTime, err := time.Parse("20060102T150405Z", req.Header.Get(api.AmzDate))
|
||||
require.NoError(t, err)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
reqInfo := middleware.NewReqInfo(w, req, middleware.ObjectRequest{Bucket: bktName, Object: objName}, "")
|
||||
req = req.WithContext(middleware.SetReqInfo(ctx, reqInfo))
|
||||
req = req.WithContext(middleware.SetBox(req.Context(), &middleware.Box{
|
||||
ClientTime: signTime,
|
||||
AuthHeaders: &middleware.AuthHeader{
|
||||
AccessKeyID: AWSAccessKeyID,
|
||||
SignatureV4: "304402202e1f1efcc56c588d9a94a3d8f20368686df8bfd5e8aad01fc4eff569ff38f1800220215198e3f1ba785492fe6703c4722872909ce8a09e8c9a13da90a9230c7a24b7",
|
||||
Region: "us-east-1",
|
||||
},
|
||||
AccessBox: &accessbox.Box{Gate: &accessbox.GateData{SecretKey: AWSSecretAccessKey}},
|
||||
}))
|
||||
|
||||
return w, req
|
||||
}
|
||||
|
||||
func TestCreateBucket(t *testing.T) {
|
||||
hc := prepareHandlerContext(t)
|
||||
bktName := "bkt-name"
|
||||
|
|
|
@ -59,6 +59,10 @@ func (c *s3ChunkReader) Read(buf []byte) (num int, err error) {
|
|||
buf = buf[num:]
|
||||
}
|
||||
|
||||
if c.err != nil {
|
||||
return 0, c.err
|
||||
}
|
||||
|
||||
var size int
|
||||
for {
|
||||
b, err := c.reader.ReadByte()
|
||||
|
|
|
@ -31,6 +31,10 @@ func (c *s3UnsignedChunkReader) Read(buf []byte) (num int, err error) {
|
|||
buf = buf[num:]
|
||||
}
|
||||
|
||||
if c.err != nil {
|
||||
return 0, c.err
|
||||
}
|
||||
|
||||
var size int
|
||||
var b byte
|
||||
for {
|
||||
|
|
|
@ -46,6 +46,10 @@ func (c *s3v4aChunkReader) Read(buf []byte) (num int, err error) {
|
|||
buf = buf[num:]
|
||||
}
|
||||
|
||||
if c.err != nil {
|
||||
return 0, c.err
|
||||
}
|
||||
|
||||
var size int
|
||||
for {
|
||||
b, err := c.reader.ReadByte()
|
||||
|
|
Loading…
Add table
Reference in a new issue