Skip to main content

wreq_util/emulate/
compress.rs

1//! Compression algorithms for TLS 1.3 certificate compression.
2
3use brotli::{CompressorWriter as BrotliEncoder, Decompressor as BrotliDecoder};
4use flate2::{Compression, read::ZlibDecoder, write::ZlibEncoder};
5use std::io::{self, Write};
6use wreq::tls::compress::{CertificateCompressionAlgorithm, CertificateCompressor, Codec};
7use zstd::stream::{Decoder as ZstdDecoder, Encoder as ZstdEncoder};
8
9#[derive(Debug)]
10pub struct BrotliCompressor;
11
12#[derive(Debug)]
13pub struct ZlibCompressor;
14
15#[derive(Debug)]
16pub struct ZstdCompressor;
17
18impl CertificateCompressor for BrotliCompressor {
19    fn compress(&self) -> Codec {
20        Codec::Pointer(|input, output| {
21            let mut writer = BrotliEncoder::new(output, input.len(), 11, 32);
22            writer.write_all(input)?;
23            writer.flush()?;
24            Ok(())
25        })
26    }
27
28    fn decompress(&self) -> Codec {
29        Codec::Pointer(|input, output| {
30            let mut reader = BrotliDecoder::new(input, 4096);
31            io::copy(&mut reader, output)?;
32            Ok(())
33        })
34    }
35
36    fn algorithm(&self) -> CertificateCompressionAlgorithm {
37        CertificateCompressionAlgorithm::BROTLI
38    }
39}
40
41impl CertificateCompressor for ZlibCompressor {
42    fn compress(&self) -> Codec {
43        Codec::Pointer(|input, output| {
44            let mut encoder = ZlibEncoder::new(output, Compression::default());
45            encoder.write_all(input)?;
46            encoder.finish()?;
47            Ok(())
48        })
49    }
50
51    fn decompress(&self) -> Codec {
52        Codec::Pointer(|input, output| {
53            let mut reader = ZlibDecoder::new(input);
54            io::copy(&mut reader, output)?;
55            Ok(())
56        })
57    }
58
59    fn algorithm(&self) -> CertificateCompressionAlgorithm {
60        CertificateCompressionAlgorithm::ZLIB
61    }
62}
63
64impl CertificateCompressor for ZstdCompressor {
65    fn compress(&self) -> Codec {
66        Codec::Pointer(|input, output| {
67            let mut encoder = ZstdEncoder::new(output, 0)?;
68            encoder.write_all(input)?;
69            encoder.finish()?;
70            Ok(())
71        })
72    }
73
74    fn decompress(&self) -> Codec {
75        Codec::Pointer(|input, output| {
76            let mut reader = ZstdDecoder::new(input)?;
77            io::copy(&mut reader, output)?;
78            Ok(())
79        })
80    }
81
82    fn algorithm(&self) -> CertificateCompressionAlgorithm {
83        CertificateCompressionAlgorithm::ZSTD
84    }
85}