There's ambiguity in the http_client.request() call on whether or not the caller
is responsible for freeing the header. It depends how request() fails, and it's
impossible for the caller to know. This needs a fundamental fix, but, in the
meantime, we get to pick between: a possible leak or a double free.
This commit opts for a possible leak. Why? Because overwhelmingly, if request
fails, it'll fail at a point where it will handle the free. In those cases
where it doesn't then the system is probably in trouble anyways (OOM).
(Also, as I was debugging, I noticed that the function.src() debug helper
wasn't working, so I fixed it).
`releaseRef` can free the XHR instance, so anything we want to set, has to
happen before then. (It might seem like the set is meaningful if we're just
going to destroy the instance, but `releaseRef` might also _not_ destroy the
instance, and the guard is for those cases).
buildJSONVersionResponse read the port from app.config.port(), which
is the configured value (still 0 with --port 0). Pass the OS-assigned
port from the bound address instead, so webSocketDebuggerUrl matches
the actual listener.
The integration test previously asserted a literal ws://127.0.0.1:9222/
that happened to match the test config's default port but not the
harness's hardcoded bind address (9583) — drop the URL assertion; the
buildJSONVersionResponse unit test already covers URL formatting.
XHR, for example, needs the context to properly shutdown. It get the page via
exec.context.page. Now, we could store the page on the XHR instance, sure. But
the point is the js.Context should never need the HttpClient, so it should
always be safe to abort inflight requests before canceling the context.
Fixes some flaky WPT crashes.
This re-implements the CDP navigate action fast-path when a page is in a
waiting state. It was removed for https://github.com/lightpanda-io/browser/pull/2297.
I believe this fast-path is still safe to do given that a page in _waiting has
had no navigation event yet and thus has nothing to preserve. The upside is
being able to re-use the existing [bare] v8::Context.
Per DOM §2.9 step 4 substep 8 ("Inner invoke"), an exception thrown by a
listener callback must be reported to the realm's global, not propagated
out of `dispatchEvent`. Subsequent listeners on the same target and the
rest of the capture/bubble walk must still run.
Both `EventManager.dispatchPhase` (DOM targets) and
`EventManagerBase.dispatchDirect` (Window/XHR/AbortSignal/etc.) wrapped
the V8 callback invocation in raw `try`, so a listener throw aborted the
whole dispatch and surfaced as an uncaught exception at the
`Runtime.evaluate` boundary. The inline-handler invocation a few lines
above already used `catch |err| log.warn(...)`; this just extends the
same shape to the listener switch.
Closes#2367
This fixes 2 separate issues, driven by the [very] broken
/dom/ranges/Range-insertNode.html WPT test.
The first, and simplest, is that when a script element is cloned, its executing
_executed and _force_async flags need to be copied. This prevents double-
execution.
The second is more complicated: dom version tracking (as a caching mechanism
used in various live collection) has to be against the node's owning frame, not
the frame that's executing the JavaScript. This includes both the version
checking and version change (on dom mutation). This introduces a relatively
expensive node -> document -> frame on every mutation and cache read. This is
potentially worth optimizing somehow, in a follow up PR. Two options come to
mind:
1 - Track a single dom version on the Page. Mutation in frame1 invalidates
frame2.
2 - Optimize for the frame-less case. If a page has no frame, then the calling
context should be equal to the owning document's frame.
When Fetch.httpErrorCallback rejects the promise, microtasks are run. Those
microtasks could do anything, including triggering a frame shutdown (e.g. via
a navigation event). The result is that we end up with
httpErrorCallback
httpShutdownCallback
And the code simply isn't designed to handle that. httpErrorCallback now takes
control of the cleanup, capturing the `self._owns_response` in a local, and
disabling so that any nested `httpShutdownCallback` are noops.
Wire the existing multipart encoder (FormData.multipartEncode) into the
fetch and XHR body paths. Previously both entry points typed their body
parameter as ?[]const u8, so the JS->Zig bridge silently coerced any
FormData JSValue via toString() and emitted "[object FormData]" with
Content-Type: application/x-www-form-urlencoded.
Introduces a BodyInit tagged union covering FormData, URLSearchParams,
Blob, and bytes. A small extract() helper returns the serialized bytes
plus the spec-mandated default Content-Type (Fetch §6.5 step 8 / XHR
§4.7.6 step 4). Both Request.init and XMLHttpRequest.send apply the
default Content-Type only when the caller hasn't already set one.
Closes#2357
Add worker.setInterval, clearInterval, setTimeout, clearTimeout by extracting
the scheduling logic from Window and making it use Execution rather than Frame.