aboutsummaryrefslogtreecommitdiff
path: root/weed/s3api
diff options
context:
space:
mode:
authorChris Lu <chris.lu@gmail.com>2021-03-19 01:31:49 -0700
committerChris Lu <chris.lu@gmail.com>2021-03-19 01:31:49 -0700
commitb1a86cf8085d5f0aff27f7ff6e3b8a7d666f766b (patch)
treea8acbba3be8543777d6b8c31dfc247a154d6de5e /weed/s3api
parentaa5179ce3c5ad92887dcddaa59a7f17868fb5bb2 (diff)
downloadseaweedfs-b1a86cf8085d5f0aff27f7ff6e3b8a7d666f766b.tar.xz
seaweedfs-b1a86cf8085d5f0aff27f7ff6e3b8a7d666f766b.zip
s3: copy object to itself
fix https://github.com/chrislusf/seaweedfs/issues/1922
Diffstat (limited to 'weed/s3api')
-rw-r--r--weed/s3api/filer_util.go6
-rw-r--r--weed/s3api/s3api_object_copy_handlers.go27
2 files changed, 32 insertions, 1 deletions
diff --git a/weed/s3api/filer_util.go b/weed/s3api/filer_util.go
index 12a74126a..1803332a3 100644
--- a/weed/s3api/filer_util.go
+++ b/weed/s3api/filer_util.go
@@ -79,6 +79,12 @@ func (s3a *S3ApiServer) exists(parentDirectoryPath string, entryName string, isD
}
+func (s3a *S3ApiServer) touch(parentDirectoryPath string, entryName string, entry *filer_pb.Entry) (err error) {
+
+ return filer_pb.Touch(s3a, parentDirectoryPath, entryName, entry)
+
+}
+
func (s3a *S3ApiServer) getEntry(parentDirectoryPath, entryName string) (entry *filer_pb.Entry, err error) {
fullPath := util.NewFullPath(parentDirectoryPath, entryName)
return filer_pb.GetEntry(s3a, fullPath)
diff --git a/weed/s3api/s3api_object_copy_handlers.go b/weed/s3api/s3api_object_copy_handlers.go
index ca578e7e5..84a85fd78 100644
--- a/weed/s3api/s3api_object_copy_handlers.go
+++ b/weed/s3api/s3api_object_copy_handlers.go
@@ -4,6 +4,7 @@ import (
"fmt"
"github.com/chrislusf/seaweedfs/weed/glog"
"github.com/chrislusf/seaweedfs/weed/s3api/s3err"
+ weed_server "github.com/chrislusf/seaweedfs/weed/server"
"net/http"
"net/url"
"strconv"
@@ -25,6 +26,26 @@ func (s3a *S3ApiServer) CopyObjectHandler(w http.ResponseWriter, r *http.Request
}
srcBucket, srcObject := pathToBucketAndObject(cpSrcPath)
+
+ if (srcBucket == dstBucket && srcObject == dstObject || cpSrcPath == "") && isReplace(r) {
+ fullPath := util.FullPath(fmt.Sprintf("%s/%s%s", s3a.option.BucketsPath, dstBucket, dstObject))
+ dir, name := fullPath.DirAndName()
+ entry, err := s3a.getEntry(dir, name)
+ if err != nil {
+ writeErrorResponse(w, s3err.ErrInvalidCopySource, r.URL)
+ }
+ entry.Extended = weed_server.SaveAmzMetaData(r, entry.Extended, isReplace(r))
+ err = s3a.touch(dir, name, entry)
+ if err != nil {
+ writeErrorResponse(w, s3err.ErrInvalidCopySource, r.URL)
+ }
+ writeSuccessResponseXML(w, encodeResponse(CopyObjectResult{
+ ETag: fmt.Sprintf("%x", entry.Attributes.Md5),
+ LastModified: time.Now().UTC(),
+ }))
+ return
+ }
+
// If source object is empty or bucket is empty, reply back invalid copy source.
if srcObject == "" || srcBucket == "" {
writeErrorResponse(w, s3err.ErrInvalidCopySource, r.URL)
@@ -32,7 +53,7 @@ func (s3a *S3ApiServer) CopyObjectHandler(w http.ResponseWriter, r *http.Request
}
if srcBucket == dstBucket && srcObject == dstObject {
- writeErrorResponse(w, s3err.ErrInvalidCopySource, r.URL)
+ writeErrorResponse(w, s3err.ErrInvalidCopyDest, r.URL)
return
}
@@ -147,3 +168,7 @@ func (s3a *S3ApiServer) CopyObjectPartHandler(w http.ResponseWriter, r *http.Req
writeSuccessResponseXML(w, encodeResponse(response))
}
+
+func isReplace(r *http.Request) bool {
+ return r.Header.Get("X-Amz-Metadata-Directive") == "REPLACE"
+}