mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-06-11 01:25:53 -04:00
discardPendingPage on Session.initiateRootNavigation
This commit is contained in:
@@ -413,7 +413,8 @@ pub fn deinit(self: *Frame) void {
|
||||
|
||||
self._script_manager.base.shutdown = true;
|
||||
|
||||
browser.http_client.abortFrame(self._frame_id);
|
||||
// don't abort pending frames.
|
||||
browser.http_client.abortFrame(self._frame_id, .{});
|
||||
|
||||
self._script_manager.deinit();
|
||||
self._style_manager.deinit();
|
||||
@@ -758,7 +759,7 @@ fn scheduleNavigationWithArena(originator: *Frame, arena: Allocator, request_url
|
||||
.type = target._type,
|
||||
});
|
||||
|
||||
session.browser.http_client.abortFrame(target._frame_id);
|
||||
session.browser.http_client.abortFrame(target._frame_id, .{});
|
||||
|
||||
// Capture the originating frame's URL as the Referer for this
|
||||
// navigation. The originator's frame may be torn down before navigate()
|
||||
|
||||
@@ -304,19 +304,25 @@ pub fn getUserAgent(self: *const Client) [:0]const u8 {
|
||||
return self.user_agent_override orelse self.network.config.http_headers.user_agent;
|
||||
}
|
||||
|
||||
const AbortOpts = struct {
|
||||
scope: enum { normal, full } = .normal,
|
||||
};
|
||||
|
||||
pub fn abort(self: *Client) void {
|
||||
self._abort(true, 0);
|
||||
self._abort(true, 0, .{ .scope = .full });
|
||||
}
|
||||
|
||||
pub fn abortFrame(self: *Client, frame_id: u32) void {
|
||||
self._abort(false, frame_id);
|
||||
// abortFrame with .normal doesn't abort protect_from_abort requests.
|
||||
// .full abort all relqtive requests.
|
||||
pub fn abortFrame(self: *Client, frame_id: u32, opts: AbortOpts) void {
|
||||
self._abort(false, frame_id, opts);
|
||||
}
|
||||
|
||||
// Written this way so that both abort and abortFrame can share the same code
|
||||
// but abort can avoid the frame_id check at comptime.
|
||||
fn _abort(self: *Client, comptime abort_all: bool, frame_id: u32) void {
|
||||
abortConnections(self.in_use, abort_all, frame_id);
|
||||
abortConnections(self.ready_queue, abort_all, frame_id);
|
||||
fn _abort(self: *Client, comptime abort_all: bool, frame_id: u32, opts: AbortOpts) void {
|
||||
abortConnections(self.in_use, abort_all, frame_id, opts);
|
||||
abortConnections(self.ready_queue, abort_all, frame_id, opts);
|
||||
|
||||
{
|
||||
var q = &self.queue;
|
||||
@@ -327,9 +333,11 @@ fn _abort(self: *Client, comptime abort_all: bool, frame_id: u32) void {
|
||||
const params = transfer.req.params;
|
||||
if (comptime abort_all) {
|
||||
transfer.kill();
|
||||
} else if (params.frame_id == frame_id and !params.protect_from_abort) {
|
||||
q.remove(node);
|
||||
transfer.kill();
|
||||
} else if (params.frame_id == frame_id) {
|
||||
if (opts.scope == .full or !params.protect_from_abort) {
|
||||
q.remove(node);
|
||||
transfer.kill();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -355,7 +363,7 @@ fn _abort(self: *Client, comptime abort_all: bool, frame_id: u32) void {
|
||||
}
|
||||
}
|
||||
|
||||
fn abortConnections(list: std.DoublyLinkedList, comptime abort_all: bool, frame_id: u32) void {
|
||||
fn abortConnections(list: std.DoublyLinkedList, comptime abort_all: bool, frame_id: u32, opts: AbortOpts) void {
|
||||
var n = list.first;
|
||||
while (n) |node| {
|
||||
n = node.next;
|
||||
@@ -363,9 +371,12 @@ fn abortConnections(list: std.DoublyLinkedList, comptime abort_all: bool, frame_
|
||||
switch (conn.transport) {
|
||||
.http => |transfer| {
|
||||
const params = transfer.req.params;
|
||||
const matches = (comptime abort_all) or (params.frame_id == frame_id and !params.protect_from_abort);
|
||||
if (matches) {
|
||||
if (comptime abort_all) {
|
||||
transfer.kill();
|
||||
} else if (params.frame_id == frame_id) {
|
||||
if (opts.scope == .full or !params.protect_from_abort) {
|
||||
transfer.kill();
|
||||
}
|
||||
}
|
||||
},
|
||||
.websocket => |ws| {
|
||||
|
||||
@@ -534,7 +534,9 @@ fn replaceRootImmediate(self: *Session, frame_id: u32, qn: *QueuedNavigation) !v
|
||||
// trip — Runtime.evaluate, DOM.*, etc. continue to operate on the OLD page
|
||||
// until commitPendingPage swaps the pointer when response headers arrive.
|
||||
pub fn initiateRootNavigation(self: *Session, frame_id: u32, url: [:0]const u8, opts: Frame.NavigateOpts) !void {
|
||||
lp.assert(self._pending_idx == null, "Session.initiateRootNavigation - pending already set", .{});
|
||||
if (self._pending_idx != null) {
|
||||
self.discardPendingPage();
|
||||
}
|
||||
|
||||
// Pick the slot NOT occupied by the active page.
|
||||
const slot = try self.findFreeSlot();
|
||||
@@ -643,8 +645,13 @@ pub fn discardPendingPage(self: *Session) void {
|
||||
log.debug(.browser, "discard pending page", .{});
|
||||
}
|
||||
|
||||
const pending_page = &self._pages[idx].?;
|
||||
|
||||
// Force abort all inflight queries.
|
||||
self.browser.http_client.abortFrame(pending_page.frame._frame_id, .{ .scope = .full });
|
||||
|
||||
self._pending_idx = null;
|
||||
self._pages[idx].?.deinit();
|
||||
pending_page.deinit();
|
||||
self.freeSlot(idx);
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,8 @@ pub fn init(url: []const u8, exec: *Execution) !*Worker {
|
||||
// Called from Frame.deinit when the frame is destroyed, so we don't need to
|
||||
// remove from the frame's worker list.
|
||||
pub fn deinit(self: *Worker) void {
|
||||
self._frame._session.browser.http_client.abortFrame(self._frame_id);
|
||||
// No pending frame for workers, so we can abort all frames.
|
||||
self._frame._session.browser.http_client.abortFrame(self._frame_id, .{ .scope = .full });
|
||||
if (self._http_response) |res| {
|
||||
res.abort(error.Abort);
|
||||
self._http_response = null;
|
||||
|
||||
Reference in New Issue
Block a user