#![forbid(unsafe_code)]
mod builder;
pub(crate) mod decompress;
pub(crate) mod execute;
mod header_merge;
mod helpers;
mod identity;
mod proxy;
mod transport_policy;
#[cfg(feature = "websocket")]
mod websocket;
#[cfg(test)]
mod tests;
pub use builder::SessionBuilder;
pub use identity::{Identity, SessionIdentity};
#[cfg(feature = "websocket")]
pub use websocket::WebSocketBuilder;
use std::sync::{Arc, Mutex};
use url::Url;
use crate::cookie::Jar;
#[cfg(feature = "websocket")]
use crate::core::WebSocketConfig;
use crate::core::retry::RetryPolicy;
use crate::core::{CompressionConfig, ProxyConfig, RedirectPolicy, TimeoutConfig};
use crate::h2::H2Config;
use crate::pool::Pool;
use crate::profile::{Browser, ChromiumBrand, HeaderStyle, Platform};
use crate::tls::FingerprintConnector;
use crate::tls::TlsTrustConfig;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum ProtocolPolicy {
Auto,
Http1,
Http2,
#[cfg(feature = "http3")]
Http3,
#[cfg(feature = "http3")]
Race,
}
impl ProtocolPolicy {
#[cfg(feature = "http3")]
pub(crate) fn requires_h3(self) -> bool {
matches!(self, Self::Http3 | Self::Race)
}
}
#[derive(Clone)]
pub struct Session {
inner: Arc<SessionInner>,
}
#[derive(Clone)]
pub(crate) struct SessionInner {
browser: Option<Browser>,
impersonates: bool,
header_style: HeaderStyle,
identity: Option<Identity>,
platform: Platform,
brand: ChromiumBrand,
user_agent: String,
sec_ch_ua: String,
accept_language: String,
header_order: Option<Vec<String>>,
default_headers: Vec<(String, String)>,
bearer: Option<builder::BearerToken>,
proxy_config: ProxyConfig,
timeouts: TimeoutConfig,
redirect_policy: RedirectPolicy,
compression: CompressionConfig,
#[cfg(feature = "websocket")]
websocket_config: WebSocketConfig,
https_only: bool,
cookie_jar: Jar,
connector: FingerprintConnector,
h2_config: H2Config,
pool: Arc<Pool>,
shutdown: tokio_util::sync::CancellationToken,
audit_tls: Option<Arc<crate::audit::AuditTlsCache>>,
protocol_policy: ProtocolPolicy,
default_retry: RetryPolicy,
#[cfg(feature = "http3")]
h3_config: Option<crate::quic::H3Config>,
tls_trust: TlsTrustConfig,
profile: Arc<crate::profile::BrowserProfile>,
base_url: Option<Url>,
languages: Option<Vec<String>>,
host_limits: crate::core::config::HostLimits,
#[cfg(feature = "html")]
crawl_limits: Arc<std::sync::OnceLock<crate::core::config::HostLimits>>,
#[cfg(feature = "html")]
crawl_pace: Option<crate::core::config::HostLimits>,
proxy_pool: Option<crate::core::proxy_pool::ProxyPool>,
trace: Option<Arc<dyn crate::trace::Trace>>,
#[expect(
clippy::type_complexity,
reason = "The shared cache retains raw input and a parsed URL shared by active requests"
)]
url_cache: Arc<Mutex<Option<(String, Arc<Url>)>>>,
}