From 4efaea60bbbd2dbc3f5c3708105961b9deb4dac0 Mon Sep 17 00:00:00 2001 From: Gwen Lg Date: Tue, 10 Mar 2026 17:11:42 +0100 Subject: [PATCH] tests: check request signatures with 'badly-encoded' uri test related to issue #1155 and #1255 --- src/garage/tests/s3/mod.rs | 1 + src/garage/tests/s3/signature_encoding.rs | 72 +++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 src/garage/tests/s3/signature_encoding.rs diff --git a/src/garage/tests/s3/mod.rs b/src/garage/tests/s3/mod.rs index e75b1397..fa081389 100644 --- a/src/garage/tests/s3/mod.rs +++ b/src/garage/tests/s3/mod.rs @@ -2,6 +2,7 @@ mod list; mod multipart; mod objects; mod presigned; +mod signature_encoding; mod simple; mod ssec; mod streaming_signature; diff --git a/src/garage/tests/s3/signature_encoding.rs b/src/garage/tests/s3/signature_encoding.rs new file mode 100644 index 00000000..6fbb4078 --- /dev/null +++ b/src/garage/tests/s3/signature_encoding.rs @@ -0,0 +1,72 @@ +use crate::common; + +use aws_sdk_s3::presigning::PresigningConfig; +use bytes::Bytes; +use http::{Request, StatusCode}; +use http_body_util::Full; +use std::time::Duration; + +#[tokio::test] +async fn test_signature_encoding() { + let ctx = common::context(); + let bucket = ctx.create_bucket("signature-encoding"); + + let obj_key = "key@good~.txt"; + let obj_content = "hello world of special characters"; + + let _put_obj_info = ctx + .client + .put_object() + .bucket(&bucket) + .key(obj_key) + .body(obj_content.as_bytes().to_vec().into()) + .send() + .await + .expect("failed to put object"); + + let _get_obj = ctx + .client + .get_object() + .bucket(&bucket) + .key(obj_key) + .send() + .await + .expect("failed to get object"); + + let presign_config = PresigningConfig::builder() + .expires_in(Duration::from_secs(10)) + .build() + .expect("failed to build presigning config"); + let presigned_request = ctx + .client + .get_object() + .bucket(&bucket) + .key(obj_key) + .presigned(presign_config) + .await + .expect("failed to construct presigned request"); + + let altered_url = presigned_request + .uri() + .replace("%40", "@") + .replace("~", "%7E"); + + let client = ctx.custom_request.client(); + let req_builder = Request::builder() + .method(presigned_request.method()) + .uri(altered_url); + let req = presigned_request + .headers() + .fold(req_builder, |req_builder, (key, value)| { + req_builder.header(key, value) + }) + .body(Full::new(Bytes::new())) + .expect("failed to construct request from presigned_request"); + + let res = client + .request(req) + .await + .expect("failed to execute presigned request"); + + assert_eq!(res.status(), StatusCode::OK); +}