1use std::{
2 error, fmt,
3 time::{Duration, SystemTime},
4};
5
6use aws_sigv4::{
7 http_request::{
8 sign, Error as AwsSigv4HttpRequestSignError, SignableRequest, SigningParams,
9 SigningSettings,
10 },
11 signing_params::BuildError as AwsSigv4SigningParamsBuildError,
12};
13use http::Request;
14
15pub fn sign_http_request<SSED, SRED>(
17 mut request: Request<Vec<u8>>,
18 access_key_id: &str,
19 secret_access_key: &str,
20 region: &str,
21 service_name: &str,
22 mut signing_settings_editor: SSED,
23 mut signing_params_editor: SRED,
24) -> Result<Request<Vec<u8>>, SignHttpRequestError>
25where
26 SSED: FnMut(SigningSettings) -> SigningSettings + Send,
27 SRED: FnMut(SigningParams) -> SigningParams + Send,
28{
29 let mut signing_settings = SigningSettings::default();
30 signing_settings.expires_in = Some(Duration::from_secs(60 * 10));
31 let signing_settings = signing_settings_editor(signing_settings);
32
33 let signing_params = SigningParams::builder()
34 .access_key(access_key_id)
35 .secret_key(secret_access_key)
36 .region(region)
37 .service_name(service_name)
38 .time(SystemTime::now())
39 .settings(signing_settings)
40 .build()
41 .map_err(SignHttpRequestError::MakeSigningParamsFailed)?;
42 let signing_params = signing_params_editor(signing_params);
43
44 let signable_request = SignableRequest::from(&request);
45 let (signing_instructions, _signature) = sign(signable_request, &signing_params)
46 .map_err(SignHttpRequestError::SignFailed)?
47 .into_parts();
48
49 signing_instructions.apply_to_request(&mut request);
50
51 Ok(request)
52}
53
54#[derive(Debug)]
56pub enum SignHttpRequestError {
57 MakeSigningParamsFailed(AwsSigv4SigningParamsBuildError),
58 SignFailed(AwsSigv4HttpRequestSignError),
59}
60impl fmt::Display for SignHttpRequestError {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 write!(f, "{:?}", self)
63 }
64}
65impl error::Error for SignHttpRequestError {}