fix: accept upload-id-marker together with key-marker in ListMultipartUploads
The posix and azure backends dropped every upload with a key equal to the key-marker before handing the list to the lister, which then looked for the upload-id-marker under the next key. An upload-id-marker that belongs to the key-marker could never be found, so the request failed with "Invalid uploadId marker", including when a client paged with the NextKeyMarker and NextUploadIdMarker the gateway returned. Keep the uploads of the key-marker itself when an upload-id-marker is set, so the listing continues right after the given upload, as S3 does. Enable the REST test that covers it. Fixes #2149
This commit is contained in:
1 parent
f81c6a5acb
commit
cbe870a618
6 files changed
+55
-11
No files matched your search
@@ -1760,7 +1760,7 @@ func (az *Azure) ListMultipartUploads(ctx context.Context, input *s3.ListMultipa
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if keyMarker != "" && *key <= keyMarker {
|
||||
if keyMarker != "" && (*key < keyMarker || (*key == keyMarker && uploadIDMarker == "")) {
|
||||
continue
|
||||
}
|
||||
if prefix != "" && !strings.HasPrefix(*key, prefix) {
|
||||
|
||||
@@ -42,7 +42,8 @@ func ListMultipartUploads(uploads []s3response.Upload, prefix, delimiter, keyMar
|
||||
// Assumptions about input Uploads:
|
||||
// - Sorted by (Key asc, Initiated asc)
|
||||
// - Filtered by Prefix
|
||||
// - Filtered to start strictly after key-marker when key-marker was provided.
|
||||
// - Filtered to start strictly after key-marker when key-marker was provided,
|
||||
// or at key-marker when upload-id-marker was provided as well.
|
||||
type MultipartUploadLister struct {
|
||||
Uploads []s3response.Upload
|
||||
Prefix string
|
||||
@@ -148,13 +149,13 @@ func (l *MultipartUploadLister) Run() (*ListMultipartUploadsPage, error) {
|
||||
}
|
||||
|
||||
// findUploadIdMarkerIndex finds the index of given uploadId marker in uploads
|
||||
// uploadIDMarker must match an upload-id among uploads with the first key after KeyMarker.
|
||||
// Since caller filtered to Key > KeyMarker and the list is sorted by key/time,
|
||||
// the first key after KeyMarker is Uploads[0].Key (if any).
|
||||
// uploadIDMarker must match an upload-id among uploads with the first key at or after KeyMarker.
|
||||
// Since caller filtered to Key >= KeyMarker and the list is sorted by key/time,
|
||||
// the first key at or after KeyMarker is Uploads[0].Key (if any).
|
||||
// -1 is returned if no uploadId is found
|
||||
func (l *MultipartUploadLister) findUploadIdMarkerIndex(uploadIDMarker string) int {
|
||||
if len(l.Uploads) == 0 {
|
||||
// key-marker provided but nothing after it => upload-id-marker can never be valid.
|
||||
// key-marker provided but nothing at or after it => upload-id-marker can never be valid.
|
||||
return -1
|
||||
}
|
||||
firstKey := l.Uploads[0].Key
|
||||
|
||||
@@ -3472,8 +3472,9 @@ func (p *Posix) ListMultipartUploads(ctx context.Context, mpu *s3.ListMultipartU
|
||||
if prefix != "" && !strings.HasPrefix(objectName, prefix) {
|
||||
continue
|
||||
}
|
||||
// filter by keyMarker
|
||||
if keyMarker != "" && objectName <= keyMarker {
|
||||
// filter by keyMarker, keeping the uploads of the key-marker
|
||||
// itself when an upload-id-marker is set
|
||||
if keyMarker != "" && (objectName < keyMarker || (objectName == keyMarker && uploadIDMarker == "")) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user