Skip to content

Commit

Permalink
Added user metadata support for cos service
Browse files Browse the repository at this point in the history
  • Loading branch information
geetanshjuneja committed Jan 5, 2025
1 parent 6ca3eab commit 36ea40a
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
8 changes: 7 additions & 1 deletion core/src/services/cos/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ impl Access for CosBackend {
stat_has_content_md5: true,
stat_has_last_modified: true,
stat_has_content_disposition: true,
stat_has_user_metadata: true,

read: true,

Expand Down Expand Up @@ -284,6 +285,7 @@ impl Access for CosBackend {
} else {
Some(usize::MAX)
},
write_with_user_metadata: true,

delete: true,
copy: true,
Expand Down Expand Up @@ -311,7 +313,11 @@ impl Access for CosBackend {
let status = resp.status();

match status {
StatusCode::OK => parse_into_metadata(path, resp.headers()).map(RpStat::new),
StatusCode::OK =>{
let headers = resp.headers();
let mut meta = self.core.parse_metadata(path, resp.headers())?;
Ok(RpStat::new(meta))
},
_ => Err(parse_error(resp)),
}
}
Expand Down
54 changes: 54 additions & 0 deletions core/src/services/cos/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,20 @@ impl CosCore {
req = req.header("x-cos-forbid-overwrite", "true")
}

// Set user metadata headers.
if let Some(user_metadata) = args.user_metadata() {
// before insert user defined metadata header, add prefix to the header name
if !self.check_user_metadata_key(key) {
return Err(Error::new(
ErrorKind::Unsupported,
"the format of the user metadata key is invalid, please refer the document",
));
}
for (key, value) in user_metadata {
req = req.header(format!("x-cos-meta-{key}"), value)
}
}

let req = req.body(body).map_err(new_request_build_error)?;

Ok(req)
Expand Down Expand Up @@ -345,6 +359,20 @@ impl CosCore {
req = req.header(CACHE_CONTROL, cache_control)
}

// Set user metadata headers.
if let Some(user_metadata) = args.user_metadata() {
// before insert user defined metadata header, add prefix to the header name
if !self.check_user_metadata_key(key) {
return Err(Error::new(
ErrorKind::Unsupported,
"the format of the user metadata key is invalid, please refer the document",
));
}
for (key, value) in user_metadata {
req = req.header(format!("x-cos-meta-{key}"), value)
}
}

let mut req = req.body(Buffer::new()).map_err(new_request_build_error)?;

self.sign(&mut req).await?;
Expand Down Expand Up @@ -434,6 +462,32 @@ impl CosCore {
self.sign(&mut req).await?;
self.send(req).await
}

// According to https://www.tencentcloud.com/document/product/436/7746
// there are some limits in user defined metadata key
fn check_user_metadata_key(&self, key: &str) -> bool {
key.chars().all(|c| c != '_')
}

/// parse_metadata will parse http headers(including standards http headers
/// and user defined metadata header) into Metadata.
///
/// # Arguments
///
/// * `user_metadata_prefix` is the prefix of user defined metadata key
///
/// # Notes
///
/// before return the user defined metadata, we'll strip the user_metadata_prefix from the key
pub fn parse_metadata(&self, path: &str, headers: &HeaderMap) -> Result<Metadata> {
let mut m = parse_into_metadata(path, headers)?;
let user_meta = parse_prefixed_headers(headers, "x-cos-meta-");
if !user_meta.is_empty() {
m.with_user_metadata(user_meta);
}

Ok(m)
}
}

/// Result of CreateMultipartUpload
Expand Down

0 comments on commit 36ea40a

Please sign in to comment.