When the snapshot isn't baked-into the binary, it requires more memory to
initialize and load. By changing the initializing order from: network, isolate,
snapshot to: isolate, snapshot, network we can reduce the peak startup memory.
This is because the short-live snapshot intermediary data and the long-lived
network data (certs) no longer overlap.
In https://github.com/lightpanda-io/browser/pull/1885 we added fallback to the
incumbent context when the current context had be released (by us, but not by
v8).
This now handles the case where there is no incumbent context. It's not clear
exactly why this can happen, but we do see it in some WPT tests (e.g.
/html/browsers/the-window-object/named-access-on-the-window-object/navigated-named-objects.window.html)
The main change is changing how CidrV4 and CidrV6 are stored, by pre-calculating
their mask and storing their address as integer.
This allows significant simplification of matchesCidrV4 and matchesCidrV6.
history.pushState() and replaceState() updated the navigation entry
but did not update page.url or reinitialize window.location. This
caused location.pathname to return the old value after pushState,
breaking SPA routing detection in automation scripts.
Both methods now set page.url and re-init the Location object after
updating the navigation history.
Fixes#2081
Ref #2043
When --user-agent is set, the provided string replaces the entire
User-Agent header instead of appending to "Lightpanda/1.0".
The existing --user-agent-suffix behavior is unchanged.
Fixes#2029
Rename --block_private_networks to --block-private-networks and
--block_cidrs to --block-cidrs to match the existing flag naming
convention (e.g. --http-proxy, --proxy-bearer-token).
CIDRs prefixed with '-' are treated as allow rules that exempt matching
IPs from blocking. Allow rules take precedence over both
--block_private_networks and custom block CIDRs.
Example: --block_private_networks --block_cidrs -10.0.0.42/32
blocks all private ranges except 10.0.0.42.
Adds 3 new tests for allow-list behavior.
Block outbound HTTP requests to specified IP ranges before TCP handshake
using libcurl CURLOPT_OPENSOCKETFUNCTION callback. Fires after DNS
resolution, reads resolved IP directly from sockaddr, does bitwise CIDR
comparison. Fail-closed: unknown address families are blocked.
--block_private_networks blocks RFC1918, localhost, link-local, ULA.
--block_cidrs blocks additional comma-separated CIDRs.
IPv4-mapped IPv6 (::ffff:x.x.x.x) is unwrapped to prevent bypass.
We need to remove v8 finalizer callbacks upfront so that, as we tear things down
there's no chance for v8 to try to finalize something which has already been
finalized or is gone.
Implement the XHR timeout property end-to-end: the JS-visible
getter/setter stores the value, send() passes it to the HTTP client,
and curl enforces it via CURLOPT_TIMEOUT_MS. On timeout, a `timeout`
event is dispatched instead of `error`, per the XHR spec.
This is standalone work that can be done to enable workers. Workers need a
subset of EventManager, specifically, dispatching events for non DOM objects.
This commit extracts the non-DOM dispatching into an EventManagerBase which
EventManager uses (via composition) and which, in the future, WorkerGlobalScope
will be able to use directly.
Dialogs auto-dismiss in headless mode, so there is no pending dialog
by the time the CDP client sends Page.handleJavaScriptDialog. Return
an explicit error so the client knows the action had no effect.
parseDomain() rejects bare TLDs (e.g. Domain=.io) but accepts
multi-level public suffixes like .co.uk, .com.au, .co.jp.
Per RFC 6265bis §5.7.3.10, user agents should reject cookies whose
domain attribute is a public suffix. Chrome, Firefox, and Safari all
enforce this using the Public Suffix List.
The PSL data is already imported (Cookie.zig:26) and used in
findSecondLevelDomain(), but parseDomain() does not consult it.
This causes behavior differences vs Chrome when automating .co.uk /
.com.au / .co.jp sites via CDP — cookies that Chrome silently drops
are accepted by Lightpanda, polluting the cookie jar across unrelated
sites in the same session.
dispatchKeyEvent only handled keyDown, returning early for keyUp,
rawKeyDown, and char types. This meant JS keyup and keypress
listeners never fired via CDP.
Now keyUp dispatches as "keyup" and char dispatches as "keypress".
rawKeyDown remains a no-op (Chrome-internal, not used for JS dispatch).
Fixes#2080
Ref #2043