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;
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.add_header(header::ACCEPT_ENCODING, &encodings.join(","));
36
37 Ok(None)
38 }
39
40 async fn on_response(&self, response: &mut DeboaResponse) -> Result<()> {
41 let content_encoding = response
42 .headers()
43 .get(header::CONTENT_ENCODING);
44 if content_encoding.is_none() {
45 return Err(DeboaError::Io(IoError::Decompress {
46 message: "Content encoding not found".to_string(),
47 }));
48 }
49
50 let decompressor = self
51 .accept_encoding
52 .get(
53 content_encoding
54 .unwrap()
55 .to_str()
56 .unwrap(),
57 );
58 if decompressor.is_none() {
59 return Err(DeboaError::Io(IoError::Decompress {
60 message: "No decompressor found".to_string(),
61 }));
62 }
63
64 decompressor
65 .unwrap()
66 .decompress_body(response)
67 .await?;
68 Ok(())
69 }
70}