blitz_ws/protocol/config.rs
1//! WebSocket configuration module
2
3use crate::protocol::compression::WebSocketCompressionConfig;
4
5/// The configuration for WebSocket connection.
6///
7/// # Example
8/// ```
9/// # use blitz::protocol::WebSocketConfig;;
10/// let conf = WebSocketConfig::default()
11/// .read_buffer_size(256 * 1024)
12/// .write_buffer_size(256 * 1024);
13/// ```
14#[derive(Debug, Clone, Copy)]
15#[non_exhaustive]
16pub struct WebSocketConfig {
17 /// Read buffer capacity. This buffer is eagerly allocated and used for receiving
18 /// messages.
19 ///
20 /// For high read load scenarios a larger buffer, e.g. 128 KiB, improves performance.
21 ///
22 /// For scenarios where you expect a lot of connections and don't need high read load
23 /// performance a smaller buffer, e.g. 4 KiB, would be appropriate to lower total
24 /// memory usage.
25 ///
26 /// The default value is 128 KiB.
27 pub read_buffer_size: usize,
28 /// The target minimum size of the write buffer to reach before writing the data
29 /// to the underlying stream.
30 /// The default value is 128 KiB.
31 ///
32 /// If set to `0` each message will be eagerly written to the underlying stream.
33 /// It is often more optimal to allow them to buffer a little, hence the default value.
34 ///
35 /// Note: [`flush`](WebSocket::flush) will always fully write the buffer regardless.
36 pub write_buffer_size: usize,
37 /// The max size of the write buffer in bytes. Setting this can provide backpressure
38 /// in the case the write buffer is filling up due to write errors.
39 /// The default value is unlimited.
40 ///
41 /// Note: The write buffer only builds up past [`write_buffer_size`](Self::write_buffer_size)
42 /// when writes to the underlying stream are failing. So the **write buffer can not
43 /// fill up if you are not observing write errors even if not flushing**.
44 ///
45 /// Note: Should always be at least [`write_buffer_size + 1 message`](Self::write_buffer_size)
46 /// and probably a little more depending on error handling strategy.
47 pub max_write_buffer_size: usize,
48 /// The maximum size of an incoming message. `None` means no size limit. The default value is 64 MiB
49 /// which should be reasonably big for all normal use-cases but small enough to prevent
50 /// memory eating by a malicious user.
51 pub max_message_size: Option<usize>,
52 /// The maximum size of a single incoming message frame. `None` means no size limit. The limit is for
53 /// frame payload NOT including the frame header. The default value is 16 MiB which should
54 /// be reasonably big for all normal use-cases but small enough to prevent memory eating
55 /// by a malicious user.
56 pub max_frame_size: Option<usize>,
57 /// When set to `true`, the server will accept and handle unmasked frames
58 /// from the client. According to the RFC 6455, the server must close the
59 /// connection to the client in such cases, however it seems like there are
60 /// some popular libraries that are sending unmasked frames, ignoring the RFC.
61 /// By default this option is set to `false`, i.e. according to RFC 6455.
62 pub accept_unmasked_frames: bool,
63 /// Configuration for compression module
64 pub compression: WebSocketCompressionConfig,
65}
66
67impl Default for WebSocketConfig {
68 fn default() -> Self {
69 Self {
70 read_buffer_size: 128 * 1024,
71 write_buffer_size: 128 * 1024,
72 max_write_buffer_size: usize::MAX,
73 max_message_size: Some(64 << 20),
74 max_frame_size: Some(64 << 20),
75 accept_unmasked_frames: false,
76 compression: WebSocketCompressionConfig::default(),
77 }
78 }
79}
80
81impl WebSocketConfig {
82 /// Set [`Self::read_buffer_size`].
83 pub fn read_buffer_size(mut self, size: usize) -> Self {
84 assert!(size > 0);
85 self.read_buffer_size = size;
86 self
87 }
88
89 /// Set [`Self::write_buffer_size`].
90 pub fn write_buffer_size(mut self, size: usize) -> Self {
91 assert!(size > 0);
92 self.write_buffer_size = size;
93 self
94 }
95
96 /// Set [`Self::max_write_buffer_size`].
97 pub fn max_write_buffer_size(mut self, size: usize) -> Self {
98 assert!(size > 0);
99 self.max_write_buffer_size = size;
100 self
101 }
102
103 /// Set [`Self::max_message_size`].
104 pub fn max_message_size(mut self, size: Option<usize>) -> Self {
105 assert!(if size.is_some() { size.unwrap() > 0 } else { true });
106 self.max_message_size = size;
107 self
108 }
109
110 /// Set [`Self::max_frame_size`].
111 pub fn max_frame_size(mut self, size: Option<usize>) -> Self {
112 assert!(if size.is_some() { size.unwrap() > 0 } else { true });
113 self.max_frame_size = size;
114 self
115 }
116
117 /// Set [`Self::accept_unmasked_frames`].
118 pub fn accept_unmasked_frames(mut self, accept_unmasked_frames: bool) -> Self {
119 self.accept_unmasked_frames = accept_unmasked_frames;
120 self
121 }
122
123 /// Panic if values are invalid.
124 pub(crate) fn asset_valid(&self) {
125 assert!(
126 self.max_write_buffer_size > self.write_buffer_size,
127 "WebSocketConfig::max_write_buffer_size must be greater than write_buffer_size, \
128 see WebSocketConfig docs`"
129 );
130 }
131}