aboutsummaryrefslogtreecommitdiff
path: root/weed/s3api/s3api_object_multipart_handlers.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/s3api/s3api_object_multipart_handlers.go')
-rw-r--r--weed/s3api/s3api_object_multipart_handlers.go36
1 files changed, 31 insertions, 5 deletions
diff --git a/weed/s3api/s3api_object_multipart_handlers.go b/weed/s3api/s3api_object_multipart_handlers.go
index 99c280e13..35bc174c8 100644
--- a/weed/s3api/s3api_object_multipart_handlers.go
+++ b/weed/s3api/s3api_object_multipart_handlers.go
@@ -1,11 +1,13 @@
package s3api
import (
+ "encoding/xml"
"fmt"
"github.com/chrislusf/seaweedfs/weed/glog"
xhttp "github.com/chrislusf/seaweedfs/weed/s3api/http"
"github.com/chrislusf/seaweedfs/weed/s3api/s3err"
weed_server "github.com/chrislusf/seaweedfs/weed/server"
+ "io"
"net/http"
"net/url"
"strconv"
@@ -56,8 +58,16 @@ func (s3a *S3ApiServer) NewMultipartUploadHandler(w http.ResponseWriter, r *http
// CompleteMultipartUploadHandler - Completes multipart upload.
func (s3a *S3ApiServer) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.Request) {
+ // https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html
+
bucket, object := xhttp.GetBucketAndObject(r)
+ parts := &CompleteMultipartUpload{}
+ if err := xmlDecoder(r.Body, parts, r.ContentLength); err != nil {
+ s3err.WriteErrorResponse(w, r, s3err.ErrMalformedXML)
+ return
+ }
+
// Get upload id.
uploadID, _, _, _ := getObjectResources(r.URL.Query())
@@ -65,7 +75,7 @@ func (s3a *S3ApiServer) CompleteMultipartUploadHandler(w http.ResponseWriter, r
Bucket: aws.String(bucket),
Key: objectKey(aws.String(object)),
UploadId: aws.String(uploadID),
- })
+ }, parts)
glog.V(2).Info("CompleteMultipartUploadHandler", string(s3err.EncodeXMLResponse(response)), errCode)
@@ -268,8 +278,24 @@ func getObjectResources(values url.Values) (uploadID string, partNumberMarker, m
return
}
-type byCompletedPartNumber []*s3.CompletedPart
+func xmlDecoder(body io.Reader, v interface{}, size int64) error {
+ var lbody io.Reader
+ if size > 0 {
+ lbody = io.LimitReader(body, size)
+ } else {
+ lbody = body
+ }
+ d := xml.NewDecoder(lbody)
+ d.CharsetReader = func(label string, input io.Reader) (io.Reader, error) {
+ return input, nil
+ }
+ return d.Decode(v)
+}
-func (a byCompletedPartNumber) Len() int { return len(a) }
-func (a byCompletedPartNumber) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-func (a byCompletedPartNumber) Less(i, j int) bool { return *a[i].PartNumber < *a[j].PartNumber }
+type CompleteMultipartUpload struct {
+ Parts []CompletedPart `xml:"Part"`
+}
+type CompletedPart struct {
+ ETag string
+ PartNumber int
+}