Skip to main content

stygian_browser/
lib.rs

1//! # stygian-browser
2//!
3#![doc = include_str!("../README.md")]
4#![allow(clippy::multiple_crate_versions)]
5#![deny(unsafe_code)] // All unsafe usage is confined to #[cfg(test)] modules with explicit #[allow]
6//!
7//! Browser automation and stealth tooling for sites protected by Cloudflare,
8//! `DataDome`, `PerimeterX`, and Akamai Bot Manager.
9//!
10//! ## Features
11//!
12//! - **Browser pooling** — warm pool with min/max sizing, LRU eviction, and backpressure;
13//!   sub-100 ms acquire from the warm queue
14//! - **Anti-detection** — User-Agent patching and plugin population
15//! - **Human behaviour** — Bézier-curve mouse paths, human-paced typing with typos,
16//!   random scroll and micro-interactions
17//! - **Fingerprint generation** — statistically-weighted device profiles matching
18//!   real-world browser market share distributions
19//!
20//! ## Quick Start
21//!
22//! ```rust,no_run
23//! use stygian_browser::{BrowserPool, BrowserConfig, WaitUntil};
24//! use std::time::Duration;
25//!
26//! # async fn run() -> Result<(), Box<dyn std::error::Error>> {
27//!     // Default config: headless, Advanced stealth, pool of 2–10 browsers
28//!     let config = BrowserConfig::default();
29//!     let pool = BrowserPool::new(config).await?;
30//!
31//!     // Acquire a browser from the warm pool (< 100 ms)
32//!     let handle = pool.acquire().await?;
33//!
34//!     // Open a tab and navigate
35//!     let mut page = handle.browser().expect("valid browser").new_page().await?;
36//!     page.navigate(
37//!         "https://example.com",
38//!         WaitUntil::DomContentLoaded,
39//!         Duration::from_secs(30),
40//!     ).await?;
41//!
42//!     println!("Title: {}", page.title().await?);
43//!
44//!     handle.release().await;
45//!     Ok(())
46//! # }
47//! ```
48//!
49//! ## Stealth Levels
50//!
51//! | Level | Navigator spoof | Canvas noise | WebGL random | CDP protection | Human behavior |
52//! | ----- | --------------- | ------------ | ------------ | -------------- | -------------- |
53//! | `None` | — | — | — | — | — |
54//! | `Basic` | ✓ | — | — | ✓ | — |
55//! | `Advanced` | ✓ | ✓ | ✓ | ✓ | ✓ |
56//!
57//! ## Module Overview
58//!
59//! | Module | Description |
60//! | -------- | ------------- |
61//! | [`browser`] | [`BrowserInstance`] — launch, health-check, shutdown |
62//! | [`pool`] | [`BrowserPool`] + [`BrowserHandle`] — warm pool management |
63//! | [`page`] | [`PageHandle`] — navigate, eval, content, cookies |
64//! | [`config`] | [`BrowserConfig`] + builder pattern |
65//! | [`error`] | [`BrowserError`] and [`Result`] alias |
66//! | [`fingerprint`] | [`DeviceProfile`], [`BrowserKind`] |
67//! | [`webrtc`] | [`WebRtcConfig`], [`WebRtcPolicy`], [`ProxyLocation`] |
68//! | [`cdp_protection`] | CDP leak protection modes |
69
70pub mod acquisition;
71pub mod behavior_adapter;
72pub mod browser;
73pub mod cdp_protection;
74pub mod coherence;
75pub mod config;
76pub mod error;
77pub mod freshness;
78pub mod integrity_canary;
79pub mod interstitial_router;
80pub mod page;
81pub mod pool;
82pub mod proxy;
83pub mod replay_defense;
84
85#[cfg(feature = "extract")]
86pub mod extract;
87
88#[cfg(feature = "extract")]
89pub use extract::Extractable;
90
91#[cfg(feature = "similarity")]
92pub mod similarity;
93
94#[cfg(feature = "similarity")]
95pub use similarity::{ElementFingerprint, SimilarMatch, SimilarityConfig};
96
97#[cfg(feature = "stealth")]
98pub mod stealth;
99
100#[cfg(feature = "stealth")]
101pub mod behavior;
102
103#[cfg(feature = "stealth")]
104pub mod fingerprint;
105
106#[cfg(feature = "stealth")]
107pub mod tls;
108
109#[cfg(feature = "stealth")]
110pub mod webrtc;
111
112#[cfg(feature = "stealth")]
113pub mod noise;
114
115#[cfg(feature = "stealth")]
116pub mod canvas_noise;
117
118#[cfg(feature = "stealth")]
119pub mod webgl_noise;
120
121#[cfg(feature = "stealth")]
122pub mod audio_noise;
123
124#[cfg(feature = "stealth")]
125pub mod rects_noise;
126
127#[cfg(feature = "stealth")]
128pub mod cdp_hardening;
129
130#[cfg(feature = "stealth")]
131pub mod peripheral_stealth;
132
133#[cfg(feature = "stealth")]
134pub mod validation;
135
136pub mod tls_validation;
137
138#[cfg(feature = "stealth")]
139pub mod profile;
140
141pub mod transport_realism;
142
143#[cfg(feature = "stealth")]
144pub mod navigator_coherence;
145
146#[cfg(feature = "stealth")]
147pub mod timing_noise;
148
149#[cfg(feature = "stealth")]
150pub mod diagnostic;
151
152#[cfg(feature = "mcp")]
153pub mod mcp;
154
155#[cfg(feature = "metrics")]
156pub mod metrics;
157
158pub mod session;
159
160pub mod recorder;
161
162pub use acquisition::InterstitialContext;
163pub use acquisition::{
164    AcquisitionMode, AcquisitionRequest, AcquisitionResult, AcquisitionRunner,
165    ReplayDefenseContext, StageFailure, StageFailureKind, StrategyUsed, TransportRealismContext,
166};
167pub use behavior_adapter::{
168    AdapterKind, AppliedBehaviorPlan, BehaviorInteractionLevel, BrowserBehaviorAdapter,
169    ExecutionMode, PolymorphicBehaviorAdapter, SessionMode, TelemetryLevel,
170};
171pub use browser::BrowserInstance;
172pub use config::{BrowserConfig, HeadlessMode, StealthLevel};
173pub use error::{BrowserError, Result};
174pub use freshness::{
175    DomainClass, FreshnessCheckInput, FreshnessContract, FreshnessDecision, FreshnessError,
176    FreshnessPolicy, FreshnessPolicyKind, FreshnessReport, InvalidationKind, InvalidationReason,
177    check, signature_hash, unix_epoch_ms,
178};
179pub use integrity_canary::{
180    IntegrityCanaryPolicy, IntegrityCanaryReport, IntegrityProbe, IntegrityProbeId,
181    IntegrityProbeOutcome, IntegrityRiskClassification, IntegrityRiskScore, ProbeFinding,
182    RISK_CONFIRMED_THRESHOLD_DEFAULT, RISK_SUSPECTED_THRESHOLD_DEFAULT,
183    all_probes as all_integrity_probes, probe_by_id as integrity_probe_by_id,
184};
185pub use interstitial_router::{
186    InterstitialClassifier, InterstitialKind, InterstitialPolicy, InterstitialRoute,
187    InterstitialRouter, InterstitialSeverity, PageSignature, RouterDecision, classify_and_route,
188    route,
189};
190pub use page::{
191    NodeHandle, OuterHtmlResult, OuterHtmlStrategy, PageHandle, ResourceFilter, WaitUntil,
192};
193pub use pool::{BrowserHandle, BrowserPool, PoolStats};
194pub use proxy::{DirectLease, ProxyLease, ProxySource};
195pub use replay_defense::{
196    ReplayDefenseCheckInput, ReplayDefenseDecision, ReplayDefenseError,
197    ReplayDefenseInvalidationKind, ReplayDefensePolicy, ReplayDefenseReason, ReplayDefenseReport,
198    ReplayDefenseState,
199};
200pub use transport_realism::{
201    HEADER_ORDER_CHROME_136, HEADER_ORDER_FIREFOX_130, Http2CheckKind, Http2CheckResult,
202    PSEUDO_HEADER_ORDER_CHROME_136, TransportCompatibility, TransportObservation, TransportProfile,
203    TransportRealismReport, score as score_transport_realism,
204};
205
206#[cfg(feature = "stealth")]
207pub use stealth::{NavigatorProfile, StealthConfig, StealthProfile};
208
209#[cfg(feature = "stealth")]
210pub use behavior::InteractionLevel;
211#[cfg(feature = "stealth")]
212pub use behavior::RequestPacer;
213#[cfg(feature = "stealth")]
214pub use fingerprint::{BrowserKind, DeviceProfile};
215
216#[cfg(feature = "stealth")]
217pub use webrtc::{ProxyLocation, WebRtcConfig, WebRtcPolicy};
218
219pub mod prelude {
220    pub use crate::config::BrowserConfig;
221    pub use crate::error::{BrowserError, Result};
222    pub use crate::pool::{BrowserHandle, BrowserPool, PoolStats};
223
224    #[cfg(feature = "stealth")]
225    pub use crate::stealth::{NavigatorProfile, StealthConfig, StealthProfile};
226}