fix: load balancer panics, stealth flag, shadow DOM polyfill

Fixes #1: replace unwrap() panics in run_multi_worker_serve with match on the Result.
Fixes #2: route /json round-robin via worker_port instead of hardcoded port+1.
Fixes #3: return 502 Bad Gateway when a worker is unreachable instead of silently dropping the connection.
Fixes #5: thread --stealth through start_with_options -> CdpContext -> BrowserContext::with_options so the flag actually has an effect in serve mode (was let _ before). Log message now reflects the actual capability based on the stealth cargo feature being compiled in.
Fixes #15: try/catch the parentNode assignment in the attachShadow polyfill so it doesn't throw a TypeError against the read-only Node.parentNode getter (Cloudflare Turnstile triggers this path).
This commit is contained in:
h4ckf0r0day committed 2026-04-25 14:27:52 +02:00
1 parent 74cf88d0f4
commit 99e75f1e62
4 files changed
+106 -24

No files matched your search

+10 -5
View File
@@ -24,10 +24,14 @@ enum ServerMessage {
}
pub async fn start(port: u16) -> anyhow::Result<()> {
start_with_options(port, None).await
start_with_options(port, None, false).await
}
pub async fn start_with_options(port: u16, proxy: Option<String>) -> anyhow::Result<()> {
pub async fn start_with_options(
port: u16,
proxy: Option<String>,
stealth: bool,
) -> anyhow::Result<()> {
let addr = SocketAddr::from(([127, 0, 0, 1], port));
let listener = TcpListener::bind(&addr).await?;
@@ -42,7 +46,7 @@ pub async fn start_with_options(port: u16, proxy: Option<String>) -> anyhow::Res
.run_until(async {
let (msg_tx, msg_rx) = mpsc::unbounded_channel::<ServerMessage>();
let processor_handle = tokio::task::spawn_local(cdp_processor(msg_rx, proxy));
let processor_handle = tokio::task::spawn_local(cdp_processor(msg_rx, proxy, stealth));
loop {
match listener.accept().await {
@@ -67,8 +71,9 @@ pub async fn start_with_options(port: u16, proxy: Option<String>) -> anyhow::Res
async fn cdp_processor(
mut rx: mpsc::UnboundedReceiver<ServerMessage>,
proxy: Option<String>,
stealth: bool,
) {
let mut ctx = CdpContext::new_with_proxy(proxy);
let mut ctx = CdpContext::new_with_options(proxy, stealth);
let (itx, irx) = mpsc::unbounded_channel::<obscura_js::ops::InterceptedRequest>();
ctx.intercept_tx = Some(itx);
let mut intercept_rx: Option<mpsc::UnboundedReceiver<obscura_js::ops::InterceptedRequest>> = Some(irx);
@@ -632,4 +637,4 @@ async fn handle_http_json(stream: TcpStream, port: u16, endpoint: &str) -> anyho
stream.write_all(resp.as_bytes()).await?;
stream.flush().await?;
Ok(())
}
}