use crate::s3::client::MinioClient;
use crate::s3::creds::Credentials;
use crate::s3::error::Error;
use crate::s3::header_constants::*;
use crate::s3::multimap_ext::{Multimap, MultimapExt};
use crate::s3::response::GetPresignedObjectUrlResponse;
use crate::s3::signer::presign_v4;
use crate::s3::types::{BucketName, ObjectKey, Region, VersionId};
use crate::s3::utils::{UtcTime, utc_now};
use http::Method;
use typed_builder::TypedBuilder;
pub const DEFAULT_EXPIRY_SECONDS: u32 = 604_800;
#[derive(Clone, Debug, TypedBuilder)]
pub struct GetPresignedObjectUrl {
#[builder(!default)] client: MinioClient,
#[builder(default, setter(into))]
extra_query_params: Option<Multimap>,
#[builder(default, setter(into))]
region: Option<Region>,
#[builder(setter(into))] bucket: BucketName,
#[builder(setter(into))] object: ObjectKey,
#[builder(default, setter(into))]
version_id: Option<VersionId>,
#[builder(!default)]
method: Method,
#[builder(default=Some(DEFAULT_EXPIRY_SECONDS), setter(into))]
expiry_seconds: Option<u32>,
#[builder(default, setter(into))]
request_time: Option<UtcTime>,
}
pub type GetPresignedObjectUrlBldr = GetPresignedObjectUrlBuilder<(
(MinioClient,),
(),
(),
(BucketName,),
(ObjectKey,),
(),
(Method,),
(),
(),
)>;
impl GetPresignedObjectUrl {
pub async fn send(self) -> Result<GetPresignedObjectUrlResponse, Error> {
let region_str: String = self
.client
.get_region_cached(self.bucket.clone(), &self.region)
.await?;
let region = Region::new(®ion_str)?;
let mut query_params: Multimap = self.extra_query_params.unwrap_or_default();
query_params.add_version(self.version_id.clone());
let mut url = self.client.shared.base_url.build_url(
&self.method,
®ion,
&query_params,
Some(&self.bucket),
Some(&self.object),
)?;
if let Some(p) = &self.client.shared.provider {
let creds: Credentials = p.fetch();
if let Some(t) = creds.session_token {
query_params.add(X_AMZ_SECURITY_TOKEN, t);
}
let date = match self.request_time {
Some(v) => v,
_ => utc_now(),
};
presign_v4(
&self.client.shared.signing_key_cache,
&self.method,
&url.host_header_value(),
&url.path,
®ion,
&mut query_params,
&creds.access_key,
&creds.secret_key,
date,
self.expiry_seconds.unwrap_or(DEFAULT_EXPIRY_SECONDS),
);
url.query = query_params;
}
Ok(GetPresignedObjectUrlResponse {
region,
bucket: self.bucket,
object: self.object,
version_id: self.version_id,
url: url.to_string(),
})
}
}