new feature: feat(services/oss): support content_encoding for write operations
enhancementservices/ossreleases-note/featrustintegrations/object_store
### Feature Description
The `services-oss` backend should support `OpWrite::content_encoding()` for write operations.
`OpWrite::content_encoding()` already exists in OpenDAL, and other object storage backends such as S3 and GCS support writing objects
with `Content-Encoding` metadata. OSS currently does not advertise `write_with_content_encoding`, and the header is not forwarded when
writing objects.
Expected usage:
```rust
op.write_with("path/to/cfg.json", compressed_bytes)
.content_type("application/json; charset=utf-8")
.content_encoding("gzip")
.cache_control("public, max-age=60")
.await?;
After upload, op.stat("path/to/cfg.json").await?.content_encoding() should return Some("gzip"), and OSS/CDN responses should preserve
Content-Encoding: gzip.
### Problem and Solution
In our application, we generate a `cfg.json`, gzip-compress it, and upload it to Aliyun OSS so that it can be served through CDN with
transparent decompression.
When using OpenDAL OSS, the uploaded object does not preserve the `Content-Encoding: gzip` metadata. The CDN/browser then receives
gzip-compressed bytes without the response header needed for transparent decompression.
We had to bypass OpenDAL for this upload path and send a native OSS `PUT` request with OSS v4 signing to explicitly set:
```text
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
Cache-Control: public, max-age=60
```
This workaround is functional, but it duplicates OSS signing logic outside OpenDAL and makes the abstraction leaky.
The proposed solution is to wire the existing write option into the OSS backend:
1. Set write_with_content_encoding: true in the OSS capability table.
2. Forward args.content_encoding() in OSS PutObject / AppendObject metadata headers.
3. Forward content_encoding when initiating multipart uploads, since OSS object metadata should be set on InitiateMultipartUpload.
### Additional Context
```markdown
This is consistent with existing content-encoding support in other object storage backends.
A minimal reproduction looks like:
```
```rust
use opendal::{services::Oss, Operator};
#[tokio::main]
async fn main() -> opendal::Result<()> {
let op: Operator = Operator::new(
Oss::default()
.endpoint("https://oss-cn-hangzhou.aliyuncs.com")
.bucket("my-bucket"),
)?
.finish();
op.write_with("cfg.json", gzip_bytes())
.content_type("application/json; charset=utf-8")
.content_encoding("gzip")
.cache_control("public, max-age=60")
.await?;
let meta = op.stat("cfg.json").await?;
assert_eq!(meta.content_encoding(), Some("gzip"));
Ok(())
}
```
Currently, OSS does not advertise write_with_content_encoding, and Content-Encoding is not forwarded in OSS write requests.
I have a patch ready and am willing to contribute it.
### Are you willing to contribute to the development of this feature?
- [x] Yes, I am willing to contribute to the development of this feature.
0 条评论