Commit Graph
23 Commits
Author SHA1 Message Date
Karl Seguin a5e27869d3 chore: remove unused imports 2026-09-05 17:51:47 +08:00
Muki Kiboigo d1f4605459 non-default credentials and request mode 2026-09-04 07:00:00 -07:00
Muki Kiboigo b114382c44 add origin field to HttpClient Request 2026-09-04 06:59:37 -07:00
Karl Seguin e25d2da0c0 chore: Simplify making HTTP requests.
If you look at https://github.com/lightpanda-io/browser/pull/3293, you'll see
a relatively contained change that has to touch over 20 files. The issue is that
every HttpClient.newRequest needs to provide a lot of data. But `newRequest`
takes a 2nd parameter: the HttpClient.Owner. If we make that Owner a little
smarter, we can start to remove some of the individual fields needed in
newRequest. For example, we can still allow a callsite to pass frame_id but,
by default, we can use the owner's frame_id (which is what we want in most
cases).
2026-09-02 07:55:53 +08:00
Halil Durak 87308b5e23 compute site-for-cookies from ancestor chain of a Frame
The site for cookies were computed from the immediate parent `Frame`, which would allow sending a cookie that's `SameSite=Strict` from 2 levels deep under. Directly from RFC6265bis, this PR essentially implements (except for step 4, we skip host-less ancestors):

   Given a Document (document), the following algorithm returns its
   "site for cookies":

   1.  Let top-document be the active document in document's navigable's
       top-level traversable.

   2.  Let top-origin be the origin of top-document's URI if top-
       document's sandboxed origin browsing context flag is set, and
       top-document's origin otherwise.

   3.  Let documents be a list consisting of the active documents of
       document's inclusive ancestor navigables.

   4.  For each item in documents:

       1.  Let origin be the origin of item's URI if item's sandboxed
           origin browsing context flag is set, and item's origin
           otherwise.

       2.  If origin is not same-site with top-origin, return an origin
           set to an opaque origin.

   5.  Return top-origin.
2026-09-02 07:19:35 +08:00
Muki Kiboigo 3bebe80e2f 401 and 403 are treated as disallow by RobotsGate 2026-08-15 11:48:06 -07:00
Muki Kiboigo 7cb6590642 better handling of allowed and disallowed robots cases 2026-08-14 08:52:37 -07:00
Muki Kiboigo fb5a9b6a35 get rid of allocator stored in RobotsGate 2026-08-13 08:20:15 -07:00
Muki Kiboigo d1d02e1114 dupe into owned arena for SingleFlight initial 2026-08-13 01:37:21 -07:00
Muki Kiboigo f7e6464370 SingleFlight should own the key 2026-08-13 00:25:33 -07:00
Muki Kiboigo cc5537dd63 discard if failure after single_flight enter 2026-08-12 18:32:46 -07:00
Muki Kiboigo 00d5be5c5b deallocate queued with same singleflight allocator 2026-08-12 18:17:42 -07:00
Muki Kiboigo 82e9496409 use SingleFlight in RobotsGate 2026-08-12 18:04:04 -07:00
Karl Seguin c86d969ce0 mem: prefer ensureTotalCapacityPrecise to reduce memory usage
When we know the precise final length, prefer ensureTotalCapacityPrecise over
ensureTotalCapacity. The latter goes through `growCapacity` which will allocate
~1.5x padding.
2026-08-04 17:44:05 +08:00
Karl Seguin bdce49a4b5 refactor: Introduce Arena wrapper
Introduces a ArenaAllocator wrappre (lp.Arena). This is groundwork for better
memory tracking and reporting memory usage to v8. This is almost purely a
mechanical change to lay a foundation for a follow up PR that will address
https://github.com/lightpanda-io/browser/issues/3027

Some code became a bit leaner: a pooled arena can release itself (it has a
reference to the ArenaPool).

Some code became uglier: The Frame has a `_local_arena: *lp.Arena` and a
`local_arena: Allocator` (same with call_arena, and same with a few other types)
so that consumers aren't impacted (they continue to use `frame.local_arena`).
2026-07-30 13:02:13 +08:00
Karl Seguin 5acfd38250 Improve CDP response event data
Give accurate connectionId, connectionReused, initialPriority and securityState
values.

