diff options
Diffstat (limited to 'src/api/s3/put.rs')
-rw-r--r-- | src/api/s3/put.rs | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/src/api/s3/put.rs b/src/api/s3/put.rs index 4d866a06..830a7998 100644 --- a/src/api/s3/put.rs +++ b/src/api/s3/put.rs @@ -37,6 +37,7 @@ use garage_api_common::signature::checksum::*; use crate::api_server::{ReqBody, ResBody}; use crate::encryption::EncryptionParams; use crate::error::*; +use crate::website::X_AMZ_WEBSITE_REDIRECT_LOCATION; const PUT_BLOCKS_MAX_PARALLEL: usize = 3; @@ -62,7 +63,7 @@ pub async fn handle_put( key: &String, ) -> Result<Response<ResBody>, Error> { // Retrieve interesting headers from request - let headers = get_headers(req.headers())?; + let headers = extract_metadata_headers(req.headers())?; debug!("Object headers: {:?}", headers); let expected_checksums = ExpectedChecksums { @@ -649,7 +650,9 @@ impl Drop for InterruptedCleanup { // ============ helpers ============ -pub(crate) fn get_headers(headers: &HeaderMap<HeaderValue>) -> Result<HeaderList, Error> { +pub(crate) fn extract_metadata_headers( + headers: &HeaderMap<HeaderValue>, +) -> Result<HeaderList, Error> { let mut ret = Vec::new(); // Preserve standard headers @@ -675,6 +678,18 @@ pub(crate) fn get_headers(headers: &HeaderMap<HeaderValue>) -> Result<HeaderList std::str::from_utf8(value.as_bytes())?.to_string(), )); } + if name == X_AMZ_WEBSITE_REDIRECT_LOCATION { + let value = std::str::from_utf8(value.as_bytes())?.to_string(); + if !(value.starts_with("/") + || value.starts_with("http://") + || value.starts_with("https://")) + { + return Err(Error::bad_request(format!( + "Invalid {X_AMZ_WEBSITE_REDIRECT_LOCATION} header", + ))); + } + ret.push((X_AMZ_WEBSITE_REDIRECT_LOCATION.to_string(), value)); + } } Ok(ret) |