use rusoto_core::signature;
use rusoto_core::signature::SignedRequest;
use rusoto_core::param::{Params, ServiceParams};
use rusoto_core::region::Region;
use rusoto_core::credential::AwsCredentials;
use crate::generated::{GetObjectRequest, PutObjectRequest, DeleteObjectRequest, UploadPartRequest};
use std::time::Duration;
pub fn encode_key<T: AsRef<str>>(key: T) -> String {
signature::encode_uri_path(key.as_ref())
}
macro_rules! add_headers {
(
$input:ident , $req:ident ; $p:ident , $e:expr ; $( $t:tt )*
) => (
{
if let Some(ref $p) = $input.$p {
$req.add_header($e, &$p.to_string());
}
add_headers! { $input, $req; $( $t )* }
}
);
(
$input:pat , $req:expr ;
) => ({
});
}
macro_rules! add_params {
(
$input:ident , $params:ident ; $p:ident , $e:expr ; $( $t:tt )*
) => (
{
if let Some(ref $p) = $input.$p {
$params.put($e, &$p);
}
add_params! { $input, $params; $( $t )* }
}
);
(
$input:pat , $req:expr ;
) => ({
});
}
pub struct PreSignedRequestOption {
pub expires_in: Duration
}
impl Default for PreSignedRequestOption {
fn default() -> Self {
Self {
expires_in: Duration::from_secs(3600)
}
}
}
pub trait PreSignedRequest {
fn get_presigned_url(&self, region: &Region, credentials: &AwsCredentials, option: &PreSignedRequestOption) -> String;
}
impl PreSignedRequest for GetObjectRequest {
fn get_presigned_url(&self, region: &Region, credentials: &AwsCredentials, option: &PreSignedRequestOption) -> String {
let request_uri = format!("/{bucket}/{key}", bucket = self.bucket, key = self.key);
let mut request = SignedRequest::new("GET", "s3", ®ion, &request_uri);
let mut params = Params::new();
add_headers!(
self, request;
range, "Range";
if_modified_since, "If-Modified-Since";
if_unmodified_since, "If-Unmodified-Since";
if_match, "If-Match";
if_none_match, "If-None-Match";
sse_customer_algorithm, "x-amz-server-side-encryption-customer-algorithm";
sse_customer_key, "x-amz-server-side-encryption-customer-key";
sse_customer_key_md5, "x-amz-server-side-encryption-customer-key-MD5";
);
add_params!(
self, params;
part_number, "partNumber";
response_content_type, "response-content-type";
response_content_language, "response-content-language";
response_expires, "response-expires";
response_cache_control, "response-cache-control";
response_content_disposition, "response-content-disposition";
response_content_encoding, "response-content-encoding";
version_id, "versionId";
);
request.set_params(params);
request.generate_presigned_url(credentials, &option.expires_in, false)
}
}
impl PreSignedRequest for PutObjectRequest {
fn get_presigned_url(&self, region: &Region, credentials: &AwsCredentials, option: &PreSignedRequestOption) -> String {
let request_uri = format!("/{bucket}/{key}", bucket = self.bucket, key = self.key);
let mut request = SignedRequest::new("PUT", "s3", ®ion, &request_uri);
add_headers!(
self, request;
cache_control, "Cache-Control";
content_disposition, "Content-Disposition";
content_encoding, "Content-Encoding";
content_length, "Content-Length";
content_md5, "Content-MD5";
content_type, "Content-Type";
expires, "Expires";
storage_class, "x-amz-storage-class";
tagging, "x-amz-tagging";
website_redirect_location, "x-amz-website-redirect-location";
acl, "x-amz-acl";
grant_read, "x-amz-grant-read";
grant_read_acp, "x-amz-grant-read-acp";
grant_write_acp, "x-amz-grant-write-acp";
grant_full_control, "x-amz-grant-full-control";
server_side_encryption, "x-amz-server-side-encryption";
ssekms_key_id, "x-amz-server-side-encryption-aws-kms-key-id";
sse_customer_algorithm, "x-amz-server-side-encryption-customer-algorithm";
sse_customer_key, "x-amz-server-side-encryption-customer-key";
sse_customer_key_md5, "x-amz-server-side-encryption-customer-key-MD5";
);
if let Some(ref metadata) = self.metadata {
for (header_name, header_value) in metadata.iter() {
let header = format!("x-amz-meta-{}", header_name);
request.add_header(header, header_value);
}
}
request.generate_presigned_url(credentials, &option.expires_in, false)
}
}
impl PreSignedRequest for DeleteObjectRequest {
fn get_presigned_url(&self, region: &Region, credentials: &AwsCredentials, option: &PreSignedRequestOption) -> String {
let request_uri = format!("/{bucket}/{key}", bucket = self.bucket, key = self.key);
let mut request = SignedRequest::new("DELETE", "s3", ®ion, &request_uri);
let mut params = Params::new();
add_headers!(
self, request;
mfa, "x-amz-mfa";
);
add_params!(
self, params;
version_id, "versionId";
);
request.set_params(params);
request.generate_presigned_url(credentials, &option.expires_in, false)
}
}
impl PreSignedRequest for UploadPartRequest {
fn get_presigned_url(&self, region: &Region, credentials: &AwsCredentials, option: &PreSignedRequestOption) -> String {
let request_uri = format!("/{bucket}/{key}", bucket = self.bucket, key = self.key);
let mut request = SignedRequest::new("PUT", "s3", ®ion, &request_uri);
request.add_param("partNumber", &self.part_number.to_string());
request.add_param("uploadId", &self.upload_id);
add_headers!(
self, request;
content_length, "Content-Length";
content_md5, "Content-MD5";
sse_customer_algorithm, "x-amz-server-side-encryption-customer-algorithm";
sse_customer_key, "x-amz-server-side-encryption-customer-key";
sse_customer_key_md5, "x-amz-server-side-encryption-customer-key-MD5";
request_payer, "x-amz-request-payer";
);
request.generate_presigned_url(credentials, &option.expires_in, false)
}
}