reqwest_proxy_pool/
config.rs1use crate::classifier::{DefaultResponseClassifier, ResponseClassifier};
4use std::fmt;
5use std::sync::Arc;
6use std::time::Duration;
7
8#[derive(Debug, Clone, Copy, PartialEq)]
10pub enum ProxySelectionStrategy {
11 FastestResponse,
13 MostReliable,
15 Random,
17 RoundRobin,
19}
20
21#[derive(Clone)]
23pub struct ProxyPoolConfig {
24 pub(crate) sources: Vec<String>,
26 pub(crate) health_check_interval: Duration,
28 pub(crate) health_check_timeout: Duration,
30 pub(crate) min_available_proxies: usize,
32 pub(crate) health_check_url: String,
34 pub(crate) retry_count: usize,
36 pub(crate) selection_strategy: ProxySelectionStrategy,
38 pub(crate) max_requests_per_second: f64,
40 pub(crate) response_classifier: Arc<dyn ResponseClassifier>,
42 pub(crate) danger_accept_invalid_certs: bool,
44}
45
46impl fmt::Debug for ProxyPoolConfig {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 f.debug_struct("ProxyPoolConfig")
49 .field("sources", &self.sources)
50 .field("health_check_interval", &self.health_check_interval)
51 .field("health_check_timeout", &self.health_check_timeout)
52 .field("min_available_proxies", &self.min_available_proxies)
53 .field("health_check_url", &self.health_check_url)
54 .field("retry_count", &self.retry_count)
55 .field("selection_strategy", &self.selection_strategy)
56 .field("max_requests_per_second", &self.max_requests_per_second)
57 .field("response_classifier", &"<dyn ResponseClassifier>")
58 .field(
59 "danger_accept_invalid_certs",
60 &self.danger_accept_invalid_certs,
61 )
62 .finish()
63 }
64}
65
66impl ProxyPoolConfig {
67 pub fn builder() -> ProxyPoolConfigBuilder {
69 ProxyPoolConfigBuilder::new()
70 }
71
72 pub fn sources(&self) -> &[String] {
74 &self.sources
75 }
76
77 pub fn health_check_interval(&self) -> Duration {
79 self.health_check_interval
80 }
81
82 pub fn health_check_timeout(&self) -> Duration {
84 self.health_check_timeout
85 }
86
87 pub fn min_available_proxies(&self) -> usize {
89 self.min_available_proxies
90 }
91
92 pub fn health_check_url(&self) -> &str {
94 &self.health_check_url
95 }
96
97 pub fn retry_count(&self) -> usize {
99 self.retry_count
100 }
101
102 pub fn selection_strategy(&self) -> ProxySelectionStrategy {
104 self.selection_strategy
105 }
106
107 pub fn max_requests_per_second(&self) -> f64 {
109 self.max_requests_per_second
110 }
111
112 pub fn response_classifier(&self) -> &Arc<dyn ResponseClassifier> {
114 &self.response_classifier
115 }
116
117 pub fn danger_accept_invalid_certs(&self) -> bool {
119 self.danger_accept_invalid_certs
120 }
121}
122
123pub struct ProxyPoolConfigBuilder {
125 sources: Vec<String>,
126 health_check_interval: Option<Duration>,
127 health_check_timeout: Option<Duration>,
128 min_available_proxies: Option<usize>,
129 health_check_url: Option<String>,
130 retry_count: Option<usize>,
131 selection_strategy: Option<ProxySelectionStrategy>,
132 max_requests_per_second: Option<f64>,
133 response_classifier: Option<Arc<dyn ResponseClassifier>>,
134 danger_accept_invalid_certs: bool,
135}
136
137impl ProxyPoolConfigBuilder {
138 pub fn new() -> Self {
140 Self {
141 sources: Vec::new(),
142 health_check_interval: None,
143 health_check_timeout: None,
144 min_available_proxies: None,
145 health_check_url: None,
146 retry_count: None,
147 selection_strategy: None,
148 max_requests_per_second: None,
149 response_classifier: None,
150 danger_accept_invalid_certs: false,
151 }
152 }
153
154 pub fn sources(mut self, sources: Vec<impl Into<String>>) -> Self {
156 self.sources = sources.into_iter().map(Into::into).collect();
157 self
158 }
159
160 pub fn health_check_interval(mut self, interval: Duration) -> Self {
162 self.health_check_interval = Some(interval);
163 self
164 }
165
166 pub fn health_check_timeout(mut self, timeout: Duration) -> Self {
168 self.health_check_timeout = Some(timeout);
169 self
170 }
171
172 pub fn min_available_proxies(mut self, count: usize) -> Self {
174 self.min_available_proxies = Some(count);
175 self
176 }
177
178 pub fn health_check_url(mut self, url: impl Into<String>) -> Self {
180 self.health_check_url = Some(url.into());
181 self
182 }
183
184 pub fn retry_count(mut self, count: usize) -> Self {
186 self.retry_count = Some(count);
187 self
188 }
189
190 pub fn selection_strategy(mut self, strategy: ProxySelectionStrategy) -> Self {
192 self.selection_strategy = Some(strategy);
193 self
194 }
195
196 pub fn max_requests_per_second(mut self, rps: f64) -> Self {
198 self.max_requests_per_second = Some(rps);
199 self
200 }
201
202 pub fn response_classifier(mut self, classifier: impl ResponseClassifier) -> Self {
207 self.response_classifier = Some(Arc::new(classifier));
208 self
209 }
210
211 pub fn danger_accept_invalid_certs(mut self, accept: bool) -> Self {
215 self.danger_accept_invalid_certs = accept;
216 self
217 }
218
219 pub fn build(self) -> ProxyPoolConfig {
221 ProxyPoolConfig {
222 sources: self.sources,
223 health_check_interval: self
224 .health_check_interval
225 .unwrap_or(Duration::from_secs(300)),
226 health_check_timeout: self.health_check_timeout.unwrap_or(Duration::from_secs(10)),
227 min_available_proxies: self.min_available_proxies.unwrap_or(3),
228 health_check_url: self
229 .health_check_url
230 .unwrap_or_else(|| "https://www.google.com".to_string()),
231 retry_count: self.retry_count.unwrap_or(3),
232 selection_strategy: self
233 .selection_strategy
234 .unwrap_or(ProxySelectionStrategy::FastestResponse),
235 max_requests_per_second: self.max_requests_per_second.unwrap_or(5.0),
236 response_classifier: self
237 .response_classifier
238 .unwrap_or_else(|| Arc::new(DefaultResponseClassifier)),
239 danger_accept_invalid_certs: self.danger_accept_invalid_certs,
240 }
241 }
242}
243
244impl Default for ProxyPoolConfigBuilder {
245 fn default() -> Self {
246 Self::new()
247 }
248}