The main.zig path for `fetch` now captures the *Browser so that
browser.env.terminate() can be called. This is a bit more complex than the serve
path because the Browser owns the Isolate and can't be moved from one thread to
another.
With main having access to the browser, two things are now possible:
1 - We can support a --terminate-ms flag (https://github.com/lightpanda-io/browser/issues/2206)
2 - ctrl-c can correctly stop blocked JavaScript processes
1 is implemented via setitimer to set a timer for SIGALRM, avoiding the need to
add another "watcher" thread, or putting a timer in Network.run.
This API isn't supported by FireFox (yet), so it isn't a huge priority, but I
did notice that its used across many Google properties. It uses the same value
as Sec-Ch-Ua (https://github.com/lightpanda-io/browser/pull/2100) to provide
consistent data.
Smaller changes:
1 - Allow `OffscreenCanvas` to be used with Worker (noticed this error too)
2 - Don't like JS execution errors at "error" level for "load" and
"DOMContentLoaded". "error" should be reserved for things we can fix and
should never be triggered from invalid a bug in JavaScript.
* Options with optional types are introduced to null by default
* Options with boolean types cannot be optional (nullable)
* Options with boolean types are introduced with false by default
* introduce shortcuts for options that can be provided via single dash
* introduce validators; custom parsing logic can be inserted for niche cases
This adds an app.storage which is a union around configurable storage engine
(currently, only sqlite).
It is _not_ being used anywhere right now. The goal is to get feedback on
the implementation and then move cache to it.
This doesn't expose a generic query API. The goal is that the storage will
expose high level methods, e.g. `cacheGet(req: CacheGetRequest)` and every
storage engine will translate the `storage.CacheGetRequest` as needed.
A thin wrapper around the Sqlite C api is included, e.g. exec(SQL, .{args}) a
`rows` and `row` fetcher. A connection pool is included. By default, an
in-memory DB is currently created. And a `migrations` table with an id of `1`
is created/inserted. I don't imagine needing fancy migratations.
@import("lightpanda") where needed.
Would also like to do this for String, Page, Session and js which all stand out
as types that are use across the codebase.
I know that a few devs are doing this in new work and I haven't heard anyone
voice an objection.
Split the single --cookies-file flag into two flags following curl's
convention as requested by @krichprollsch:
- --cookie (read-only): loads cookies at startup for fetch, mcp, and
serve/CDP commands
- --cookie-jar (write-only): saves cookies on exit for fetch and mcp
only (CDP cookie-jar deferred per maintainer guidance)
Add cookie integration to MCP server (load in init, save in deinit)
and CDP session creation (load only). The serve command now rejects
--cookie-jar with a clear error message.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Escape braces in help text format string to avoid std.debug.print
interpreting them as format specifiers
- Use writer.interface for std.Io.Writer methods (writeAll, stringify)
instead of calling them directly on fs.File.Writer
- Replace writer.flush() with writer.end() per codebase convention
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a --cookies-file CLI option that loads cookies from a JSON file
at startup and saves them back on exit. This enables AI agents to
maintain login sessions across multiple Lightpanda invocations.
The cookie format matches CDP Network.Cookie (compatible with
Puppeteer's page.cookies() export):
[{"name":"sid","value":"abc","domain":".example.com","path":"/",
"expires":1234567890,"secure":true,"httpOnly":true}]
Closes#335
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.