Skip to content

Commit e3afe6c

Browse files
committed
fix: handle trailing slash in URLs.
1 parent d30ac48 commit e3afe6c

4 files changed

Lines changed: 27 additions & 23 deletions

File tree

src/backend/azure.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,9 @@ impl StorageBackend for AzureBlobStorageBackend {
618618
}
619619

620620
// The prefix should end with `/` to signify a directory.
621-
prefix.push('/');
621+
if !prefix.ends_with('/') {
622+
prefix.push('/');
623+
}
622624

623625
{
624626
// Append the operation and block id to the URL
@@ -675,10 +677,8 @@ impl StorageBackend for AzureBlobStorageBackend {
675677
}
676678

677679
paths.extend(results.blobs.items.into_iter().map(|b| {
678-
b.name
679-
.strip_prefix(&prefix)
680-
.map(Into::into)
681-
.unwrap_or(b.name)
680+
let name = b.name.strip_prefix(&prefix).unwrap_or(&b.name);
681+
name.strip_prefix('/').unwrap_or(name).into()
682682
}));
683683

684684
next = results.next.unwrap_or_default();

src/backend/google.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -677,9 +677,11 @@ impl StorageBackend for GoogleStorageBackend {
677677

678678
let (bucket, path) = url.bucket_and_path();
679679

680-
// The prefix should end with `/` to signify a directory.
681680
let mut prefix = path.strip_prefix('/').unwrap_or(path).to_string();
682-
prefix.push('/');
681+
// The prefix should end with `/` to signify a directory.
682+
if !prefix.ends_with('/') {
683+
prefix.push('/');
684+
}
683685

684686
// Format the request to always use the virtual-host style URL
685687
url.set_host(Some(&format!("{bucket}.{GOOGLE_ROOT_DOMAIN}")))
@@ -745,12 +747,10 @@ impl StorageBackend for GoogleStorageBackend {
745747
return Ok(paths);
746748
}
747749

748-
paths.extend(
749-
results
750-
.contents
751-
.into_iter()
752-
.map(|c| c.key.strip_prefix(&prefix).map(Into::into).unwrap_or(c.key)),
753-
);
750+
paths.extend(results.contents.into_iter().map(|c| {
751+
let key = c.key.strip_prefix(&prefix).unwrap_or(&c.key);
752+
key.strip_prefix('/').unwrap_or(key).into()
753+
}));
754754

755755
token = results.token.unwrap_or_default();
756756
if token.is_empty() {

src/backend/s3.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -759,9 +759,11 @@ impl StorageBackend for S3StorageBackend {
759759

760760
let (bucket, path) = url.bucket_and_path();
761761

762-
// The prefix should end with `/` to signify a directory.
763762
let mut prefix = path.strip_prefix('/').unwrap_or(path).to_string();
764-
prefix.push('/');
763+
// The prefix should end with `/` to signify a directory.
764+
if !prefix.ends_with('/') {
765+
prefix.push('/');
766+
}
765767

766768
// Format the request to always use the virtual-host style URL
767769
let domain = url.domain().expect("URL should have domain");
@@ -829,12 +831,10 @@ impl StorageBackend for S3StorageBackend {
829831
return Ok(paths);
830832
}
831833

832-
paths.extend(
833-
results
834-
.contents
835-
.into_iter()
836-
.map(|c| c.key.strip_prefix(&prefix).map(Into::into).unwrap_or(c.key)),
837-
);
834+
paths.extend(results.contents.into_iter().map(|c| {
835+
let key = c.key.strip_prefix(&prefix).unwrap_or(&c.key);
836+
key.strip_prefix('/').unwrap_or(key).into()
837+
}));
838838

839839
token = results.token.unwrap_or_default();
840840
if token.is_empty() {

tests/copy.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -749,10 +749,14 @@ async fn walk() -> Result<()> {
749749
.context("failed to upload file")?;
750750
}
751751

752-
let files = cloud_copy::walk(config.clone(), client.clone(), url)
752+
let files = cloud_copy::walk(config.clone(), client.clone(), url.clone())
753753
.await
754754
.expect("should walk");
755-
assert_eq!(files, &["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]);
755+
assert_eq!(
756+
files,
757+
&["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
758+
"unexpected walk output for URL `{url}`"
759+
);
756760
}
757761

758762
Ok(())

0 commit comments

Comments
 (0)