forked from TrueCloudLab/frostfs-s3-gw
[#186] Fix versioning issues in UploadPart
Signed-off-by: Angira Kekteeva <kira@nspcc.ru>
This commit is contained in:
parent
873622d4d5
commit
d6f0ab8ea4
5 changed files with 43 additions and 14 deletions
|
@ -5,11 +5,13 @@ import (
|
|||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/data"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/errors"
|
||||
"github.com/nspcc-dev/neofs-s3-gw/api/layer"
|
||||
"go.uber.org/zap"
|
||||
|
@ -251,6 +253,8 @@ func (h *handler) UploadPartCopy(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
var (
|
||||
versionID string
|
||||
|
||||
queryValues = reqInfo.URL.Query()
|
||||
uploadID = queryValues.Get(uploadIDHeaderName)
|
||||
additional = []zap.Field{zap.String("uploadID", uploadID), zap.String("Key", reqInfo.ObjectName)}
|
||||
|
@ -263,6 +267,10 @@ func (h *handler) UploadPartCopy(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
src := r.Header.Get(api.AmzCopySource)
|
||||
if u, err := url.Parse(src); err == nil {
|
||||
versionID = u.Query().Get(api.QueryVersionID)
|
||||
src = u.Path
|
||||
}
|
||||
srcBucket, srcObject := path2BucketObject(src)
|
||||
|
||||
srcRange, err := parseRange(r.Header.Get(api.AmzCopySourceRange))
|
||||
|
@ -273,13 +281,29 @@ func (h *handler) UploadPartCopy(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
srcInfo, err := h.obj.GetObjectInfo(r.Context(), &layer.HeadObjectParams{
|
||||
Bucket: srcBucket,
|
||||
Object: srcObject,
|
||||
Bucket: srcBucket,
|
||||
Object: srcObject,
|
||||
VersionID: versionID,
|
||||
})
|
||||
if err != nil {
|
||||
if errors.IsS3Error(err, errors.ErrNoSuchKey) && versionID != "" {
|
||||
h.logAndSendError(w, "could not head source object version", reqInfo,
|
||||
errors.GetAPIError(errors.ErrBadRequest), additional...)
|
||||
return
|
||||
}
|
||||
h.logAndSendError(w, "could not head source object", reqInfo, err, additional...)
|
||||
return
|
||||
}
|
||||
if isDeleted(srcInfo) {
|
||||
if versionID != "" {
|
||||
h.logAndSendError(w, "could not head source object version", reqInfo,
|
||||
errors.GetAPIError(errors.ErrBadRequest), additional...)
|
||||
return
|
||||
}
|
||||
h.logAndSendError(w, "could not head source object", reqInfo,
|
||||
errors.GetAPIError(errors.ErrNoSuchKey), additional...)
|
||||
return
|
||||
}
|
||||
|
||||
args, err := parseCopyObjectArgs(r.Header)
|
||||
if err != nil {
|
||||
|
@ -643,3 +667,7 @@ func encodeListPartsToResponse(info *layer.ListPartsInfo, params *layer.ListPart
|
|||
Parts: info.Parts,
|
||||
}
|
||||
}
|
||||
|
||||
func isDeleted(objInfo *data.ObjectInfo) bool {
|
||||
return objInfo.Headers[layer.VersionsDeleteMarkAttr] == layer.DelMarkFullObject
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue