fix(signer): address post-merge review comments (#3216)

* fix: address PR #3150 review comments

- Restore get_host_addr as best-effort wrapper (String return type)
- Replace bare expect("err") with descriptive messages in unsigned trailer
- Simplify aws-chunked header construction
- 20 signer + 96 io-core tests pass

* fix(signer): preserve host fallback

* fix(signer): avoid signer fallback panics

---------

Co-authored-by: houseme <housemecn@gmail.com>
This commit is contained in:
安正超
2026-06-05 06:45:50 +08:00
committed by GitHub
parent d6120f5788
commit 1dd3839a9f
2 changed files with 70 additions and 18 deletions
+34 -14
View File
@@ -26,14 +26,7 @@ pub enum HostAddrError {
pub fn try_get_host_addr(req: &request::Request<Body>) -> Result<String, HostAddrError> {
let host = req.headers().get("host");
let uri = req.uri();
let uri_host = uri.host().ok_or(HostAddrError::MissingUriHost)?;
let req_host = if let Some(port) = uri.port() {
format!("{uri_host}:{port}")
} else {
uri_host.to_string()
};
let req_host = uri_host_addr(req).ok_or(HostAddrError::MissingUriHost)?;
if let Some(host) = host {
let host = host.to_str().map_err(|_| HostAddrError::InvalidHostHeader)?;
@@ -48,12 +41,24 @@ pub fn try_get_host_addr(req: &request::Request<Body>) -> Result<String, HostAdd
pub fn get_host_addr(req: &request::Request<Body>) -> String {
match try_get_host_addr(req) {
Ok(host) => host,
Err(HostAddrError::MissingUriHost) => match req.headers().get("host").map(|host| host.to_str()) {
Some(Ok(host)) => host.to_string(),
Some(Err(_)) => panic!("failed to resolve request host: invalid UTF-8 header value for `host`"),
None => panic!("failed to resolve request host: request uri has no host"),
},
Err(err) => panic!("failed to resolve request host: {err}"),
Err(HostAddrError::MissingUriHost) => req
.headers()
.get("host")
.and_then(|host| host.to_str().ok())
.unwrap_or_default()
.to_string(),
Err(HostAddrError::InvalidHostHeader) => uri_host_addr(req).unwrap_or_default(),
}
}
fn uri_host_addr(req: &request::Request<Body>) -> Option<String> {
let uri = req.uri();
let uri_host = uri.host()?;
if let Some(port) = uri.port() {
Some(format!("{uri_host}:{port}"))
} else {
Some(uri_host.to_string())
}
}
@@ -132,6 +137,21 @@ mod tests {
assert!(matches!(err, HostAddrError::InvalidHostHeader));
}
#[test]
fn get_host_addr_uses_uri_host_when_host_header_is_non_utf8() {
let mut req = request::Request::builder()
.method(http::Method::GET)
.uri("https://bucket.example.com:9443/object")
.body(Body::empty())
.expect("request should build");
req.headers_mut().insert(
"host",
HeaderValue::from_bytes(&[0xFF]).expect("invalid utf8 bytes should be accepted by HeaderValue"),
);
assert_eq!(get_host_addr(&req), "bucket.example.com:9443");
}
#[test]
fn try_get_host_addr_rejects_relative_uri_without_host() {
let req = request::Request::builder()