Skip to main content

ferrijs_fetch/
bridge.rs

1//! Two-way bridge between the engine and a host-owned cookie jar.
2//!
3//! The shape is Playwright's `BrowserContextAPIRequestContext`
4//! (`server/fetch.ts:649`), which shares the browser context's cookie
5//! jar in both directions: the outgoing `Cookie` header is assembled
6//! from the host's cookies before every hop, and every hop's
7//! `Set-Cookie` headers are written back through the host. reqwest's own
8//! jar can't do that (the cookies live in the HOST, and each hop needs a
9//! fresh read), so the bridged path follows redirects manually and
10//! reads/writes cookies through this trait.
11
12/// Boxed future used by [`ContextBridge`] (`async fn` in traits is not
13/// dyn-compatible).
14pub type BridgeFuture<'a, T> =
15  std::pin::Pin<Box<dyn std::future::Future<Output = Result<T, crate::FetchError>> + Send + 'a>>;
16
17/// Live per-request defaults sourced from the owning context. Mirrors
18/// the subset of Playwright's `_defaultOptions()` (fetch.ts:666) a
19/// browser context carries.
20#[derive(Debug, Clone, Default)]
21pub struct ContextDefaults {
22  pub base_url: Option<String>,
23  pub extra_http_headers: Vec<(String, String)>,
24  pub user_agent: Option<String>,
25  pub ignore_https_errors: bool,
26}
27
28/// Two-way bridge between the engine and a host-owned context. Read
29/// live on every request so option mutations and host-side cookie
30/// changes are always visible, matching Playwright's live
31/// `_defaultOptions()` read.
32pub trait ContextBridge: Send + Sync {
33  fn defaults(&self) -> BridgeFuture<'_, ContextDefaults>;
34  fn cookies(&self) -> BridgeFuture<'_, Vec<crate::Cookie>>;
35  fn add_cookies(&self, cookies: Vec<crate::Cookie>) -> BridgeFuture<'_, ()>;
36}