Skip to main content

leyline/core/config/
compression.rs

1pub(crate) const DEFAULT_MAX_BODY_SIZE: usize = 100 * 1024 * 1024;
2pub(crate) const DEFAULT_MAX_HEADER_LIST_BYTES: usize = 256 * 1024;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5#[non_exhaustive]
6pub struct CompressionConfig {
7    pub(crate) gzip: bool,
8    pub(crate) brotli: bool,
9    pub(crate) deflate: bool,
10    pub(crate) zstd: bool,
11    pub(crate) max_body_size: usize,
12    pub(crate) max_error_body: usize,
13}
14
15impl Default for CompressionConfig {
16    fn default() -> Self {
17        Self {
18            gzip: true,
19            brotli: true,
20            deflate: true,
21            zstd: true,
22            max_body_size: DEFAULT_MAX_BODY_SIZE,
23            max_error_body: 64 * 1024,
24        }
25    }
26}
27
28impl CompressionConfig {
29    pub fn new() -> Self {
30        Self::default()
31    }
32
33    pub fn none() -> Self {
34        Self {
35            gzip: false,
36            brotli: false,
37            deflate: false,
38            zstd: false,
39            ..Self::default()
40        }
41    }
42
43    pub fn gzip(mut self, on: bool) -> Self {
44        self.gzip = on;
45        self
46    }
47
48    pub fn brotli(mut self, on: bool) -> Self {
49        self.brotli = on;
50        self
51    }
52
53    pub fn deflate(mut self, on: bool) -> Self {
54        self.deflate = on;
55        self
56    }
57
58    pub fn zstd(mut self, on: bool) -> Self {
59        self.zstd = on;
60        self
61    }
62
63    pub fn max_body_size(mut self, bytes: usize) -> Self {
64        self.max_body_size = bytes;
65        self
66    }
67
68    pub fn max_error_body(mut self, bytes: usize) -> Self {
69        self.max_error_body = bytes;
70        self
71    }
72
73    pub(crate) fn accept_encoding(&self) -> Option<String> {
74        let codecs = [
75            ("gzip", self.gzip && cfg!(feature = "compression-gzip")),
76            (
77                "deflate",
78                self.deflate && cfg!(feature = "compression-deflate"),
79            ),
80            ("br", self.brotli && cfg!(feature = "compression-brotli")),
81            ("zstd", self.zstd && cfg!(feature = "compression-zstd")),
82        ];
83        let enabled: Vec<&str> = codecs
84            .iter()
85            .filter(|(_, on)| *on)
86            .map(|(name, _)| *name)
87            .collect();
88        (!enabled.is_empty()).then(|| enabled.join(", "))
89    }
90
91    pub(crate) fn allows(&self, encoding: &str) -> bool {
92        match encoding {
93            "gzip" | "x-gzip" => self.gzip,
94            "br" => self.brotli,
95            "deflate" => self.deflate,
96            "zstd" => self.zstd,
97            "identity" | "" => true,
98            _ => false,
99        }
100    }
101}