1use std::net::SocketAddr;
4use std::time::Duration;
5
6use crate::protocol::constants::*;
7
8#[derive(Debug, Clone)]
10pub struct ServerConfig {
11 pub bind_addr: SocketAddr,
13
14 pub max_connections: usize,
16
17 pub chunk_size: u32,
19
20 pub window_ack_size: u32,
22
23 pub peer_bandwidth: u32,
25
26 pub connection_timeout: Duration,
28
29 pub idle_timeout: Duration,
31
32 pub tcp_nodelay: bool,
34
35 pub tcp_recv_buffer: usize,
37
38 pub tcp_send_buffer: usize,
40
41 pub read_buffer_size: usize,
43
44 pub write_buffer_size: usize,
46
47 pub gop_buffer_enabled: bool,
49
50 pub gop_buffer_max_size: usize,
52
53 pub stats_interval: Duration,
55}
56
57impl Default for ServerConfig {
58 fn default() -> Self {
59 Self {
60 bind_addr: "0.0.0.0:1935".parse().unwrap(),
61 max_connections: 0, chunk_size: RECOMMENDED_CHUNK_SIZE,
63 window_ack_size: DEFAULT_WINDOW_ACK_SIZE,
64 peer_bandwidth: DEFAULT_PEER_BANDWIDTH,
65 connection_timeout: Duration::from_secs(10),
66 idle_timeout: Duration::from_secs(60),
67 tcp_nodelay: true, tcp_recv_buffer: 0,
69 tcp_send_buffer: 0,
70 read_buffer_size: 64 * 1024, write_buffer_size: 64 * 1024,
72 gop_buffer_enabled: true,
73 gop_buffer_max_size: 4 * 1024 * 1024, stats_interval: Duration::from_secs(5),
75 }
76 }
77}
78
79impl ServerConfig {
80 pub fn with_addr(addr: SocketAddr) -> Self {
82 Self {
83 bind_addr: addr,
84 ..Default::default()
85 }
86 }
87
88 pub fn bind(mut self, addr: SocketAddr) -> Self {
90 self.bind_addr = addr;
91 self
92 }
93
94 pub fn max_connections(mut self, max: usize) -> Self {
96 self.max_connections = max;
97 self
98 }
99
100 pub fn chunk_size(mut self, size: u32) -> Self {
102 self.chunk_size = size.min(MAX_CHUNK_SIZE);
103 self
104 }
105
106 pub fn disable_gop_buffer(mut self) -> Self {
108 self.gop_buffer_enabled = false;
109 self
110 }
111
112 pub fn connection_timeout(mut self, timeout: Duration) -> Self {
114 self.connection_timeout = timeout;
115 self
116 }
117
118 pub fn idle_timeout(mut self, timeout: Duration) -> Self {
120 self.idle_timeout = timeout;
121 self
122 }
123}
124
125#[cfg(test)]
126mod tests {
127 use super::*;
128
129 #[test]
130 fn test_default_config() {
131 let config = ServerConfig::default();
132
133 assert_eq!(config.bind_addr.port(), 1935);
134 assert_eq!(config.max_connections, 0);
135 assert_eq!(config.chunk_size, RECOMMENDED_CHUNK_SIZE);
136 assert_eq!(config.window_ack_size, DEFAULT_WINDOW_ACK_SIZE);
137 assert_eq!(config.peer_bandwidth, DEFAULT_PEER_BANDWIDTH);
138 assert!(config.tcp_nodelay);
139 assert!(config.gop_buffer_enabled);
140 }
141
142 #[test]
143 fn test_with_addr() {
144 let addr: SocketAddr = "127.0.0.1:1936".parse().unwrap();
145 let config = ServerConfig::with_addr(addr);
146
147 assert_eq!(config.bind_addr.port(), 1936);
148 }
149
150 #[test]
151 fn test_builder_bind() {
152 let addr: SocketAddr = "0.0.0.0:8080".parse().unwrap();
153 let config = ServerConfig::default().bind(addr);
154
155 assert_eq!(config.bind_addr, addr);
156 }
157
158 #[test]
159 fn test_builder_max_connections() {
160 let config = ServerConfig::default().max_connections(100);
161
162 assert_eq!(config.max_connections, 100);
163 }
164
165 #[test]
166 fn test_builder_chunk_size() {
167 let config = ServerConfig::default().chunk_size(8192);
168
169 assert_eq!(config.chunk_size, 8192);
170 }
171
172 #[test]
173 fn test_builder_chunk_size_capped() {
174 let config = ServerConfig::default().chunk_size(u32::MAX);
176
177 assert_eq!(config.chunk_size, MAX_CHUNK_SIZE);
178 }
179
180 #[test]
181 fn test_builder_disable_gop_buffer() {
182 let config = ServerConfig::default().disable_gop_buffer();
183
184 assert!(!config.gop_buffer_enabled);
185 }
186
187 #[test]
188 fn test_builder_connection_timeout() {
189 let config = ServerConfig::default().connection_timeout(Duration::from_secs(30));
190
191 assert_eq!(config.connection_timeout, Duration::from_secs(30));
192 }
193
194 #[test]
195 fn test_builder_idle_timeout() {
196 let config = ServerConfig::default().idle_timeout(Duration::from_secs(120));
197
198 assert_eq!(config.idle_timeout, Duration::from_secs(120));
199 }
200
201 #[test]
202 fn test_builder_chaining() {
203 let addr: SocketAddr = "127.0.0.1:1935".parse().unwrap();
204 let config = ServerConfig::default()
205 .bind(addr)
206 .max_connections(50)
207 .chunk_size(4096)
208 .connection_timeout(Duration::from_secs(5))
209 .idle_timeout(Duration::from_secs(30))
210 .disable_gop_buffer();
211
212 assert_eq!(config.bind_addr, addr);
213 assert_eq!(config.max_connections, 50);
214 assert_eq!(config.chunk_size, 4096);
215 assert_eq!(config.connection_timeout, Duration::from_secs(5));
216 assert_eq!(config.idle_timeout, Duration::from_secs(30));
217 assert!(!config.gop_buffer_enabled);
218 }
219}