Skip to content

feat(cdp): add Network.setBlockedURLs and --block-urls request blocking#3004

Closed
mvanhorn wants to merge 2 commits into
lightpanda-io:mainfrom
mvanhorn:fix/lightpanda-request-blocking
Closed

feat(cdp): add Network.setBlockedURLs and --block-urls request blocking#3004
mvanhorn wants to merge 2 commits into
lightpanda-io:mainfrom
mvanhorn:fix/lightpanda-request-blocking

Conversation

@mvanhorn

@mvanhorn mvanhorn commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

What

Add request-time URL blocking from two entry points that share one blocklist:

  • --block-urls <LIST> — comma-separated *-wildcard patterns, matched case-insensitively against the full URL, on serve / fetch / mcp, next to the existing --block-cidrs.
  • Network.setBlockedURLs — the CDP method, matching Chrome's semantics.

Why

Lightpanda's Network CDP domain implemented no request-blocking method (src/cdp/domains/network.zig dispatched enable, disable, setCacheDisabled, header/cookie methods, and getResponseBody, nothing else), and the fetch CLI had no URL blocklist. So a Puppeteer/Playwright script that blocks ad/tracker requests against Chrome via page.setRequestInterception / page.route(..., r => r.abort()) — backed by CDP Network.setBlockedURLs — silently lost that behavior when pointed at Lightpanda. For a high-volume scraper those dropped requests are the point: they cut connections, latency, and bandwidth an agent never reads (Browserless markets the same request/ad blocking as a scraping speedup).

Change

  • New src/network/UrlBlocklist.zig, modeled on IpFilter.zig: compiles and owns a set of wildcard patterns once, and answers isBlocked(url) with an allocation-free two-pointer glob match.
  • HttpClient holds an optional UrlBlocklist built from config.blockedUrlPatterns() at init. Enforcement sits at the existing request-start gate that already handles robots and IP/CIDR blocking, and also on the redirect target, so a blocked URL never opens a socket and fails via the same async path. Internal transfers (e.g. robots.txt) are exempt, matching the robots / IP-filter exemption. setBlockedUrls() replaces the live list at runtime for the CDP path (owning its own copies).
  • A blocked request fails with error.UrlBlocked, which maps through Notification.RequestFail.blocked_reason to Network.loadingFailed with blockedReason: "inspector" — the reason Chrome reports for setBlockedURLs hits — so CDP clients see the expected event.

Demo

Simulated demo (illustrative, not a live capture): --block-urls "*doubleclick*,*analytics*,*://*/*.png" drops the matching ad/tracker/image requests while index.html and the non-matching pixel.gif still load.

Simulated demo of --block-urls request blocking

Test

  • src/network/UrlBlocklist.zig: wildcard-matcher unit tests — case-insensitivity, backtracking, consecutive/trailing *, empty and * patterns, and pattern ownership (mutating the source after init leaves matches intact). These run standalone under the leak-detecting test allocator and pass.
  • src/network/HttpClient.zig: setBlockedUrls owns/replaces/clears, and the internal-transfer exemption.
  • src/cdp/domains/network.zig: a blocked request emits Network.loadingFailed with blockedReason: "inspector", for both the initial request and a redirect target.
  • zig fmt --check clean; zig ast-check clean on all touched files. The full make test needs the V8 toolchain build.

Comment thread src/cdp/domains/network.zig Outdated
Reimplement request blocking on the non-deprecated urlPatterns shape:
each pattern carries an explicit block/allow flag (first match wins),
UrlBlocklist owns the compiled patterns plus their block flags, and the
legacy setBlockedUrls path stays for back-compat. Tests updated.
@mvanhorn

Copy link
Copy Markdown
Contributor Author

Reworked onto urlPatterns in b573eb1: each pattern carries its block/allow flag (first match wins), the blocklist owns the compiled patterns plus flags, and the legacy urls path stays for back-compat. The three standalone UrlBlocklist tests pass; the full Zig 0.15.2 build runs in CI since my local toolchain is 0.16.

@krichprollsch

Copy link
Copy Markdown
Member

merged via #3040
Thanks!

@github-actions github-actions Bot locked and limited conversation to collaborators Jul 23, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants