pub struct Client { /* private fields */ }Expand description
HTTP client used to probe sites.
Cheap to clone — the underlying reqwest::Client is reference-counted
internally, and the throttle is Arc-backed, so cloning is the
recommended way to share a client between tasks. Cloned clients share
throttle state, which is what you want: a fan-out scan must not
accidentally exceed a per-host budget by spawning more clients.
Implementations§
Source§impl Client
impl Client
Sourcepub fn builder() -> ClientBuilder
pub fn builder() -> ClientBuilder
Start configuring a new client.
Sourcepub fn egress_summary(&self) -> Vec<EgressSummary>
pub fn egress_summary(&self) -> Vec<EgressSummary>
Read-only view of the configured egress pool — (country, kind)
for every registered proxy, in the order they were declared.
Proxy URLs are not surfaced (they typically carry credentials),
so this is safe to serialise to a JSON response.
Sourcepub fn session_names(&self) -> Vec<String>
pub fn session_names(&self) -> Vec<String>
Names of the configured sessions (sorted lexicographically),
without any header values. Useful for a UI listing which session
keys an operator can reference via access.session on a site.
Sourcepub fn egress_names(&self) -> Vec<String>
pub fn egress_names(&self) -> Vec<String>
Names of the configured egresses (in registration order, only
those that supplied a name). Used by the server to validate
per-scan egress_names against the loaded pool.
Sourcepub fn with_egress_subset(&self, names: &[String]) -> Self
pub fn with_egress_subset(&self, names: &[String]) -> Self
Returns a new client identical to this one except its egress
pool is restricted to entries whose name matches one of
names. An empty names slice is treated as “no filter” and
returns a clone of the full pool.
Cheap to call repeatedly: all shared state (HTTP clients,
throttle, sessions, budgets, browser backend, …) is
Arc-cloned so the returned client shares the parent’s
per-scan caps (browser budget, escalation budget, throttle
state) rather than each subset getting a fresh one. This is the
right behaviour for a single web-server instance handing out
per-request clients.
Sourcepub async fn check(&self, site: &Site, username: &Username) -> CheckOutcome
pub async fn check(&self, site: &Site, username: &Username) -> CheckOutcome
Probe a single site for username, retrying on transient bans.
Network failures, timeouts, and unexpected response shapes all yield
MatchKind::Uncertain with a descriptive note. The method never
returns an error: at the executor level we want a partial result for
every site, not abort-on-first-failure semantics.
When ban detection classifies a response as rate_limited /
cloudflare_challenge, the call is retried with jittered exponential
backoff (configurable via ClientBuilder::max_retries). Non-ban
Uncertain (network errors, body read failures) is not retried —
those failures rarely fix themselves in the seconds-to-minutes window
we’d block for.
Sourcepub async fn fetch(&self, url: &str) -> Option<RawResponse>
pub async fn fetch(&self, url: &str) -> Option<RawResponse>
Fetch a URL and return raw response data (status, final URL, body)
with the same throttle / User-Agent / proxy machinery as check,
but without signal evaluation or retry.
Returns None on any network/transport error. Intended for
diagnostics such as adler --doctor --fix, which diffs the
responses for a known-present and a nonsense user to derive a
signature.
Sourcepub async fn fetch_for_doctor(
&self,
site: &Site,
url: &str,
) -> Option<RawResponse>
pub async fn fetch_for_doctor( &self, site: &Site, url: &str, ) -> Option<RawResponse>
Same as Self::fetch but routes through the configured browser
backend when the site is tagged bot-protected and a backend is
available. Used by doctor::suggest_fix
so that the diff-derivation works against the JS-rendered page
(login wall vs. real profile) rather than two identical raw-HTTP
shells.
Falls back to raw HTTP if (a) no browser is configured, (b) the
site isn’t bot-protected, or (c) the browser fetch fails — so
callers get the same Option<RawResponse> shape either way.