1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//! Auto-managed Byparr/FlareSolverr client for bypassing bot detection.
//!
//! Provides a unified client for the FlareSolverr-compatible API used by both
//! [Byparr](https://github.com/thephaseless/byparr) and
//! [FlareSolverr](https://github.com/FlareSolverr/FlareSolverr).
//!
//! # Features
//! - Automatic Docker container lifecycle (pull, start, health-wait, restart, drop)
//! - Provider-agnostic: Byparr, FlareSolverr, or any compatible image
//! - Builder-style [`SolveRequest`] with GET/POST, headers, cookies, proxy, sessions, fingerprint
//! - Per-domain session/cookie cache so repeat solves are free
//! - Concurrent-solve coalescer that dedupes parallel solves
//! - Retry policy with exponential backoff
//! - Lock-free [`MetricsSnapshot`] for observability
//! - Optional disk-replay sink for debugging
//! - Round-robin across multiple instances
//! - `solve_stream` for batch use with bounded concurrency
//! - Standalone [`detect`] helpers for cheap challenge fingerprinting
//!
//! # Quick start
//! ```no_run
//! use antibot_rs::{Antibot, Provider};
//!
//! # async fn example() -> Result<(), antibot_rs::AntibotError> {
//! let client = Antibot::builder()
//! .provider(Provider::Byparr)
//! .auto_start(true)
//! .enable_session_cache()
//! .build()
//! .await?;
//!
//! let solution = client.solve("https://example.com").await?;
//! println!("Got {} bytes of HTML", solution.html().len());
//! # Ok(())
//! # }
//! ```
//!
//! # Full-featured example
//! ```no_run
//! use antibot_rs::{
//! Antibot, CoalesceKey, Cookie, DebugConfig, DockerLimits, ProxyConfig,
//! Provider, RetryPolicy, SolveRequest,
//! };
//! use std::time::Duration;
//!
//! # async fn example() -> Result<(), antibot_rs::AntibotError> {
//! let client = Antibot::builder()
//! .provider(Provider::Byparr)
//! .auto_start(true)
//! .docker_limits(DockerLimits::default().memory("2g").cpus("1.5").shm_size("1g"))
//! .enable_session_cache()
//! .coalesce_solves(CoalesceKey::Domain)
//! .retry(RetryPolicy::default())
//! .default_proxy(ProxyConfig::http("http://proxy.example:8080"))
//! .debug(DebugConfig::new("./antibot-replay"))
//! .health_watch(Duration::from_secs(30))
//! .manage_lifecycle(true)
//! .build()
//! .await?;
//!
//! let solution = client.execute(
//! SolveRequest::post("https://site.com/api/login")
//! .json(serde_json::json!({"user": "alice"}))
//! .with_header("X-Custom", "value")
//! .with_cookie(Cookie::new("session", "abc123"))
//! ).await?;
//! # let _ = solution;
//! # Ok(())
//! # }
//! ```
pub use ;
pub use CoalesceKey;
pub use ;
pub use DebugConfig;
pub use ;
pub use DockerLimits;
pub use AntibotError;
pub use ;
pub use MetricsSnapshot;
pub use ProxyConfig;
pub use ;
pub use RetryPolicy;
pub use ;
pub use SolveStream;
pub use ;
/// Re-export of `futures::StreamExt` so callers don't need a direct dep
/// just to consume [`Antibot::solve_stream`].
pub use StreamExt;
/// Docker image provider for the challenge-solving proxy.