rustapi_ws/
compression.rs1#[derive(Debug, Clone, Copy)]
7pub struct WsCompressionConfig {
8 pub min_size: usize,
10 pub window_bits: u8,
12 pub client_window_bits: u8,
14}
15
16impl Default for WsCompressionConfig {
17 fn default() -> Self {
18 Self {
19 min_size: 256,
20 window_bits: 15,
21 client_window_bits: 15,
22 }
23 }
24}
25
26impl WsCompressionConfig {
27 pub fn new() -> Self {
29 Self::default()
30 }
31
32 pub fn min_size(mut self, size: usize) -> Self {
34 self.min_size = size;
35 self
36 }
37
38 pub fn window_bits(mut self, bits: u8) -> Self {
40 self.window_bits = bits.clamp(9, 15);
41 self
42 }
43
44 pub fn client_window_bits(mut self, bits: u8) -> Self {
46 self.client_window_bits = bits.clamp(9, 15);
47 self
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54 use crate::WebSocketUpgrade;
55 use proptest::prelude::*;
56
57 proptest! {
58 #[test]
59 fn test_compression_negotiation(
60 min_size in 0usize..10000,
61 window_bits in 9u8..15,
62 client_window_bits in 9u8..15,
63 client_supports_compression in proptest::bool::ANY,
64 ) {
65 let config = WsCompressionConfig::new()
66 .min_size(min_size)
67 .window_bits(window_bits)
68 .client_window_bits(client_window_bits);
69
70 let client_extensions = if client_supports_compression {
71 Some(
72 "permessage-deflate; server_max_window_bits=15; client_max_window_bits"
73 .to_string(),
74 )
75 } else {
76 None
77 };
78
79 let upgrade = WebSocketUpgrade::new(
80 "dGhlIHNhbXBsZSBub25jZQ==".to_string(),
81 client_extensions,
82 None, )
84 .compress(config);
85
86 let response = upgrade.into_response_inner();
87 let ext_header = response.headers().get("Sec-WebSocket-Extensions");
88
89 if client_supports_compression {
90 assert!(ext_header.is_some(), "Header missing when client supports compression");
91 let header_str = ext_header.unwrap().to_str().unwrap();
92 assert!(header_str.contains("permessage-deflate"));
93
94 if window_bits < 15 {
95 assert!(header_str.contains(&format!("server_max_window_bits={}", window_bits)));
96 }
97 if client_window_bits < 15 {
98 assert!(header_str.contains(&format!("client_max_window_bits={}", client_window_bits)));
99 }
100 } else {
101 assert!(ext_header.is_none());
102 }
103 }
104 }
105}