From f5dc97b131446d3448f0aeb1bb8ef86916ce735c Mon Sep 17 00:00:00 2001 From: "Jim Zhang @ wonderhoi" Date: Thu, 16 Jul 2026 18:43:13 +0800 Subject: [PATCH] fix(net): scope passive callbacks to the registering page (#414) The on_request/on_response Vec lived on the ObscuraHttpClient shared by every page in the context, so a callback registered on one page fired for all pages (#408 cross-page bleed) and outlived its page. Callbacks now live in a per-page CallbackRegistry (Arc shared with the page's JS runtime state). Page-driven fetch paths (navigation, POST, scripts, stylesheets, robots.txt, module loads, JS fetch/XHR in both plain and stealth modes) pass the registry through; the HTTP client itself is callback-free. Adds callbacks_do_not_bleed_across_pages: page A's callback stays silent for page B's requests and stops firing after page A is dropped. --- crates/obscura-browser/src/page.rs | 56 +++++--- crates/obscura-js/src/ops.rs | 42 +++--- crates/obscura-js/src/runtime.rs | 13 +- crates/obscura-net/src/client.rs | 186 ++++++++++++++++++--------- crates/obscura-net/src/lib.rs | 5 +- crates/obscura/src/page.rs | 6 +- crates/obscura/tests/interception.rs | 47 +++++++ docs/Use-as-a-Rust-library.md | 2 +- 8 files changed, 249 insertions(+), 108 deletions(-) diff --git a/crates/obscura-browser/src/page.rs b/crates/obscura-browser/src/page.rs index 24e278e..a7176f0 100644 --- a/crates/obscura-browser/src/page.rs +++ b/crates/obscura-browser/src/page.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use base64::{engine::general_purpose::STANDARD as BASE64, Engine as _}; use obscura_dom::{parse_html, DomTree}; use obscura_js::runtime::ObscuraJsRuntime; -use obscura_net::{ObscuraHttpClient, ObscuraNetError, RequestCallback, Response, ResponseCallback}; +use obscura_net::{CallbackRegistry, ObscuraHttpClient, ObscuraNetError, RequestCallback, Response, ResponseCallback}; use url::Url; use crate::context::BrowserContext; @@ -194,6 +194,10 @@ pub struct Page { // contract. Includes `Runtime.addBinding` shims so puppeteer's // `exposeFunction` bindings exist before inline `