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.go44
1 files changed, 41 insertions, 3 deletions
diff --git a/weed/s3api/s3api_object_multipart_handlers.go b/weed/s3api/s3api_object_multipart_handlers.go
index 35bc174c8..d2fa21c2e 100644
--- a/weed/s3api/s3api_object_multipart_handlers.go
+++ b/weed/s3api/s3api_object_multipart_handlers.go
@@ -2,6 +2,7 @@ package s3api
import (
"encoding/xml"
+ "crypto/sha1"
"fmt"
"github.com/chrislusf/seaweedfs/weed/glog"
xhttp "github.com/chrislusf/seaweedfs/weed/s3api/http"
@@ -70,6 +71,11 @@ func (s3a *S3ApiServer) CompleteMultipartUploadHandler(w http.ResponseWriter, r
// Get upload id.
uploadID, _, _, _ := getObjectResources(r.URL.Query())
+ err := s3a.checkUploadId(object, uploadID)
+ if err != nil {
+ s3err.WriteErrorResponse(w, r, s3err.ErrNoSuchUpload)
+ return
+ }
response, errCode := s3a.completeMultipartUpload(&s3.CompleteMultipartUploadInput{
Bucket: aws.String(bucket),
@@ -94,6 +100,11 @@ func (s3a *S3ApiServer) AbortMultipartUploadHandler(w http.ResponseWriter, r *ht
// Get upload id.
uploadID, _, _, _ := getObjectResources(r.URL.Query())
+ err := s3a.checkUploadId(object, uploadID)
+ if err != nil {
+ s3err.WriteErrorResponse(w, r, s3err.ErrNoSuchUpload)
+ return
+ }
response, errCode := s3a.abortMultipartUpload(&s3.AbortMultipartUploadInput{
Bucket: aws.String(bucket),
@@ -165,6 +176,12 @@ func (s3a *S3ApiServer) ListObjectPartsHandler(w http.ResponseWriter, r *http.Re
return
}
+ err := s3a.checkUploadId(object, uploadID)
+ if err != nil {
+ s3err.WriteErrorResponse(w, r, s3err.ErrNoSuchUpload)
+ return
+ }
+
response, errCode := s3a.listObjectParts(&s3.ListPartsInput{
Bucket: aws.String(bucket),
Key: objectKey(aws.String(object)),
@@ -186,11 +203,11 @@ func (s3a *S3ApiServer) ListObjectPartsHandler(w http.ResponseWriter, r *http.Re
// PutObjectPartHandler - Put an object part in a multipart upload.
func (s3a *S3ApiServer) PutObjectPartHandler(w http.ResponseWriter, r *http.Request) {
- bucket, _ := xhttp.GetBucketAndObject(r)
+ bucket, object := xhttp.GetBucketAndObject(r)
uploadID := r.URL.Query().Get("uploadId")
- exists, err := s3a.exists(s3a.genUploadsFolder(bucket), uploadID, true)
- if !exists {
+ err := s3a.checkUploadId(object, uploadID)
+ if err != nil {
s3err.WriteErrorResponse(w, r, s3err.ErrNoSuchUpload)
return
}
@@ -250,6 +267,27 @@ func (s3a *S3ApiServer) genUploadsFolder(bucket string) string {
return fmt.Sprintf("%s/%s/.uploads", s3a.option.BucketsPath, bucket)
}
+// Generate uploadID hash string from object
+func (s3a *S3ApiServer) generateUploadID(object string) string {
+ if strings.HasPrefix(object, "/") {
+ object = object[1:]
+ }
+ h := sha1.New()
+ h.Write([]byte(object))
+ return fmt.Sprintf("%x", h.Sum(nil))
+}
+
+//Check object name and uploadID when processing multipart uploading
+func (s3a *S3ApiServer) checkUploadId(object string, id string) error {
+
+ hash := s3a.generateUploadID(object)
+ if hash != id {
+ glog.Errorf("object %s and uploadID %s are not matched", object, id)
+ return fmt.Errorf("object %s and uploadID %s are not matched", object, id)
+ }
+ return nil
+}
+
// Parse bucket url queries for ?uploads
func getBucketMultipartResources(values url.Values) (prefix, keyMarker, uploadIDMarker, delimiter string, maxUploads int, encodingType string) {
prefix = values.Get("prefix")