Skip to main content

http_encoding/
lib.rs

1//! Content-Encoding support on top of `http` crate
2
3#![forbid(unsafe_code)]
4
5pub mod error;
6
7#[macro_use]
8mod coder;
9mod coding;
10mod decode;
11
12#[cfg(any(feature = "br", feature = "gz", feature = "de", feature = "zs"))]
13mod writer;
14
15#[cfg(feature = "br")]
16mod brotli {
17    use std::io::{self, Write};
18
19    use brotli2::write::{BrotliDecoder, BrotliEncoder};
20    use bytes::Bytes;
21
22    use super::{coder::Code, writer::BytesMutWriter};
23
24    pub struct Decoder(Option<BrotliDecoder<BytesMutWriter>>);
25
26    impl Decoder {
27        pub(crate) fn new() -> Self {
28            Self(Some(BrotliDecoder::new(BytesMutWriter::new())))
29        }
30    }
31
32    pub struct Encoder(Option<BrotliEncoder<BytesMutWriter>>);
33
34    impl Encoder {
35        pub(crate) fn new(level: u32) -> Self {
36            Self(Some(BrotliEncoder::new(BytesMutWriter::new(), level)))
37        }
38    }
39
40    impl<T> Code<T> for Decoder
41    where
42        T: AsRef<[u8]>,
43    {
44        type Item = Bytes;
45
46        fn code(&mut self, item: T) -> io::Result<Option<Self::Item>> {
47            let decoder = self.0.as_mut().unwrap();
48            decoder.write_all(item.as_ref())?;
49            decoder.flush()?;
50            let b = decoder.get_mut().take();
51            if !b.is_empty() { Ok(Some(b)) } else { Ok(None) }
52        }
53
54        fn code_eof(&mut self) -> io::Result<Option<Self::Item>> {
55            match self.0.take() {
56                Some(mut decoder) => {
57                    let b = decoder.finish()?.take_owned();
58                    Ok(Some(b))
59                }
60                None => Ok(None),
61            }
62        }
63
64        #[inline]
65        fn is_end_stream(&self, _: &impl http_body_alt::Body) -> bool {
66            self.0.is_none()
67        }
68    }
69
70    impl<T> Code<T> for Encoder
71    where
72        T: AsRef<[u8]>,
73    {
74        type Item = Bytes;
75
76        fn code(&mut self, item: T) -> io::Result<Option<Self::Item>> {
77            let encoder = self.0.as_mut().unwrap();
78            encoder.write_all(item.as_ref())?;
79            encoder.flush()?;
80            let b = encoder.get_mut().take();
81            if !b.is_empty() { Ok(Some(b)) } else { Ok(None) }
82        }
83
84        fn code_eof(&mut self) -> io::Result<Option<Self::Item>> {
85            match self.0.take() {
86                Some(encoder) => {
87                    let b = encoder.finish()?.take_owned();
88                    Ok(Some(b))
89                }
90                None => Ok(None),
91            }
92        }
93
94        #[inline]
95        fn is_end_stream(&self, _: &impl http_body_alt::Body) -> bool {
96            self.0.is_none()
97        }
98    }
99}
100
101#[cfg(feature = "gz")]
102mod gzip {
103    use super::writer::BytesMutWriter;
104
105    use flate2::write::{GzDecoder, GzEncoder};
106
107    pub type Decoder = GzDecoder<BytesMutWriter>;
108    pub type Encoder = GzEncoder<BytesMutWriter>;
109
110    code_impl!(GzDecoder);
111    code_impl!(GzEncoder);
112}
113
114#[cfg(feature = "de")]
115mod deflate {
116    use super::writer::BytesMutWriter;
117
118    use flate2::write::{DeflateDecoder, DeflateEncoder};
119
120    pub type Decoder = DeflateDecoder<BytesMutWriter>;
121    pub type Encoder = DeflateEncoder<BytesMutWriter>;
122
123    code_impl!(DeflateDecoder);
124    code_impl!(DeflateEncoder);
125}
126
127#[cfg(feature = "zs")]
128mod zstandard {
129    use std::io::{self, Write};
130
131    use bytes::Bytes;
132    use zstd::stream::write::{Decoder as ZstdDecoder, Encoder as ZstdEncoder};
133
134    use super::{coder::Code, writer::BytesMutWriter};
135
136    pub struct Decoder(Option<ZstdDecoder<'static, BytesMutWriter>>);
137
138    impl Decoder {
139        pub(crate) fn new() -> Self {
140            Self(Some(ZstdDecoder::new(BytesMutWriter::new()).unwrap()))
141        }
142    }
143
144    pub struct Encoder(Option<ZstdEncoder<'static, BytesMutWriter>>);
145
146    impl Encoder {
147        pub(crate) fn new(level: i32) -> Self {
148            Self(Some(ZstdEncoder::new(BytesMutWriter::new(), level).unwrap()))
149        }
150    }
151
152    impl<T> Code<T> for Decoder
153    where
154        T: AsRef<[u8]>,
155    {
156        type Item = Bytes;
157
158        fn code(&mut self, item: T) -> io::Result<Option<Self::Item>> {
159            let decoder = self.0.as_mut().unwrap();
160            decoder.write_all(item.as_ref())?;
161            decoder.flush()?;
162            let b = decoder.get_mut().take();
163            if !b.is_empty() { Ok(Some(b)) } else { Ok(None) }
164        }
165
166        fn code_eof(&mut self) -> io::Result<Option<Self::Item>> {
167            match self.0.take() {
168                Some(decoder) => {
169                    let b = decoder.into_inner().take_owned();
170                    Ok(Some(b))
171                }
172                None => Ok(None),
173            }
174        }
175
176        #[inline]
177        fn is_end_stream(&self, _: &impl http_body_alt::Body) -> bool {
178            self.0.is_none()
179        }
180    }
181
182    impl<T> Code<T> for Encoder
183    where
184        T: AsRef<[u8]>,
185    {
186        type Item = Bytes;
187
188        fn code(&mut self, item: T) -> io::Result<Option<Self::Item>> {
189            let encoder = self.0.as_mut().unwrap();
190            encoder.write_all(item.as_ref())?;
191            encoder.flush()?;
192            let b = encoder.get_mut().take();
193            if !b.is_empty() { Ok(Some(b)) } else { Ok(None) }
194        }
195
196        fn code_eof(&mut self) -> io::Result<Option<Self::Item>> {
197            match self.0.take() {
198                Some(encoder) => {
199                    let b = encoder.finish()?.take_owned();
200                    Ok(Some(b))
201                }
202                None => Ok(None),
203            }
204        }
205
206        #[inline]
207        fn is_end_stream(&self, _: &impl http_body_alt::Body) -> bool {
208            self.0.is_none()
209        }
210    }
211}
212
213pub use self::coder::{Code, Coder, FeaturedCode};
214pub use self::coding::ContentEncoding;
215pub use self::decode::try_decoder;