deboa_extras/catcher/
encoding.rs1use deboa::{
2 catcher::DeboaCatcher,
3 errors::{DeboaError, IoError},
4 fs::io::Decompressor,
5 request::DeboaRequest,
6 response::DeboaResponse,
7 Result,
8};
9use http::{header, HeaderValue};
10use std::collections::HashMap;
11
12pub struct EncodingCatcher<D: Decompressor> {
13 pub accept_encoding: HashMap<String, Box<D>>,
14}
15
16impl<D: Decompressor> EncodingCatcher<D> {
17 pub fn register_decoders(decoders: Vec<D>) -> Self {
18 let mut accept_encoding = HashMap::new();
19 for decoder in decoders {
20 accept_encoding.insert(decoder.name(), Box::new(decoder));
21 }
22 Self { accept_encoding }
23 }
24}
25
26#[deboa::async_trait]
27impl<D: Decompressor> DeboaCatcher for EncodingCatcher<D> {
28 async fn on_request(&self, request: &mut DeboaRequest) -> Result<Option<DeboaResponse>> {
29 let encodings = self
30 .accept_encoding
31 .values()
32 .map(|decoder| decoder.name())
33 .collect::<Vec<String>>();
34
35 request
36 .headers_mut()
37 .insert(header::ACCEPT_ENCODING, HeaderValue::from_str(&encodings.join(",")).unwrap());
38
39 Ok(None)
40 }
41
42 async fn on_response(&self, response: &mut DeboaResponse) -> Result<()> {
43 let content_encoding = response
44 .headers()
45 .get(header::CONTENT_ENCODING);
46 if content_encoding.is_none() {
47 return Err(DeboaError::Io(IoError::Decompress {
48 message: "Content encoding not found".to_string(),
49 }));
50 }
51
52 let decompressor = self
53 .accept_encoding
54 .get(
55 content_encoding
56 .unwrap()
57 .to_str()
58 .unwrap(),
59 );
60 if decompressor.is_none() {
61 return Err(DeboaError::Io(IoError::Decompress {
62 message: "No decompressor found".to_string(),
63 }));
64 }
65
66 decompressor
67 .unwrap()
68 .decompress_body(response)
69 .await?;
70 Ok(())
71 }
72}