You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@opendal.apache.org by xu...@apache.org on 2026/07/27 01:51:42 UTC
(opendal) branch main updated: fix(services/gcs): encode object paths exactly once (#7947)
This is an automated email from the ASF dual-hosted git repository.
Xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/opendal.git
The following commit(s) were added to refs/heads/main by this push:
new 7ce945d92 fix(services/gcs): encode object paths exactly once (#7947)
7ce945d92 is described below
commit 7ce945d925ac765f3d5f877451a27f48bd7b862e
Author: Xuanwo <gi...@xuanwo.io>
AuthorDate: Mon Jul 27 09:51:36 2026 +0800
fix(services/gcs): encode object paths exactly once (#7947)
---
bindings/ruby/Cargo.lock | 65 +++++++++++++------------------
core/Cargo.lock | 79 ++++++++++++++++----------------------
core/core/Cargo.toml | 2 +-
core/services/azblob/Cargo.toml | 6 +--
core/services/azdls/Cargo.toml | 6 +--
core/services/azfile/Cargo.toml | 6 +--
core/services/cos/Cargo.toml | 6 +--
core/services/gcs/Cargo.toml | 6 +--
core/services/gcs/src/core.rs | 56 ++++++++++++++++++++++++++-
core/services/gcs/src/writer.rs | 17 +++-----
core/services/ghac/Cargo.toml | 4 +-
core/services/obs/Cargo.toml | 6 +--
core/services/oss/Cargo.toml | 6 +--
core/services/s3/Cargo.toml | 6 +--
core/services/tos/Cargo.toml | 6 +--
core/tests/behavior/async_write.rs | 2 +-
16 files changed, 152 insertions(+), 127 deletions(-)
diff --git a/bindings/ruby/Cargo.lock b/bindings/ruby/Cargo.lock
index ed9a13ff7..2b72ce84d 100644
--- a/bindings/ruby/Cargo.lock
+++ b/bindings/ruby/Cargo.lock
@@ -1408,7 +1408,7 @@ dependencies = [
"md-5",
"mea",
"percent-encoding",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-core",
"serde",
"serde_json",
@@ -1495,7 +1495,7 @@ dependencies = [
"log",
"opendal-core",
"opendal-service-azure-common",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-azure-storage",
"reqsign-core",
"reqsign-file-read-tokio",
@@ -1515,7 +1515,7 @@ dependencies = [
"mea",
"opendal-core",
"opendal-service-azure-common",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-azure-storage",
"reqsign-core",
"reqsign-file-read-tokio",
@@ -1532,7 +1532,7 @@ dependencies = [
"log",
"opendal-core",
"opendal-service-azure-common",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-azure-storage",
"reqsign-core",
"reqsign-file-read-tokio",
@@ -1555,7 +1555,7 @@ dependencies = [
"http",
"log",
"opendal-core",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-core",
"reqsign-file-read-tokio",
"reqsign-tencent-cos",
@@ -1584,7 +1584,7 @@ dependencies = [
"log",
"opendal-core",
"percent-encoding",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-core",
"reqsign-file-read-tokio",
"reqsign-google",
@@ -1641,7 +1641,7 @@ dependencies = [
"http",
"log",
"opendal-core",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-core",
"reqsign-file-read-tokio",
"reqsign-huaweicloud-obs",
@@ -1656,7 +1656,7 @@ dependencies = [
"http",
"log",
"opendal-core",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-aliyun-oss",
"reqsign-core",
"reqsign-file-read-tokio",
@@ -1674,7 +1674,7 @@ dependencies = [
"log",
"md-5",
"opendal-core",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-aws-v4",
"reqsign-core",
"reqsign-file-read-tokio",
@@ -1692,7 +1692,7 @@ dependencies = [
"log",
"mea",
"opendal-core",
- "quick-xml 0.41.0",
+ "quick-xml",
"serde",
]
@@ -1915,16 +1915,6 @@ dependencies = [
"winapi",
]
-[[package]]
-name = "quick-xml"
-version = "0.40.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2474bd2e5029e7ccb6abb2ba48cf2383a333851dedf495901544281590c7da7f"
-dependencies = [
- "memchr",
- "serde",
-]
-
[[package]]
name = "quick-xml"
version = "0.41.0"
@@ -2176,9 +2166,9 @@ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
[[package]]
name = "reqsign-aliyun-oss"
-version = "3.1.0"
+version = "3.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "372266b4733756738eeb199a98188037d27a0989980e2600ae7ce1faf00a867d"
+checksum = "9c0f9f69a519dd6958c4b43606bb8e1278cdc76d611fc8fed4b796eee548dc0f"
dependencies = [
"anyhow",
"form_urlencoded",
@@ -2193,9 +2183,9 @@ dependencies = [
[[package]]
name = "reqsign-aws-v4"
-version = "3.0.1"
+version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b75624bd8a466e37ddc0a7b6c33ac859a85347c153a916e1dd9d0b68338f74a"
+checksum = "cc883bc56889f3e4a419265c87facea222a921debc5c6f15c7fd8b68ec4b36b2"
dependencies = [
"anyhow",
"bytes",
@@ -2204,7 +2194,7 @@ dependencies = [
"http",
"log",
"percent-encoding",
- "quick-xml 0.40.1",
+ "quick-xml",
"reqsign-core",
"rust-ini",
"serde",
@@ -2215,9 +2205,9 @@ dependencies = [
[[package]]
name = "reqsign-azure-storage"
-version = "3.0.1"
+version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b96928e73ad984de1d99e382749d09e5dab7dd707b767974f7e40aa926b82f"
+checksum = "a6ebd8524185ce9c64063e3095f83968acfa90922f00c601a4a0f3aca15b077e"
dependencies = [
"anyhow",
"base64",
@@ -2236,14 +2226,13 @@ dependencies = [
[[package]]
name = "reqsign-core"
-version = "3.0.1"
+version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5fa5cb48808693614d1701fcd3db0b30fa292e0f18e122ae068b6d32eaeed3f"
+checksum = "7e38b44697c60a823705ccef85cb04d8e0527c9d16ed7c58bf1c6395bdd24ceb"
dependencies = [
"anyhow",
"base64",
"bytes",
- "form_urlencoded",
"futures",
"hex",
"hmac 0.13.0",
@@ -2261,9 +2250,9 @@ dependencies = [
[[package]]
name = "reqsign-file-read-tokio"
-version = "3.0.1"
+version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a4b6f3a3fd29ffcc99a90aec585a65217783badfd73acddf847b63ae683bda9"
+checksum = "688ff0ae421b8d4b92b53fdafaf53df2de28f428a9962edcf21702990b26f74b"
dependencies = [
"anyhow",
"reqsign-core",
@@ -2272,9 +2261,9 @@ dependencies = [
[[package]]
name = "reqsign-google"
-version = "3.0.1"
+version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb215d0876a18b6bd9cdd380b589e5292aaa638ca15266de794b1122d898b6b2"
+checksum = "a96da0b579b846d358090cb06b9e3c2ad1375529efbe3e0c45f96bd7bcf043ea"
dependencies = [
"form_urlencoded",
"http",
@@ -2290,9 +2279,9 @@ dependencies = [
[[package]]
name = "reqsign-huaweicloud-obs"
-version = "3.0.1"
+version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1136b31eb7202016d8bbb9445bc3e9ee81e7040736f0dae749a8b2b31d738c9"
+checksum = "3f2c702fcce7067977f4a00d34d7ec2517fea75a80698b6cd5b352a903553773"
dependencies = [
"anyhow",
"http",
@@ -2303,9 +2292,9 @@ dependencies = [
[[package]]
name = "reqsign-tencent-cos"
-version = "3.0.1"
+version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84110aabba799fbcd48b3abb51fbbff4749f879252e5806b6f5d0cbe0fef6abb"
+checksum = "f6497dd9f6e3d1349b420521484099b284f95e8d3a65f088fccef42493a7b644"
dependencies = [
"anyhow",
"http",
diff --git a/core/Cargo.lock b/core/Cargo.lock
index 4ba9be1a5..dd5fef7dc 100644
--- a/core/Cargo.lock
+++ b/core/Cargo.lock
@@ -6443,7 +6443,7 @@ dependencies = [
"mea",
"percent-encoding",
"pretty_assertions",
- "quick-xml 0.41.0",
+ "quick-xml",
"rand 0.10.1",
"reqsign-core",
"serde",
@@ -6805,7 +6805,7 @@ dependencies = [
"opendal-core",
"opendal-service-azure-common",
"pretty_assertions",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-azure-storage",
"reqsign-core",
"reqsign-file-read-tokio",
@@ -6827,7 +6827,7 @@ dependencies = [
"mea",
"opendal-core",
"opendal-service-azure-common",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-azure-storage",
"reqsign-core",
"reqsign-file-read-tokio",
@@ -6845,7 +6845,7 @@ dependencies = [
"log",
"opendal-core",
"opendal-service-azure-common",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-azure-storage",
"reqsign-core",
"reqsign-file-read-tokio",
@@ -6916,7 +6916,7 @@ dependencies = [
"http 1.4.2",
"log",
"opendal-core",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-core",
"reqsign-file-read-tokio",
"reqsign-tencent-cos",
@@ -7049,7 +7049,7 @@ dependencies = [
"log",
"opendal-core",
"percent-encoding",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-core",
"reqsign-file-read-tokio",
"reqsign-google",
@@ -7313,7 +7313,7 @@ dependencies = [
"http 1.4.2",
"log",
"opendal-core",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-core",
"reqsign-file-read-tokio",
"reqsign-huaweicloud-obs",
@@ -7358,7 +7358,7 @@ dependencies = [
"log",
"opendal-core",
"pretty_assertions",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-aliyun-oss",
"reqsign-core",
"reqsign-file-read-tokio",
@@ -7445,7 +7445,7 @@ dependencies = [
"md-5 0.11.0",
"opendal-core",
"pretty_assertions",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-aws-v4",
"reqsign-core",
"reqsign-file-read-tokio",
@@ -7528,7 +7528,7 @@ dependencies = [
"log",
"opendal-core",
"percent-encoding",
- "quick-xml 0.41.0",
+ "quick-xml",
"serde",
"serde_json",
"sha1 0.11.0",
@@ -7555,7 +7555,7 @@ dependencies = [
"bytes",
"http 1.4.2",
"opendal-core",
- "quick-xml 0.41.0",
+ "quick-xml",
"reqsign-core",
"reqsign-file-read-tokio",
"reqsign-volcengine-tos",
@@ -7574,7 +7574,7 @@ dependencies = [
"log",
"md-5 0.11.0",
"opendal-core",
- "quick-xml 0.41.0",
+ "quick-xml",
"serde",
"serde_json",
"sha1 0.11.0",
@@ -7603,7 +7603,7 @@ dependencies = [
"http 1.4.2",
"log",
"opendal-core",
- "quick-xml 0.41.0",
+ "quick-xml",
"serde",
"serde_json",
"tokio",
@@ -7619,7 +7619,7 @@ dependencies = [
"log",
"mea",
"opendal-core",
- "quick-xml 0.41.0",
+ "quick-xml",
"serde",
"tokio",
]
@@ -7648,7 +7648,7 @@ dependencies = [
"http 1.4.2",
"log",
"opendal-core",
- "quick-xml 0.41.0",
+ "quick-xml",
"serde",
"serde_json",
"tokio",
@@ -8718,16 +8718,6 @@ dependencies = [
"winapi",
]
-[[package]]
-name = "quick-xml"
-version = "0.40.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2474bd2e5029e7ccb6abb2ba48cf2383a333851dedf495901544281590c7da7f"
-dependencies = [
- "memchr",
- "serde",
-]
-
[[package]]
name = "quick-xml"
version = "0.41.0"
@@ -9160,9 +9150,9 @@ dependencies = [
[[package]]
name = "reqsign-aliyun-oss"
-version = "3.1.0"
+version = "3.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "372266b4733756738eeb199a98188037d27a0989980e2600ae7ce1faf00a867d"
+checksum = "9c0f9f69a519dd6958c4b43606bb8e1278cdc76d611fc8fed4b796eee548dc0f"
dependencies = [
"anyhow",
"form_urlencoded",
@@ -9177,9 +9167,9 @@ dependencies = [
[[package]]
name = "reqsign-aws-v4"
-version = "3.0.1"
+version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b75624bd8a466e37ddc0a7b6c33ac859a85347c153a916e1dd9d0b68338f74a"
+checksum = "cc883bc56889f3e4a419265c87facea222a921debc5c6f15c7fd8b68ec4b36b2"
dependencies = [
"anyhow",
"bytes",
@@ -9188,7 +9178,7 @@ dependencies = [
"http 1.4.2",
"log",
"percent-encoding",
- "quick-xml 0.40.1",
+ "quick-xml",
"reqsign-core",
"rust-ini",
"serde",
@@ -9199,9 +9189,9 @@ dependencies = [
[[package]]
name = "reqsign-azure-storage"
-version = "3.0.1"
+version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b96928e73ad984de1d99e382749d09e5dab7dd707b767974f7e40aa926b82f"
+checksum = "a6ebd8524185ce9c64063e3095f83968acfa90922f00c601a4a0f3aca15b077e"
dependencies = [
"anyhow",
"base64 0.22.1",
@@ -9220,14 +9210,13 @@ dependencies = [
[[package]]
name = "reqsign-core"
-version = "3.0.1"
+version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5fa5cb48808693614d1701fcd3db0b30fa292e0f18e122ae068b6d32eaeed3f"
+checksum = "7e38b44697c60a823705ccef85cb04d8e0527c9d16ed7c58bf1c6395bdd24ceb"
dependencies = [
"anyhow",
"base64 0.22.1",
"bytes",
- "form_urlencoded",
"futures",
"hex",
"hmac 0.13.0",
@@ -9245,9 +9234,9 @@ dependencies = [
[[package]]
name = "reqsign-file-read-tokio"
-version = "3.0.1"
+version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a4b6f3a3fd29ffcc99a90aec585a65217783badfd73acddf847b63ae683bda9"
+checksum = "688ff0ae421b8d4b92b53fdafaf53df2de28f428a9962edcf21702990b26f74b"
dependencies = [
"anyhow",
"reqsign-core",
@@ -9256,9 +9245,9 @@ dependencies = [
[[package]]
name = "reqsign-google"
-version = "3.0.1"
+version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb215d0876a18b6bd9cdd380b589e5292aaa638ca15266de794b1122d898b6b2"
+checksum = "a96da0b579b846d358090cb06b9e3c2ad1375529efbe3e0c45f96bd7bcf043ea"
dependencies = [
"form_urlencoded",
"http 1.4.2",
@@ -9274,9 +9263,9 @@ dependencies = [
[[package]]
name = "reqsign-huaweicloud-obs"
-version = "3.0.1"
+version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1136b31eb7202016d8bbb9445bc3e9ee81e7040736f0dae749a8b2b31d738c9"
+checksum = "3f2c702fcce7067977f4a00d34d7ec2517fea75a80698b6cd5b352a903553773"
dependencies = [
"anyhow",
"http 1.4.2",
@@ -9287,9 +9276,9 @@ dependencies = [
[[package]]
name = "reqsign-tencent-cos"
-version = "3.0.1"
+version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84110aabba799fbcd48b3abb51fbbff4749f879252e5806b6f5d0cbe0fef6abb"
+checksum = "f6497dd9f6e3d1349b420521484099b284f95e8d3a65f088fccef42493a7b644"
dependencies = [
"anyhow",
"http 1.4.2",
@@ -9302,9 +9291,9 @@ dependencies = [
[[package]]
name = "reqsign-volcengine-tos"
-version = "3.0.1"
+version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91d083a363b3577f519ce8425bb50f902622a28a83f7c4a26a5c990b66ec75b3"
+checksum = "4335f949a3fd8b53867fd716dac97fbd545e45bcaed44343796517f2e19cd609"
dependencies = [
"anyhow",
"http 1.4.2",
diff --git a/core/core/Cargo.toml b/core/core/Cargo.toml
index 0eeea1b6f..02a9338e3 100644
--- a/core/core/Cargo.toml
+++ b/core/core/Cargo.toml
@@ -76,7 +76,7 @@ md-5 = "0.11.0"
mea = { workspace = true }
percent-encoding = "2"
quick-xml = { workspace = true, features = ["serialize", "overlapped-lists"] }
-reqsign-core = { version = "3.0.1", default-features = false, optional = true }
+reqsign-core = { version = "3.2.0", default-features = false, optional = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
tokio = { workspace = true, features = ["macros", "io-util"] }
diff --git a/core/services/azblob/Cargo.toml b/core/services/azblob/Cargo.toml
index 1655f9eb6..287761ac0 100644
--- a/core/services/azblob/Cargo.toml
+++ b/core/services/azblob/Cargo.toml
@@ -40,9 +40,9 @@ opendal-core = { path = "../../core", version = "0.58.1", default-features = fal
] }
opendal-service-azure-common = { path = "../azure-common", version = "0.58.1" }
quick-xml = { workspace = true, features = ["serialize", "overlapped-lists"] }
-reqsign-azure-storage = { version = "3.0.1", default-features = false }
-reqsign-core = { version = "3.0.1", default-features = false }
-reqsign-file-read-tokio = { version = "3.0.1", default-features = false }
+reqsign-azure-storage = { version = "3.1.1", default-features = false }
+reqsign-core = { version = "3.2.0", default-features = false }
+reqsign-file-read-tokio = { version = "3.0.3", default-features = false }
serde = { workspace = true, features = ["derive"] }
sha2 = { workspace = true }
uuid = { workspace = true, features = ["v4", "serde"] }
diff --git a/core/services/azdls/Cargo.toml b/core/services/azdls/Cargo.toml
index e04627a97..32cfe544e 100644
--- a/core/services/azdls/Cargo.toml
+++ b/core/services/azdls/Cargo.toml
@@ -41,9 +41,9 @@ opendal-core = { path = "../../core", version = "0.58.1", default-features = fal
] }
opendal-service-azure-common = { path = "../azure-common", version = "0.58.1" }
quick-xml = { workspace = true, features = ["serialize", "overlapped-lists"] }
-reqsign-azure-storage = { version = "3.0.1", default-features = false }
-reqsign-core = { version = "3.0.1", default-features = false }
-reqsign-file-read-tokio = { version = "3.0.1", default-features = false }
+reqsign-azure-storage = { version = "3.1.1", default-features = false }
+reqsign-core = { version = "3.2.0", default-features = false }
+reqsign-file-read-tokio = { version = "3.0.3", default-features = false }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
diff --git a/core/services/azfile/Cargo.toml b/core/services/azfile/Cargo.toml
index 93d3ed867..34f92e0fc 100644
--- a/core/services/azfile/Cargo.toml
+++ b/core/services/azfile/Cargo.toml
@@ -39,9 +39,9 @@ opendal-core = { path = "../../core", version = "0.58.1", default-features = fal
] }
opendal-service-azure-common = { path = "../azure-common", version = "0.58.1" }
quick-xml = { workspace = true, features = ["serialize", "overlapped-lists"] }
-reqsign-azure-storage = { version = "3.0.1", default-features = false }
-reqsign-core = { version = "3.0.1", default-features = false }
-reqsign-file-read-tokio = { version = "3.0.1", default-features = false }
+reqsign-azure-storage = { version = "3.1.1", default-features = false }
+reqsign-core = { version = "3.2.0", default-features = false }
+reqsign-file-read-tokio = { version = "3.0.3", default-features = false }
serde = { workspace = true, features = ["derive"] }
[dev-dependencies]
diff --git a/core/services/cos/Cargo.toml b/core/services/cos/Cargo.toml
index 9ba1ffad4..503375347 100644
--- a/core/services/cos/Cargo.toml
+++ b/core/services/cos/Cargo.toml
@@ -38,9 +38,9 @@ opendal-core = { path = "../../core", version = "0.58.1", default-features = fal
"reqsign",
] }
quick-xml = { workspace = true, features = ["serialize", "overlapped-lists"] }
-reqsign-core = { version = "3.0.1", default-features = false }
-reqsign-file-read-tokio = { version = "3.0.1", default-features = false }
-reqsign-tencent-cos = { version = "3.0.1", default-features = false }
+reqsign-core = { version = "3.2.0", default-features = false }
+reqsign-file-read-tokio = { version = "3.0.3", default-features = false }
+reqsign-tencent-cos = { version = "3.0.3", default-features = false }
serde = { workspace = true, features = ["derive"] }
[dev-dependencies]
diff --git a/core/services/gcs/Cargo.toml b/core/services/gcs/Cargo.toml
index bcc4e6808..69e9eb1c6 100644
--- a/core/services/gcs/Cargo.toml
+++ b/core/services/gcs/Cargo.toml
@@ -40,9 +40,9 @@ opendal-core = { path = "../../core", version = "0.58.1", default-features = fal
] }
percent-encoding = "2.3"
quick-xml = { workspace = true, features = ["serialize"] }
-reqsign-core = { version = "3.0.1", default-features = false }
-reqsign-file-read-tokio = { version = "3.0.1", default-features = false }
-reqsign-google = { version = "3.0.1", default-features = false }
+reqsign-core = { version = "3.2.0", default-features = false }
+reqsign-file-read-tokio = { version = "3.0.3", default-features = false }
+reqsign-google = { version = "3.0.3", default-features = false }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
tokio = { workspace = true, features = ["rt"] }
diff --git a/core/services/gcs/src/core.rs b/core/services/gcs/src/core.rs
index 80eab2090..5faf9ac04 100644
--- a/core/services/gcs/src/core.rs
+++ b/core/services/gcs/src/core.rs
@@ -605,7 +605,12 @@ impl GcsCore {
) -> Result<Response<Buffer>> {
let p = build_abs_path(&self.root, path);
- let url = format!("{}/{}/{}?uploads", self.endpoint, self.bucket, p);
+ let url = format!(
+ "{}/{}/{}?uploads",
+ self.endpoint,
+ self.bucket,
+ gcs_percent_encode_path(&p)
+ );
let mut builder = Request::post(&url)
.header(CONTENT_LENGTH, 0)
@@ -951,6 +956,55 @@ struct GetObjectJsonResponse {
#[cfg(test)]
mod tests {
use super::*;
+ use reqsign_core::ProvideCredentialChain;
+ use reqsign_google::RequestSigner;
+ use reqsign_google::TokenCredentialProvider;
+
+ #[tokio::test]
+ async fn test_insert_object_signing_preserves_wire_uri() {
+ let sign_ctx = Context::new();
+ let signer = Signer::new(
+ sign_ctx.clone(),
+ ProvideCredentialChain::new().push(TokenCredentialProvider::new("test-token")),
+ RequestSigner::new("storage"),
+ );
+
+ let core = GcsCore {
+ info: ServiceInfo::new("gcs", "/", "test-bucket"),
+ capability: Capability::default(),
+ endpoint: "https://storage.googleapis.com".to_string(),
+ bucket: "test-bucket".to_string(),
+ root: "/".to_string(),
+ signer,
+ sign_ctx,
+ predefined_acl: None,
+ default_storage_class: None,
+ skip_signature: false,
+ };
+ let req = core
+ .gcs_insert_object_request(
+ "nested/object #1.txt",
+ Some(0),
+ &OpWrite::default(),
+ Buffer::new(),
+ )
+ .expect("request must build");
+ let original_uri = req.uri().clone();
+
+ assert!(
+ original_uri
+ .to_string()
+ .contains("nested%2Fobject%20%231.txt")
+ );
+ assert!(!original_uri.to_string().contains("%252F"));
+
+ let signed = core
+ .sign(&OperationContext::default(), req)
+ .await
+ .expect("request must sign");
+
+ assert_eq!(signed.uri(), &original_uri);
+ }
#[test]
fn test_deserialize_get_object_json_response() {
diff --git a/core/services/gcs/src/writer.rs b/core/services/gcs/src/writer.rs
index 769c0fbbe..9e50e3b9e 100644
--- a/core/services/gcs/src/writer.rs
+++ b/core/services/gcs/src/writer.rs
@@ -23,7 +23,6 @@ use http::StatusCode;
use super::core::CompleteMultipartUploadRequestPart;
use super::core::GcsCore;
use super::core::InitiateMultipartUploadResult;
-use super::core::gcs_percent_encode_path;
use super::core::parse_error;
use opendal_core::raw::*;
use opendal_core::*;
@@ -51,12 +50,10 @@ impl GcsWriter {
impl oio::MultipartWrite for GcsWriter {
async fn write_once(&self, _: u64, body: Buffer) -> Result<Metadata> {
let size = body.len() as u64;
- let req = self.core.gcs_insert_object_request(
- &gcs_percent_encode_path(&self.path),
- Some(size),
- &self.op,
- body,
- )?;
+ // Request builders own percent-encoding; writers pass logical paths unchanged.
+ let req = self
+ .core
+ .gcs_insert_object_request(&self.path, Some(size), &self.op, body)?;
let req = self.core.sign(&self.ctx, req).await?;
@@ -77,11 +74,7 @@ impl oio::MultipartWrite for GcsWriter {
async fn initiate_part(&self) -> Result<String> {
let resp = self
.core
- .gcs_initiate_multipart_upload(
- &self.ctx,
- &gcs_percent_encode_path(&self.path),
- &self.op,
- )
+ .gcs_initiate_multipart_upload(&self.ctx, &self.path, &self.op)
.await?;
if !resp.status().is_success() {
diff --git a/core/services/ghac/Cargo.toml b/core/services/ghac/Cargo.toml
index 9e4689dd3..8db69cfb5 100644
--- a/core/services/ghac/Cargo.toml
+++ b/core/services/ghac/Cargo.toml
@@ -38,8 +38,8 @@ log = { workspace = true }
opendal-core = { path = "../../core", version = "0.58.1", default-features = false }
opendal-service-azblob = { path = "../azblob", version = "0.58.1", default-features = false }
prost = { version = "0.14.3", default-features = false }
-reqsign-azure-storage = { version = "3.0.1", default-features = false }
-reqsign-core = { version = "3.0.1", default-features = false }
+reqsign-azure-storage = { version = "3.1.1", default-features = false }
+reqsign-core = { version = "3.2.0", default-features = false }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sha2 = { workspace = true }
diff --git a/core/services/obs/Cargo.toml b/core/services/obs/Cargo.toml
index 95bce7163..de031efca 100644
--- a/core/services/obs/Cargo.toml
+++ b/core/services/obs/Cargo.toml
@@ -38,9 +38,9 @@ opendal-core = { path = "../../core", version = "0.58.1", default-features = fal
"reqsign",
] }
quick-xml = { workspace = true, features = ["serialize", "overlapped-lists"] }
-reqsign-core = "3.0.1"
-reqsign-file-read-tokio = "3.0.1"
-reqsign-huaweicloud-obs = "3.0.1"
+reqsign-core = "3.2.0"
+reqsign-file-read-tokio = "3.0.3"
+reqsign-huaweicloud-obs = "3.0.3"
serde = { workspace = true, features = ["derive"] }
[dev-dependencies]
diff --git a/core/services/oss/Cargo.toml b/core/services/oss/Cargo.toml
index 3553fa4d5..3a1101432 100644
--- a/core/services/oss/Cargo.toml
+++ b/core/services/oss/Cargo.toml
@@ -38,9 +38,9 @@ opendal-core = { path = "../../core", version = "0.58.1", default-features = fal
"reqsign",
] }
quick-xml = { workspace = true, features = ["serialize", "overlapped-lists"] }
-reqsign-aliyun-oss = { version = "3.1.0", default-features = false }
-reqsign-core = { version = "3.0.1", default-features = false }
-reqsign-file-read-tokio = { version = "3.0.1", default-features = false }
+reqsign-aliyun-oss = { version = "3.1.2", default-features = false }
+reqsign-core = { version = "3.2.0", default-features = false }
+reqsign-file-read-tokio = { version = "3.0.3", default-features = false }
serde = { workspace = true, features = ["derive"] }
[dev-dependencies]
diff --git a/core/services/s3/Cargo.toml b/core/services/s3/Cargo.toml
index f867d69ae..f3c3287e4 100644
--- a/core/services/s3/Cargo.toml
+++ b/core/services/s3/Cargo.toml
@@ -41,9 +41,9 @@ opendal-core = { path = "../../core", version = "0.58.1", default-features = fal
"reqsign",
] }
quick-xml = { workspace = true, features = ["serialize", "overlapped-lists"] }
-reqsign-aws-v4 = { version = "3.0.0", default-features = false }
-reqsign-core = { version = "3.0.1", default-features = false }
-reqsign-file-read-tokio = { version = "3.0.1", default-features = false }
+reqsign-aws-v4 = { version = "3.0.3", default-features = false }
+reqsign-core = { version = "3.2.0", default-features = false }
+reqsign-file-read-tokio = { version = "3.0.3", default-features = false }
serde = { workspace = true, features = ["derive"] }
url = { workspace = true }
diff --git a/core/services/tos/Cargo.toml b/core/services/tos/Cargo.toml
index 44db9babf..460eceda7 100644
--- a/core/services/tos/Cargo.toml
+++ b/core/services/tos/Cargo.toml
@@ -37,8 +37,8 @@ opendal-core = { path = "../../core", version = "0.58.1", default-features = fal
"reqsign",
] }
quick-xml = { workspace = true, features = ["serialize", "overlapped-lists"] }
-reqsign-core = { version = "3.0.1", default-features = false }
-reqsign-file-read-tokio = { version = "3.0.1", default-features = false }
-reqsign-volcengine-tos = "3.0.1"
+reqsign-core = { version = "3.2.0", default-features = false }
+reqsign-file-read-tokio = { version = "3.0.3", default-features = false }
+reqsign-volcengine-tos = "3.0.3"
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
diff --git a/core/tests/behavior/async_write.rs b/core/tests/behavior/async_write.rs
index d3b5b05e7..d7a88cbad 100644
--- a/core/tests/behavior/async_write.rs
+++ b/core/tests/behavior/async_write.rs
@@ -119,7 +119,7 @@ pub async fn test_write_with_special_chars(op: Operator) -> Result<()> {
return Ok(());
}
- let path = format!("{} !@#$%^&()_+-=;',.txt", uuid::Uuid::new_v4());
+ let path = format!("nested/{} !@#$%^&()_+-=;',.txt", uuid::Uuid::new_v4());
let (path, content, size) = TEST_FIXTURE.new_file_with_path(op.clone(), &path);
op.write(&path, content).await?;