Skip to main content

deboa_extras/catcher/
encoding.rs

1use 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}