http_msgsign_draft/sign/
params.rs1use std::time::Duration;
2
3use http::{Request, Response};
4use indexmap::IndexSet;
5
6use crate::errors::{HttpPayloadSeekError, SignatureParamsError};
7use crate::sign::SignatureBase;
8use crate::sign::field::{TargetField, TimeOrDuration};
9
10#[derive(Debug, Clone)]
11pub struct SignatureParams {
12 targets: IndexSet<TargetField>,
13}
14
15pub struct SignatureParamsBuilder {
16 builder: Result<SignatureParams, SignatureParamsError>,
17}
18
19impl SignatureParams {
20 pub fn builder() -> SignatureParamsBuilder {
21 SignatureParamsBuilder {
22 builder: Ok(SignatureParams {
23 targets: Default::default(),
24 }),
25 }
26 }
27
28 pub(crate) fn seek_request<B>(
29 &self,
30 request: &Request<B>,
31 ) -> Result<SignatureBase, HttpPayloadSeekError> {
32 let seeked = self
33 .targets
34 .iter()
35 .map(|target| target.seek_request(request))
36 .collect::<Result<IndexSet<_>, _>>()?;
37
38 Ok(SignatureBase::from_components(seeked))
39 }
40
41 pub(crate) fn seek_response<B>(
42 &self,
43 response: &Response<B>,
44 ) -> Result<SignatureBase, HttpPayloadSeekError> {
45 let seeked = self
46 .targets
47 .iter()
48 .map(|target| target.seek_response(response))
49 .collect::<Result<IndexSet<_>, _>>()?;
50
51 Ok(SignatureBase::from_components(seeked))
52 }
53}
54
55impl SignatureParamsBuilder {
56 pub fn add_header<H>(self, header: H) -> Self
57 where
58 H: TryInto<http::HeaderName>,
59 H::Error: Into<http::Error>,
60 {
61 self.and_then(|mut params| {
62 let header = header.try_into().map_err(Into::into)?;
63 params.targets.insert(TargetField::HeaderField(header));
64 Ok(params)
65 })
66 }
67
68 pub fn add_request_target(self) -> Self {
69 self.and_then(|mut params| {
70 params.targets.insert(TargetField::RequestTarget);
71 Ok(params)
72 })
73 }
74
75 pub fn set_created(self) -> Self {
76 self.and_then(|mut params| {
77 params.targets.insert(TargetField::Created(None));
78 Ok(params)
79 })
80 }
81
82 pub fn set_expires(self, expires: impl Into<Duration>) -> Self {
83 self.and_then(|mut params| {
84 params
85 .targets
86 .insert(TargetField::Expires(TimeOrDuration::Duration(
87 expires.into(),
88 )));
89 Ok(params)
90 })
91 }
92
93 pub fn build(self) -> Result<SignatureParams, SignatureParamsError> {
94 self.builder.map(|mut params| {
97 if params.targets.is_empty() {
98 params.targets.insert(TargetField::Created(None));
99 }
100 Ok(params)
101 })?
102 }
103
104 fn and_then<F>(self, f: F) -> Self
105 where
106 F: FnOnce(SignatureParams) -> Result<SignatureParams, SignatureParamsError>,
107 {
108 Self {
109 builder: self.builder.and_then(f),
110 }
111 }
112}