mirror of
https://github.com/minio/minio.git
synced 2024-12-24 22:25:54 -05:00
handle trimming '/' if present in the object names (#11765)
- MultipleDeletes should handle '/' prefix for objectnames - Trimming the slash alone is enough for ListObjects() prefix and markers fixes #11769
This commit is contained in:
parent
9b54fcdf12
commit
feafccf007
@ -36,19 +36,8 @@ func getListObjectsV1Args(values url.Values) (prefix, marker, delimiter string,
|
||||
maxkeys = maxObjectList
|
||||
}
|
||||
|
||||
var err error
|
||||
prefix, err = unescapePath(values.Get("prefix"))
|
||||
if err != nil {
|
||||
errCode = ErrInvalidRequest
|
||||
return
|
||||
}
|
||||
|
||||
marker, err = unescapePath(values.Get("marker"))
|
||||
if err != nil {
|
||||
errCode = ErrInvalidRequest
|
||||
return
|
||||
}
|
||||
|
||||
prefix = trimLeadingSlash(values.Get("prefix"))
|
||||
marker = trimLeadingSlash(values.Get("marker"))
|
||||
delimiter = values.Get("delimiter")
|
||||
encodingType = values.Get("encoding-type")
|
||||
return
|
||||
@ -67,19 +56,8 @@ func getListBucketObjectVersionsArgs(values url.Values) (prefix, marker, delimit
|
||||
maxkeys = maxObjectList
|
||||
}
|
||||
|
||||
var err error
|
||||
prefix, err = unescapePath(values.Get("prefix"))
|
||||
if err != nil {
|
||||
errCode = ErrInvalidRequest
|
||||
return
|
||||
}
|
||||
|
||||
marker, err = unescapePath(values.Get("key-marker"))
|
||||
if err != nil {
|
||||
errCode = ErrInvalidRequest
|
||||
return
|
||||
}
|
||||
|
||||
prefix = trimLeadingSlash(values.Get("prefix"))
|
||||
marker = trimLeadingSlash(values.Get("key-marker"))
|
||||
delimiter = values.Get("delimiter")
|
||||
encodingType = values.Get("encoding-type")
|
||||
versionIDMarker = values.Get("version-id-marker")
|
||||
@ -108,19 +86,8 @@ func getListObjectsV2Args(values url.Values) (prefix, token, startAfter, delimit
|
||||
maxkeys = maxObjectList
|
||||
}
|
||||
|
||||
var err error
|
||||
prefix, err = unescapePath(values.Get("prefix"))
|
||||
if err != nil {
|
||||
errCode = ErrInvalidRequest
|
||||
return
|
||||
}
|
||||
|
||||
startAfter, err = unescapePath(values.Get("start-after"))
|
||||
if err != nil {
|
||||
errCode = ErrInvalidRequest
|
||||
return
|
||||
}
|
||||
|
||||
prefix = trimLeadingSlash(values.Get("prefix"))
|
||||
startAfter = trimLeadingSlash(values.Get("start-after"))
|
||||
delimiter = values.Get("delimiter")
|
||||
fetchOwner = values.Get("fetch-owner") == "true"
|
||||
encodingType = values.Get("encoding-type")
|
||||
@ -150,19 +117,8 @@ func getBucketMultipartResources(values url.Values) (prefix, keyMarker, uploadID
|
||||
maxUploads = maxUploadsList
|
||||
}
|
||||
|
||||
var err error
|
||||
prefix, err = unescapePath(values.Get("prefix"))
|
||||
if err != nil {
|
||||
errCode = ErrInvalidRequest
|
||||
return
|
||||
}
|
||||
|
||||
keyMarker, err = unescapePath(values.Get("key-marker"))
|
||||
if err != nil {
|
||||
errCode = ErrInvalidRequest
|
||||
return
|
||||
}
|
||||
|
||||
prefix = trimLeadingSlash(values.Get("prefix"))
|
||||
keyMarker = trimLeadingSlash(values.Get("key-marker"))
|
||||
uploadIDMarker = values.Get("upload-id-marker")
|
||||
delimiter = values.Get("delimiter")
|
||||
encodingType = values.Get("encoding-type")
|
||||
|
@ -411,6 +411,11 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
|
||||
return
|
||||
}
|
||||
|
||||
// Convert object name delete objects if it has `/` in the beginning.
|
||||
for i := range deleteObjects.Objects {
|
||||
deleteObjects.Objects[i].ObjectName = trimLeadingSlash(deleteObjects.Objects[i].ObjectName)
|
||||
}
|
||||
|
||||
// Call checkRequestAuthType to populate ReqInfo.AccessKey before GetBucketInfo()
|
||||
// Ignore errors here to preserve the S3 error behavior of GetBucketInfo()
|
||||
checkRequestAuthType(ctx, r, policy.DeleteObjectAction, bucket, "")
|
||||
@ -853,13 +858,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
|
||||
// by the filename attribute passed in multipart
|
||||
formValues.Set("Key", strings.Replace(formValues.Get("Key"), "${filename}", fileName, -1))
|
||||
}
|
||||
object := formValues.Get("Key")
|
||||
|
||||
object, err = unescapePath(object)
|
||||
if err != nil {
|
||||
writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||
return
|
||||
}
|
||||
object := trimLeadingSlash(formValues.Get("Key"))
|
||||
|
||||
successRedirect := formValues.Get("success_action_redirect")
|
||||
successStatus := formValues.Get("success_action_status")
|
||||
|
26
cmd/utils.go
26
cmd/utils.go
@ -687,6 +687,20 @@ func ceilFrac(numerator, denominator int64) (ceil int64) {
|
||||
return
|
||||
}
|
||||
|
||||
func trimLeadingSlash(ep string) string {
|
||||
if len(ep) > 0 && ep[0] == '/' {
|
||||
// Path ends with '/' preserve it
|
||||
if ep[len(ep)-1] == '/' && len(ep) > 1 {
|
||||
ep = path.Clean(ep)
|
||||
ep += slashSeparator
|
||||
} else {
|
||||
ep = path.Clean(ep)
|
||||
}
|
||||
ep = ep[1:]
|
||||
}
|
||||
return ep
|
||||
}
|
||||
|
||||
// unescapeGeneric is similar to url.PathUnescape or url.QueryUnescape
|
||||
// depending on input, additionally also handles situations such as
|
||||
// `//` are normalized as `/`, also removes any `/` prefix before
|
||||
@ -696,17 +710,7 @@ func unescapeGeneric(p string, escapeFn func(string) (string, error)) (string, e
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(ep) > 0 && ep[0] == '/' {
|
||||
// Path ends with '/' preserve it
|
||||
if ep[len(ep)-1] == '/' {
|
||||
ep = path.Clean(ep)
|
||||
ep += slashSeparator
|
||||
} else {
|
||||
ep = path.Clean(ep)
|
||||
}
|
||||
ep = ep[1:]
|
||||
}
|
||||
return ep, nil
|
||||
return trimLeadingSlash(ep), nil
|
||||
}
|
||||
|
||||
// unescapePath is similar to unescapeGeneric but for specifically
|
||||
|
Loading…
Reference in New Issue
Block a user