Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions core/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion core/services/tos/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ opendal-core = { path = "../../core", version = "0.58.1", default-features = fal
quick-xml = { workspace = true, features = ["serialize", "overlapped-lists"] }
reqsign-core = { version = "3.2.0", default-features = false }
reqsign-file-read-tokio = { version = "3.0.3", default-features = false }
reqsign-volcengine-tos = "3.0.3"
reqsign-volcengine-tos = "3.1.1"
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
40 changes: 32 additions & 8 deletions core/services/tos/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use crate::writer::TosWriter;
use http::StatusCode;
use opendal_core::OperationContext;
use opendal_core::raw::*;
use opendal_core::{Builder, Capability, EntryMode, Error, ErrorKind, Result};
use opendal_core::{Buffer, Builder, Capability, EntryMode, Error, ErrorKind, Result};
use reqsign_core::{Context, OsEnv, ProvideCredentialChain, Signer};
use reqsign_file_read_tokio::TokioFileRead;
use reqsign_volcengine_tos::{EnvCredentialProvider, RequestSigner, StaticCredentialProvider};
Expand Down Expand Up @@ -215,6 +215,12 @@ impl Builder for TosBuilder {
list_with_versions: true,
list_with_deleted: true,

presign: true,
presign_stat: true,
presign_read: true,
presign_write: true,
presign_delete: true,

stat: true,
stat_with_if_match: true,
stat_with_if_none_match: true,
Expand Down Expand Up @@ -416,13 +422,31 @@ impl Service for TosBackend {

async fn presign(
&self,
_ctx: &OperationContext,
_path: &str,
_args: OpPresign,
ctx: &OperationContext,
path: &str,
args: OpPresign,
) -> Result<RpPresign> {
Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
))
let (expire, op) = args.into_parts();
let req = match op {
PresignOperation::Stat(v) => self.core.tos_head_object_request(path, v),
PresignOperation::Read(range, v) => self.core.tos_get_object_request(path, range, &v),
PresignOperation::Write(v) => {
self.core
.tos_put_object_request(path, None, &v, Buffer::new())
}
PresignOperation::Delete(v) => self.core.tos_delete_object_request(path, &v),
_ => Err(Error::new(
ErrorKind::Unsupported,
"operation is not supported",
)),
}?;
let req = self.core.sign_query(ctx, req, expire).await?;
let (parts, _) = req.into_parts();

Ok(RpPresign::new(PresignedRequest::new(
parts.method,
parts.uri,
parts.headers,
)))
}
}
41 changes: 35 additions & 6 deletions core/services/tos/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
// under the License.

use std::fmt::Debug;
use std::time::Duration;

use http::Request;
use http::Response;
Expand Down Expand Up @@ -99,6 +100,27 @@ impl TosCore {
)
}

pub async fn sign_query<T>(
&self,
ctx: &OperationContext,
req: Request<T>,
duration: Duration,
) -> Result<Request<T>> {
if self.skip_signature {
return Ok(req);
}

let (mut parts, body) = req.into_parts();
self.signer(ctx)
.sign(&mut parts, Some(duration))
.await
.map_err(|e| new_request_sign_error(e.into()))?;

parts.headers.remove(HOST);

Ok(Request::from_parts(parts, body))
}

pub async fn send(
&self,
ctx: &OperationContext,
Expand Down Expand Up @@ -413,12 +435,11 @@ impl TosCore {
self.send(ctx, req).await
}

pub async fn tos_delete_object(
pub fn tos_delete_object_request(
&self,
ctx: &OperationContext,
path: &str,
args: &OpDelete,
) -> Result<Response<Buffer>> {
) -> Result<Request<Buffer>> {
let p = build_abs_path(&self.root, path);

let mut url = format!(
Expand All @@ -444,11 +465,19 @@ impl TosCore {

let req = Request::delete(&url);

let req = req
.extension(Operation::Delete)
req.extension(Operation::Delete)
.extension(ServiceOperation("DeleteObject"))
.body(Buffer::new())
.map_err(new_request_build_error)?;
.map_err(new_request_build_error)
}

pub async fn tos_delete_object(
&self,
ctx: &OperationContext,
path: &str,
args: &OpDelete,
) -> Result<Response<Buffer>> {
let req = self.tos_delete_object_request(path, args)?;

self.send(ctx, req).await
}
Expand Down
2 changes: 1 addition & 1 deletion core/services/tos/src/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Depending on its configuration and the backing system, this service can expose:
- [x] list
- [x] copy
- [ ] rename
- [ ] presign
- [x] presign

Inspect the effective capability set with [`opendal_core::Operator::info`] and
[`opendal_core::OperatorInfo::capability`] after building an operator.
Expand Down
Loading