Skip to content

Commit

Permalink
feat:(core): add content encoding to Opwrite (#5390)
Browse files Browse the repository at this point in the history
  • Loading branch information
Frank-III authored Dec 10, 2024
1 parent 7cde1f5 commit d48e06d
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 0 deletions.
12 changes: 12 additions & 0 deletions core/src/raw/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@ pub struct OpWrite {
concurrent: usize,
content_type: Option<String>,
content_disposition: Option<String>,
content_encoding: Option<String>,
cache_control: Option<String>,
executor: Option<Executor>,
if_match: Option<String>,
Expand Down Expand Up @@ -598,6 +599,17 @@ impl OpWrite {
self
}

/// Get the content encoding from option
pub fn content_encoding(&self) -> Option<&str> {
self.content_encoding.as_deref()
}

/// Set the content encoding of option
pub fn with_content_encoding(mut self, content_encoding: &str) -> Self {
self.content_encoding = Some(content_encoding.to_string());
self
}

/// Get the cache control from option
pub fn cache_control(&self) -> Option<&str> {
self.cache_control.as_deref()
Expand Down
1 change: 1 addition & 0 deletions core/src/services/s3/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,7 @@ impl Access for S3Backend {
write_can_multi: true,
write_with_cache_control: true,
write_with_content_type: true,
write_with_content_encoding: true,
write_with_if_match: !self.core.disable_write_with_if_match,
write_with_if_not_exists: true,
write_with_user_metadata: true,
Expand Down
5 changes: 5 additions & 0 deletions core/src/services/s3/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use constants::X_AMZ_META_PREFIX;
use http::header::HeaderName;
use http::header::CACHE_CONTROL;
use http::header::CONTENT_DISPOSITION;
use http::header::CONTENT_ENCODING;
use http::header::CONTENT_LENGTH;
use http::header::CONTENT_TYPE;
use http::header::HOST;
Expand Down Expand Up @@ -452,6 +453,10 @@ impl S3Core {
req = req.header(CONTENT_DISPOSITION, pos)
}

if let Some(encoding) = args.content_encoding() {
req = req.header(CONTENT_ENCODING, encoding);
}

if let Some(cache_control) = args.cache_control() {
req = req.header(CACHE_CONTROL, cache_control)
}
Expand Down
2 changes: 2 additions & 0 deletions core/src/types/capability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ pub struct Capability {
pub write_with_content_type: bool,
/// Indicates if Content-Disposition can be specified during write operations.
pub write_with_content_disposition: bool,
/// Indicates if Content-Encoding can be specified during write operations.
pub write_with_content_encoding: bool,
/// Indicates if Cache-Control can be specified during write operations.
pub write_with_cache_control: bool,
/// Indicates if conditional write operations using If-Match are supported.
Expand Down
32 changes: 32 additions & 0 deletions core/src/types/operator/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,38 @@ impl Operator {
/// # }
/// ```
///
/// ## `content_encoding`
///
/// Sets Content-Encoding header for this write request.
///
/// ### Capability
///
/// Check [`Capability::write_with_content_encoding`] before using this feature.
///
/// ### Behavior
///
/// - If supported, sets Content-Encoding as system metadata on the target file
/// - The value should follow HTTP Content-Encoding header format
/// - If not supported, the value will be ignored
///
/// This operation allows specifying the content encoding for the written content.
///
/// ## Example
///
/// ```no_run
/// # use opendal::Result;
/// # use opendal::Operator;
/// use bytes::Bytes;
/// # async fn test(op: Operator) -> Result<()> {
/// let bs = b"hello, world!".to_vec();
/// let _ = op
/// .write_with("path/to/file", bs)
/// .content_encoding("br")
/// .await?;
/// # Ok(())
/// # }
/// ```
///
/// ## `if_none_match`
///
/// Sets an `if none match` condition with specified ETag for this write request.
Expand Down
5 changes: 5 additions & 0 deletions core/src/types/operator/operator_futures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,11 @@ impl<F: Future<Output = Result<()>>> FutureWrite<F> {
self.map(|(args, options, bs)| (args.with_content_disposition(v), options, bs))
}

/// Set the content encoding of option
pub fn content_encoding(self, v: &str) -> Self {
self.map(|(args, options, bs)| (args.with_content_encoding(v), options, bs))
}

/// Set the executor for this operation.
pub fn executor(self, executor: Executor) -> Self {
self.map(|(args, options, bs)| (args.with_executor(executor), options, bs))
Expand Down
23 changes: 23 additions & 0 deletions core/tests/behavior/async_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub fn tests(op: &Operator, tests: &mut Vec<Trial>) {
test_write_with_cache_control,
test_write_with_content_type,
test_write_with_content_disposition,
test_write_with_content_encoding,
test_write_with_if_none_match,
test_write_with_if_not_exists,
test_write_with_if_match,
Expand Down Expand Up @@ -211,6 +212,28 @@ pub async fn test_write_with_content_disposition(op: Operator) -> Result<()> {
Ok(())
}

/// Write a single file with content encoding should succeed.
pub async fn test_write_with_content_encoding(op: Operator) -> Result<()> {
if !op.info().full_capability().write_with_content_encoding {
return Ok(());
}

let (path, content, _) = TEST_FIXTURE.new_file(op.clone());

let target_content_encoding = "gzip";
op.write_with(&path, content)
.content_encoding(target_content_encoding)
.await?;

let meta = op.stat(&path).await.expect("stat must succeed");
assert_eq!(
meta.content_encoding()
.expect("content encoding must exist"),
target_content_encoding
);
Ok(())
}

/// write a single file with user defined metadata should succeed.
pub async fn test_write_with_user_metadata(op: Operator) -> Result<()> {
if !op.info().full_capability().write_with_user_metadata {
Expand Down

0 comments on commit d48e06d

Please sign in to comment.