diff options
| author | Chris Lu <chrislusf@users.noreply.github.com> | 2025-12-12 23:21:51 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-12-12 23:21:51 -0800 |
| commit | 72853a3bbfce27c55e6c316ee446ad35e6786260 (patch) | |
| tree | 91d272c6022f0557e89d2e4058c5b6b7ccad3b4e /weed | |
| parent | 662a6ac8ee45caede35b82f4c5527cc30c0de0c2 (diff) | |
| download | seaweedfs-72853a3bbfce27c55e6c316ee446ad35e6786260.tar.xz seaweedfs-72853a3bbfce27c55e6c316ee446ad35e6786260.zip | |
fix: prevent path doubling in versioned object listing (#7729)
* fix: prevent path doubling in versioned object listing
Fix path doubling bug in getLatestVersionEntryForListOperation that caused
Velero/Kopia backups to fail when using S3 bucket versioning.
The issue was that when creating logical entries for versioned object listing,
the entry.Name was set to the full object path (e.g., 'kopia/logpaste/kopia.blobcfg')
instead of just the base filename ('kopia.blobcfg'). When this entry was used in
the list callback which combines dir + entry.Name, the paths got doubled:
'/buckets/velero/kopia/logpaste/kopia/logpaste/kopia.blobcfg'
This caused Kopia to fail loading pack indexes with the error:
'unable to load pack indexes despite 10 retries'
The fix uses path.Base(object) to extract only the filename portion, matching
how regular (non-versioned) entries work in the listing callback.
Fixes: GitHub discussion #7573
* refactor: use path.Base directly in test instead of reimplementing
Address code review feedback to simplify the test by using the standard
library path.Base function directly instead of reimplementing it.
* remove test: unit test for path.Base doesn't add much value
Diffstat (limited to 'weed')
| -rw-r--r-- | weed/s3api/s3api_object_handlers_list.go | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/weed/s3api/s3api_object_handlers_list.go b/weed/s3api/s3api_object_handlers_list.go index a4e844df8..4d91efeb8 100644 --- a/weed/s3api/s3api_object_handlers_list.go +++ b/weed/s3api/s3api_object_handlers_list.go @@ -7,6 +7,7 @@ import ( "io" "net/http" "net/url" + "path" "sort" "strconv" "strings" @@ -729,8 +730,10 @@ func (s3a *S3ApiServer) getLatestVersionEntryForListOperation(bucket, object str // Create a logical entry that appears to be stored at the object path (not the versioned path) // This allows the list operation to show the logical object name while preserving all metadata + // Use path.Base to get just the filename, since the entry.Name should be the local name only + // (the directory path is already included in the 'dir' parameter passed to eachEntryFn) logicalEntry := &filer_pb.Entry{ - Name: strings.TrimPrefix(object, "/"), + Name: path.Base(object), IsDirectory: false, Attributes: latestVersionEntry.Attributes, Extended: latestVersionEntry.Extended, |
