proxy_protocol_rs/
config.rs1use std::fmt;
16use std::sync::Arc;
17use std::time::Duration;
18
19use crate::policy::{AcceptAll, ConnPolicy};
20use crate::validator::HeaderValidator;
21
22pub struct ProxyProtocolConfig {
24 pub header_timeout: Duration,
27
28 pub max_header_size: usize,
31
32 pub max_pending_handshakes: usize,
35
36 pub policy: Arc<dyn ConnPolicy>,
39
40 pub validator: Option<Arc<dyn HeaderValidator>>,
43
44 pub version: VersionPreference,
47}
48
49impl Default for ProxyProtocolConfig {
50 fn default() -> Self {
51 Self {
52 header_timeout: Duration::from_secs(5),
53 max_header_size: 4096,
54 max_pending_handshakes: 1024,
55 policy: Arc::new(AcceptAll),
56 validator: None,
57 version: VersionPreference::Both,
58 }
59 }
60}
61
62impl ProxyProtocolConfig {
63 pub fn builder() -> ConfigBuilder {
64 ConfigBuilder::default()
65 }
66}
67
68pub struct ConfigBuilder {
69 header_timeout: Duration,
70 max_header_size: usize,
71 max_pending_handshakes: usize,
72 policy: Arc<dyn ConnPolicy>,
73 validator: Option<Arc<dyn HeaderValidator>>,
74 version: VersionPreference,
75}
76
77impl Default for ConfigBuilder {
78 fn default() -> Self {
79 Self {
80 header_timeout: Duration::from_secs(5),
81 max_header_size: 4096,
82 max_pending_handshakes: 1024,
83 policy: Arc::new(AcceptAll),
84 validator: None,
85 version: VersionPreference::Both,
86 }
87 }
88}
89
90impl ConfigBuilder {
91 pub fn header_timeout(mut self, timeout: Duration) -> Self {
92 self.header_timeout = timeout;
93 self
94 }
95
96 pub fn max_header_size(mut self, size: usize) -> Self {
97 self.max_header_size = size;
98 self
99 }
100
101 pub fn max_pending_handshakes(mut self, limit: usize) -> Self {
102 self.max_pending_handshakes = limit;
103 self
104 }
105
106 pub fn policy(mut self, policy: impl ConnPolicy) -> Self {
107 self.policy = Arc::new(policy);
108 self
109 }
110
111 pub fn validator(mut self, validator: impl HeaderValidator) -> Self {
112 self.validator = Some(Arc::new(validator));
113 self
114 }
115
116 pub fn version(mut self, version: VersionPreference) -> Self {
117 self.version = version;
118 self
119 }
120
121 pub fn build(self) -> Result<ProxyProtocolConfig, ConfigError> {
122 if self.header_timeout.is_zero() {
123 return Err(ConfigError("header_timeout must be greater than zero"));
124 }
125 if self.max_header_size == 0 {
126 return Err(ConfigError("max_header_size must be greater than zero"));
127 }
128 if self.max_pending_handshakes == 0 {
129 return Err(ConfigError(
130 "max_pending_handshakes must be greater than zero",
131 ));
132 }
133 Ok(ProxyProtocolConfig {
134 header_timeout: self.header_timeout,
135 max_header_size: self.max_header_size,
136 max_pending_handshakes: self.max_pending_handshakes,
137 policy: self.policy,
138 validator: self.validator,
139 version: self.version,
140 })
141 }
142}
143
144#[derive(Debug, Clone, PartialEq, Eq)]
145pub struct ConfigError(pub &'static str);
146
147impl fmt::Display for ConfigError {
148 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149 f.write_str(self.0)
150 }
151}
152
153impl std::error::Error for ConfigError {}
154
155#[derive(Debug, Clone, Copy, PartialEq, Eq)]
156#[non_exhaustive]
157pub enum VersionPreference {
158 Both,
159 V1Only,
160 V2Only,
163}