diff --git a/api/handler/multipart_upload.go b/api/handler/multipart_upload.go index 1795c29..18d717c 100644 --- a/api/handler/multipart_upload.go +++ b/api/handler/multipart_upload.go @@ -199,14 +199,16 @@ func (h *handler) UploadPartHandler(w http.ResponseWriter, r *http.Request) { return } - body, err := h.getBodyReader(r) + body, decodedSize, err := h.getBodyReader(r) if err != nil { h.logAndSendError(w, "failed to get body reader", reqInfo, err, additional...) return } var size uint64 - if r.ContentLength > 0 { + if decodedSize > 0 { + size = uint64(decodedSize) + } else if r.ContentLength > 0 { size = uint64(r.ContentLength) } diff --git a/api/handler/put.go b/api/handler/put.go index e740cbb..c4f0453 100644 --- a/api/handler/put.go +++ b/api/handler/put.go @@ -233,7 +233,7 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) { return } - body, err := h.getBodyReader(r) + body, decodedSize, err := h.getBodyReader(r) if err != nil { h.logAndSendError(w, "failed to get body reader", reqInfo, err) return @@ -243,7 +243,10 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) { } var size uint64 - if r.ContentLength > 0 { + + if decodedSize > 0 { + size = uint64(decodedSize) + } else if r.ContentLength > 0 { size = uint64(r.ContentLength) } @@ -310,9 +313,9 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) { } } -func (h *handler) getBodyReader(r *http.Request) (io.ReadCloser, error) { +func (h *handler) getBodyReader(r *http.Request) (io.ReadCloser, int, error) { if !api.IsSignedStreamingV4(r) { - return r.Body, nil + return r.Body, -1, nil } encodings := r.Header.Values(api.ContentEncoding) @@ -331,25 +334,26 @@ func (h *handler) getBodyReader(r *http.Request) (io.ReadCloser, error) { r.Header.Set(api.ContentEncoding, strings.Join(resultContentEncoding, ",")) if !chunkedEncoding && !h.cfg.BypassContentEncodingInChunks() { - return nil, fmt.Errorf("%w: request is not chunk encoded, encodings '%s'", + return nil, -1, fmt.Errorf("%w: request is not chunk encoded, encodings '%s'", errors.GetAPIError(errors.ErrInvalidEncodingMethod), strings.Join(encodings, ",")) } decodeContentSize := r.Header.Get(api.AmzDecodedContentLength) if len(decodeContentSize) == 0 { - return nil, errors.GetAPIError(errors.ErrMissingContentLength) + return nil, -1, errors.GetAPIError(errors.ErrMissingContentLength) } - if _, err := strconv.Atoi(decodeContentSize); err != nil { - return nil, fmt.Errorf("%w: parse decoded content length: %s", errors.GetAPIError(errors.ErrMissingContentLength), err.Error()) + decoded, err := strconv.Atoi(decodeContentSize) + if err != nil { + return nil, -1, fmt.Errorf("%w: parse decoded content length: %s", errors.GetAPIError(errors.ErrMissingContentLength), err.Error()) } chunkReader, err := newSignV4ChunkedReader(r) if err != nil { - return nil, fmt.Errorf("initialize chunk reader: %w", err) + return nil, -1, fmt.Errorf("initialize chunk reader: %w", err) } - return chunkReader, nil + return chunkReader, decoded, nil } func formEncryptionParams(r *http.Request) (enc encryption.Params, err error) {