From 050a7d034c428b2519ef1603215f16fd983622f9 Mon Sep 17 00:00:00 2001 From: Xuanwo Date: Tue, 18 Jul 2023 15:56:44 +0800 Subject: [PATCH 1/2] feat(core/http_util): Remove sensitive header like Set-Cookie Signed-off-by: Xuanwo --- core/src/raw/http_util/error.rs | 89 +++++---------------- core/src/raw/http_util/mod.rs | 3 +- core/src/services/azblob/error.rs | 5 +- core/src/services/azdfs/error.rs | 4 +- core/src/services/cos/error.rs | 5 +- core/src/services/dropbox/error.rs | 9 +-- core/src/services/gcs/error.rs | 4 +- core/src/services/gdrive/error.rs | 7 +- core/src/services/ghac/error.rs | 7 +- core/src/services/http/error.rs | 7 +- core/src/services/ipfs/error.rs | 7 +- core/src/services/ipmfs/error.rs | 4 +- core/src/services/obs/error.rs | 4 +- core/src/services/onedrive/error.rs | 7 +- core/src/services/oss/error.rs | 4 +- core/src/services/s3/error.rs | 9 +-- core/src/services/supabase/error.rs | 4 +- core/src/services/vercel_artifacts/error.rs | 7 +- core/src/services/wasabi/error.rs | 4 +- core/src/services/webdav/error.rs | 7 +- core/src/services/webhdfs/error.rs | 4 +- 21 files changed, 95 insertions(+), 106 deletions(-) diff --git a/core/src/raw/http_util/error.rs b/core/src/raw/http_util/error.rs index 3fed55c5e093..34c416260c35 100644 --- a/core/src/raw/http_util/error.rs +++ b/core/src/raw/http_util/error.rs @@ -15,77 +15,11 @@ // specific language governing permissions and limitations // under the License. -use std::fmt::Display; -use std::fmt::Formatter; - -use anyhow::anyhow; use http::response::Parts; -use http::HeaderMap; -use http::HeaderValue; -use http::Response; -use http::StatusCode; +use http::Uri; -use super::IncomingAsyncBody; use crate::Error; use crate::ErrorKind; -use crate::Result; - -/// ErrorResponse carries HTTP status code, headers and body. -/// -/// This struct should only be used to parse error response which is small. -pub struct ErrorResponse { - parts: Parts, - body: Vec, -} - -impl ErrorResponse { - /// Get http status code - pub fn status_code(&self) -> StatusCode { - self.parts.status - } - - /// Get http headers - pub fn headers(&self) -> &HeaderMap { - &self.parts.headers - } - - /// Get http error response body content (in bytes). - pub fn body(&self) -> &[u8] { - &self.body - } -} - -impl Display for ErrorResponse { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!( - f, - "status code: {:?}, headers: {:?}, body: {:?}", - self.status_code(), - self.headers(), - String::from_utf8_lossy(self.body()) - ) - } -} - -/// parse_error_response will parse response into `ErrorResponse`. -/// -/// # NOTE -/// -/// Please only use this for parsing error response hence it will read the -/// entire body into memory. -pub async fn parse_error_response(resp: Response) -> Result { - let (parts, body) = resp.into_parts(); - let bs = body.bytes().await.map_err(|err| { - Error::new(ErrorKind::Unexpected, "reading error response") - .with_operation("http_util::parse_error_response") - .set_source(anyhow!(err)) - })?; - - Ok(ErrorResponse { - parts, - body: bs.to_vec(), - }) -} /// Create a new error happened during building request. pub fn new_request_build_error(err: http::Error) -> Error { @@ -111,3 +45,24 @@ pub fn new_request_sign_error(err: anyhow::Error) -> Error { .with_operation("reqsign::Sign") .set_source(err) } + +/// Add response context to error. +/// +/// This helper function will: +/// +/// - remove sensitive or useless headers from parts. +/// - fetch uri if parts extensions contains `Uri`. +pub fn with_error_response_context(mut err: Error, mut parts: Parts) -> Error { + if let Some(uri) = parts.extensions.get::() { + err = err.with_context("uri", uri.to_string()); + } + + // The folloing headers may contains sensitive information. + parts.headers.remove("Set-Cookie"); + parts.headers.remove("WWW-Authenticate"); + parts.headers.remove("Proxy-Authenticate"); + + err = err.with_context("response", format!("{parts:?}")); + + err +} diff --git a/core/src/raw/http_util/mod.rs b/core/src/raw/http_util/mod.rs index dc6822b88011..2d6946db7e71 100644 --- a/core/src/raw/http_util/mod.rs +++ b/core/src/raw/http_util/mod.rs @@ -51,8 +51,7 @@ mod error; pub use error::new_request_build_error; pub use error::new_request_credential_error; pub use error::new_request_sign_error; -pub use error::parse_error_response; -pub use error::ErrorResponse; +pub use error::with_error_response_context; mod bytes_range; pub use bytes_range::BytesRange; diff --git a/core/src/services/azblob/error.rs b/core/src/services/azblob/error.rs index 76eac0a30c04..80049d571110 100644 --- a/core/src/services/azblob/error.rs +++ b/core/src/services/azblob/error.rs @@ -104,6 +104,7 @@ pub async fn parse_error(resp: Response) -> Result { Ok(azblob_err) => format!("{azblob_err:?}"), Err(_) => String::from_utf8_lossy(&bs).into_owned(), }; + // If there is no body here, fill with error code. if message.is_empty() { if let Some(v) = parts.headers.get("x-ms-error-code") { @@ -119,7 +120,9 @@ pub async fn parse_error(resp: Response) -> Result { } } - let mut err = Error::new(kind, &message).with_context("response", format!("{parts:?}")); + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); diff --git a/core/src/services/azdfs/error.rs b/core/src/services/azdfs/error.rs index 9acc816368c0..ad0cc94e1771 100644 --- a/core/src/services/azdfs/error.rs +++ b/core/src/services/azdfs/error.rs @@ -95,7 +95,9 @@ pub async fn parse_error(resp: Response) -> Result { } } - let mut err = Error::new(kind, &message).with_context("response", format!("{parts:?}")); + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); diff --git a/core/src/services/cos/error.rs b/core/src/services/cos/error.rs index ba451659e4a6..e0d98920f66f 100644 --- a/core/src/services/cos/error.rs +++ b/core/src/services/cos/error.rs @@ -63,12 +63,13 @@ pub async fn parse_error(resp: Response) -> Result { Err(_) => String::from_utf8_lossy(&bs).into_owned(), }; - let mut err = Error::new(kind, &message).with_context("response", format!("{parts:?}")); + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); } - Ok(err) } diff --git a/core/src/services/dropbox/error.rs b/core/src/services/dropbox/error.rs index b2772263667c..f25f298af61b 100644 --- a/core/src/services/dropbox/error.rs +++ b/core/src/services/dropbox/error.rs @@ -17,7 +17,6 @@ use http::Response; use http::StatusCode; -use http::Uri; use serde::Deserialize; use crate::raw::*; @@ -55,16 +54,14 @@ pub async fn parse_error(resp: Response) -> Result { parse_dropbox_error_summary(&dropbox_err.error_summary).unwrap_or((kind, retryable)); } - let mut err = Error::new(kind, &message).with_context("response", format!("{parts:?}")); + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); } - if let Some(uri) = parts.extensions.get::() { - err = err.with_context("uri", uri.to_string()); - } - Ok(err) } diff --git a/core/src/services/gcs/error.rs b/core/src/services/gcs/error.rs index 3f2e0b688a65..2c5665ffd4cf 100644 --- a/core/src/services/gcs/error.rs +++ b/core/src/services/gcs/error.rs @@ -72,7 +72,9 @@ pub async fn parse_error(resp: Response) -> Result { Err(_) => String::from_utf8_lossy(&bs).into_owned(), }; - let mut err = Error::new(kind, &message).with_context("response", format!("{parts:?}")); + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); diff --git a/core/src/services/gdrive/error.rs b/core/src/services/gdrive/error.rs index 6fe6b57d42aa..60de6ae0d0a9 100644 --- a/core/src/services/gdrive/error.rs +++ b/core/src/services/gdrive/error.rs @@ -38,8 +38,11 @@ pub async fn parse_error(resp: Response) -> Result { _ => (ErrorKind::Unexpected, false), }; - let mut err = Error::new(kind, &String::from_utf8_lossy(&bs)) - .with_context("response", format!("{parts:?}")); + let message = String::from_utf8_lossy(&bs); + + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); diff --git a/core/src/services/ghac/error.rs b/core/src/services/ghac/error.rs index 005936b2d4c9..598822f1821e 100644 --- a/core/src/services/ghac/error.rs +++ b/core/src/services/ghac/error.rs @@ -40,8 +40,11 @@ pub async fn parse_error(resp: Response) -> Result { }; let bs = body.bytes().await?; - let mut err = Error::new(kind, &String::from_utf8_lossy(&bs)) - .with_context("response", format!("{parts:?}")); + let message = String::from_utf8_lossy(&bs); + + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); diff --git a/core/src/services/http/error.rs b/core/src/services/http/error.rs index aed2e13d63b1..c8afa09a963f 100644 --- a/core/src/services/http/error.rs +++ b/core/src/services/http/error.rs @@ -41,8 +41,11 @@ pub async fn parse_error(resp: Response) -> Result { _ => (ErrorKind::Unexpected, false), }; - let mut err = Error::new(kind, &String::from_utf8_lossy(&bs)) - .with_context("response", format!("{parts:?}")); + let message = String::from_utf8_lossy(&bs); + + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); diff --git a/core/src/services/ipfs/error.rs b/core/src/services/ipfs/error.rs index 7020dc43dcf4..1470b209899e 100644 --- a/core/src/services/ipfs/error.rs +++ b/core/src/services/ipfs/error.rs @@ -40,8 +40,11 @@ pub async fn parse_error(resp: Response) -> Result { _ => (ErrorKind::Unexpected, false), }; - let mut err = Error::new(kind, &String::from_utf8_lossy(&bs)) - .with_context("response", format!("{parts:?}")); + let message = String::from_utf8_lossy(&bs); + + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); diff --git a/core/src/services/ipmfs/error.rs b/core/src/services/ipmfs/error.rs index 286eda36be1e..df6e7f4752d7 100644 --- a/core/src/services/ipmfs/error.rs +++ b/core/src/services/ipmfs/error.rs @@ -73,7 +73,9 @@ pub async fn parse_error(resp: Response) -> Result { None => String::from_utf8_lossy(&bs).into_owned(), }; - let mut err = Error::new(kind, &message).with_context("response", format!("{parts:?}")); + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); diff --git a/core/src/services/obs/error.rs b/core/src/services/obs/error.rs index ddcca5f39047..0c2081312bc9 100644 --- a/core/src/services/obs/error.rs +++ b/core/src/services/obs/error.rs @@ -63,7 +63,9 @@ pub async fn parse_error(resp: Response) -> Result { Err(_) => String::from_utf8_lossy(&bs).into_owned(), }; - let mut err = Error::new(kind, &message).with_context("response", format!("{parts:?}")); + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); diff --git a/core/src/services/onedrive/error.rs b/core/src/services/onedrive/error.rs index 6fe6b57d42aa..60de6ae0d0a9 100644 --- a/core/src/services/onedrive/error.rs +++ b/core/src/services/onedrive/error.rs @@ -38,8 +38,11 @@ pub async fn parse_error(resp: Response) -> Result { _ => (ErrorKind::Unexpected, false), }; - let mut err = Error::new(kind, &String::from_utf8_lossy(&bs)) - .with_context("response", format!("{parts:?}")); + let message = String::from_utf8_lossy(&bs); + + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); diff --git a/core/src/services/oss/error.rs b/core/src/services/oss/error.rs index 715ad744f8c0..ecead41c4f76 100644 --- a/core/src/services/oss/error.rs +++ b/core/src/services/oss/error.rs @@ -59,7 +59,9 @@ pub async fn parse_error(resp: Response) -> Result { Err(_) => String::from_utf8_lossy(&bs).into_owned(), }; - let mut err = Error::new(kind, &message).with_context("response", format!("{parts:?}")); + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); diff --git a/core/src/services/s3/error.rs b/core/src/services/s3/error.rs index fce5c6d146bc..f683554877f7 100644 --- a/core/src/services/s3/error.rs +++ b/core/src/services/s3/error.rs @@ -17,7 +17,6 @@ use bytes::Buf; use http::Response; -use http::Uri; use quick_xml::de; use serde::Deserialize; @@ -60,16 +59,14 @@ pub async fn parse_error(resp: Response) -> Result { (kind, retryable) = parse_s3_error_code(s3_err.code.as_str()).unwrap_or((kind, retryable)); } - let mut err = Error::new(kind, &message).with_context("response", format!("{parts:?}")); + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); } - if let Some(uri) = parts.extensions.get::() { - err = err.with_context("uri", uri.to_string()); - } - Ok(err) } diff --git a/core/src/services/supabase/error.rs b/core/src/services/supabase/error.rs index 41c4225b22d0..58288959b001 100644 --- a/core/src/services/supabase/error.rs +++ b/core/src/services/supabase/error.rs @@ -53,7 +53,9 @@ pub async fn parse_error(resp: Response) -> Result { }) .unwrap_or_else(|_| (String::from_utf8_lossy(&bs).into_owned(), None)); - let mut err = Error::new(kind, &message).with_context("response", format!("{parts:?}")); + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); diff --git a/core/src/services/vercel_artifacts/error.rs b/core/src/services/vercel_artifacts/error.rs index 6fe6b57d42aa..60de6ae0d0a9 100644 --- a/core/src/services/vercel_artifacts/error.rs +++ b/core/src/services/vercel_artifacts/error.rs @@ -38,8 +38,11 @@ pub async fn parse_error(resp: Response) -> Result { _ => (ErrorKind::Unexpected, false), }; - let mut err = Error::new(kind, &String::from_utf8_lossy(&bs)) - .with_context("response", format!("{parts:?}")); + let message = String::from_utf8_lossy(&bs); + + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); diff --git a/core/src/services/wasabi/error.rs b/core/src/services/wasabi/error.rs index 2e4423f48a24..74bb4aa2e596 100644 --- a/core/src/services/wasabi/error.rs +++ b/core/src/services/wasabi/error.rs @@ -62,7 +62,9 @@ pub async fn parse_error(resp: Response) -> Result { (kind, retryable) = parse_wasabi_error_code(&wasabi_err.code).unwrap_or((kind, retryable)); } - let mut err = Error::new(kind, &message).with_context("response", format!("{parts:?}")); + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); diff --git a/core/src/services/webdav/error.rs b/core/src/services/webdav/error.rs index 472e7e30af25..967dc19f52a6 100644 --- a/core/src/services/webdav/error.rs +++ b/core/src/services/webdav/error.rs @@ -41,8 +41,11 @@ pub async fn parse_error(resp: Response) -> Result { _ => (ErrorKind::Unexpected, false), }; - let mut err = Error::new(kind, &String::from_utf8_lossy(&bs)) - .with_context("response", format!("{parts:?}")); + let message = String::from_utf8_lossy(&bs); + + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); diff --git a/core/src/services/webhdfs/error.rs b/core/src/services/webhdfs/error.rs index eafd36beebdb..7964ea38399f 100644 --- a/core/src/services/webhdfs/error.rs +++ b/core/src/services/webhdfs/error.rs @@ -65,7 +65,9 @@ fn parse_error_msg(parts: Parts, body: &str) -> Result { Err(_) => body.to_owned(), }; - let mut err = Error::new(kind, &message).with_context("response", format!("{parts:?}")); + let mut err = Error::new(kind, &message); + + err = with_error_response_context(err, parts); if retryable { err = err.set_temporary(); From 3895ba651ae42f4701e3c0dfe2fba5bf7a7d4f0b Mon Sep 17 00:00:00 2001 From: Xuanwo Date: Tue, 18 Jul 2023 16:01:05 +0800 Subject: [PATCH 2/2] Fix typo Signed-off-by: Xuanwo --- core/src/raw/http_util/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/raw/http_util/error.rs b/core/src/raw/http_util/error.rs index 34c416260c35..d84e75d7c673 100644 --- a/core/src/raw/http_util/error.rs +++ b/core/src/raw/http_util/error.rs @@ -57,7 +57,7 @@ pub fn with_error_response_context(mut err: Error, mut parts: Parts) -> Error { err = err.with_context("uri", uri.to_string()); } - // The folloing headers may contains sensitive information. + // The following headers may contains sensitive information. parts.headers.remove("Set-Cookie"); parts.headers.remove("WWW-Authenticate"); parts.headers.remove("Proxy-Authenticate");