aws_runtime/content_encoding/
sign.rs1use aws_sigv4::http_request::SigningError;
7use aws_smithy_runtime_api::http::Headers;
8use aws_smithy_types::config_bag::{Storable, StoreReplace};
9use bytes::Bytes;
10use std::sync::{mpsc, Arc, Mutex};
11
12pub(crate) trait SignChunk: std::fmt::Debug {
16 fn chunk_signature(&mut self, chunk: &Bytes) -> Result<String, SigningError>;
17
18 fn trailer_signature(&mut self, trailing_headers: &Headers) -> Result<String, SigningError>;
19}
20
21#[derive(Clone, Debug)]
30#[allow(clippy::type_complexity)]
31pub struct DeferredSigner {
32 signer: Arc<Mutex<Option<Box<dyn SignChunk + Send + Sync>>>>,
35 rx: Arc<Mutex<Option<mpsc::Receiver<Box<dyn SignChunk + Send + Sync>>>>>,
36}
37
38impl Storable for DeferredSigner {
39 type Storer = StoreReplace<Self>;
40}
41
42impl DeferredSigner {
43 pub fn new() -> (Self, DeferredSignerSender) {
45 let (tx, rx) = mpsc::channel();
46 (
47 Self {
48 signer: Default::default(),
49 rx: Arc::new(Mutex::new(Some(rx))),
50 },
51 DeferredSignerSender { tx: Mutex::new(tx) },
52 )
53 }
54
55 pub fn empty() -> Self {
57 Self {
58 rx: Default::default(),
59 signer: Default::default(),
60 }
61 }
62
63 fn acquire(&self) -> Box<dyn SignChunk + Send + Sync> {
64 let mut rx = self.rx.lock().unwrap();
65 rx.take()
66 .and_then(|receiver| receiver.try_recv().ok())
67 .expect("signer should be available")
68 }
69}
70
71#[derive(Debug)]
73pub struct DeferredSignerSender {
74 tx: Mutex<mpsc::Sender<Box<dyn SignChunk + Send + Sync>>>,
75}
76
77impl DeferredSignerSender {
78 pub(crate) fn send(
79 &self,
80 signer: Box<dyn SignChunk + Send + Sync>,
81 ) -> Result<(), mpsc::SendError<Box<dyn SignChunk + Send + Sync>>> {
82 self.tx.lock().unwrap().send(signer)
83 }
84}
85
86impl Storable for DeferredSignerSender {
87 type Storer = StoreReplace<Self>;
88}
89
90impl SignChunk for DeferredSigner {
91 fn chunk_signature(&mut self, chunk: &Bytes) -> Result<String, SigningError> {
92 let mut signer = self.signer.lock().unwrap();
93 let signer = signer.get_or_insert_with(|| self.acquire());
94 signer.chunk_signature(chunk)
95 }
96
97 fn trailer_signature(&mut self, trailing_headers: &Headers) -> Result<String, SigningError> {
98 let mut signer = self.signer.lock().unwrap();
99 let signer = signer.get_or_insert_with(|| self.acquire());
100 signer.trailer_signature(trailing_headers)
101 }
102}