Always set `referrerPolicy` to `unsafe-url` as the most honest answer (we should
implement proper referrer policy!).

For workers, track the underlying frame_id so that it can be used for the
`documentURL` field.
2026-07-25 11:36:13 +08:00
Karl Seguin 2e9aebc6b1 Merge pull request #2935 from lightpanda-io/robots-skip-non-200-body
robots, mem: don't buffer body on a non-200 robots response
2026-07-15 07:02:28 +08:00
Karl Seguin f0784de015 add http metrics 2026-07-14 11:32:52 +08:00
Karl Seguin 042e85e807 robots, mem: don't buffer body on a non-200 robots response 2026-07-14 09:16:00 +08:00
Karl Seguin 86c8b88328 httpclient: eliminate some uaf on transfer abort
Commit eliminates a class of UAF on transfer abort due to the abort potentially
JS callbacks within a libcurl callback.

It also introduces a graveyard queue to the HttpClient so that, on deinit,
Transfers become detached but their memory is still valid. In debug, the
transfer is poisoned so that any uaf fails loudly. In release, the graveyard
is simply cleaned up.
2026-07-10 12:34:45 +08:00
Karl Seguin 377de019b8 fix uaf when aborting a robots-parked transfer 2026-07-10 08:22:28 +08:00
Karl Seguin 941935af56 fix inverted robots check 2026-07-10 07:35:36 +08:00
Karl Seguin 2eab4d2630 refactor: HttpClient
Replaces layering with an inline request pipeline, and transfer queue. This is
meant to simplify the code, reduce footguns, and make future enhancements easier
to implement (e.g. speculative parsing (which requires streaming to fully
leverage)).

Previously, HttpClient implemented deferring as a layer which required special
pumping at various callsites (https://github.com/lightpanda-io/browser/pull/2855,
https://github.com/lightpanda-io/browser/pull/2843, ...). In this new approach,
deferring is built-into the HttpClient/Transfer's flow. Specifically, Transfers
now maintain a queue of events (start, header, data, end, err) which are
dispatched in HttpClient.tick. The result is that JS callbacks are never
executed in the same stack that initiated the I/O, without needing guards or any
external intervention.

tTwo other benefits come from this. The first is that reentrant libcurl is
eliminated. Instead of "libcurl -> callback", it's now "libcurl -> transfer
event queue THEN  tick -> callback" (we don't have to wait until the NEXT tick, we
can just do it later in the tick). HttpClient still has to guard against libcurl
reentrancy, but only because of how WebSocket is implemented, and we should be
able to unify WebSockets to use an event queue too in a follow up PR (which will
eliminate a bunch of guard code).

The transfer queue should also be useful to re-implement streaming, since a
data chunk is just an event in the transfer's event queue. For now, I kept it
as a single buffered event to minimize the change. But since speculative parsing
depends on this, and speculative parsing seems to be the next major performance
tweak we can make, we need to re-introduce streaming.

The other change is the removal of all other layers in favor of a pipeline. This
works well with the existing Transfer.park mechanism, where a parked Transfer
can restart the pipeline for a transfer in an arbitrary point (not as fancy as
it sounds given how simple the flow is). The fallout from this is that we're no
longer creating/wrapping contexts and callbacks: whatever the request was
configured with is all we need.

Because of this, HttpClient.Response is removed. There are no intermediary
responses and no changing context, everything is just the Transfer.

A smaller change is the addition of newRequest + transfer.submit(). The one-shot
HttpClient.request and HttpClient.requestT still exist, but this explicit create
+ submit has some advantage. First, callers can use the transfer.arena (e.g.
Frame using the transfer's arena to set the Referrer header). Second, callers
can holds Transfer immediately, rather than waiting for their startCallback to
be fired. An abort on an XMLHttpRequest called before the start of the transfer
no longer silently fails.
2026-07-10 07:35:36 +08:00