mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 15:13:28 +00:00
Merge pull request #771 from lightpanda-io/http_request_fail
Some checks failed
e2e-test / zig build release (push) Has been cancelled
zig-test / zig build dev (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
e2e-test / puppeteer-perf (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
zig-test / browser fetch (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
Some checks failed
e2e-test / zig build release (push) Has been cancelled
zig-test / zig build dev (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
e2e-test / puppeteer-perf (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
zig-test / browser fetch (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
Emit http_request_fail notification
This commit is contained in:
@@ -247,6 +247,8 @@ pub const Page = struct {
|
|||||||
.content_type = content_type,
|
.content_type = content_type,
|
||||||
.charset = mime.charset,
|
.charset = mime.charset,
|
||||||
.url = request_url,
|
.url = request_url,
|
||||||
|
.method = opts.method,
|
||||||
|
.reason = opts.reason,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!mime.isHTML()) {
|
if (!mime.isHTML()) {
|
||||||
@@ -597,6 +599,10 @@ pub const Page = struct {
|
|||||||
// The page.arena is safe to use here, but the transfer_arena exists
|
// The page.arena is safe to use here, but the transfer_arena exists
|
||||||
// specifically for this type of lifetime.
|
// specifically for this type of lifetime.
|
||||||
pub fn navigateFromWebAPI(self: *Page, url: []const u8, opts: NavigateOpts) !void {
|
pub fn navigateFromWebAPI(self: *Page, url: []const u8, opts: NavigateOpts) !void {
|
||||||
|
log.debug(.browser, "delayed navigation", .{
|
||||||
|
.url = url,
|
||||||
|
.reason = opts.reason,
|
||||||
|
});
|
||||||
self.delayed_navigation = true;
|
self.delayed_navigation = true;
|
||||||
const arena = self.session.transfer_arena;
|
const arena = self.session.transfer_arena;
|
||||||
const navi = try arena.create(DelayedNavigation);
|
const navi = try arena.create(DelayedNavigation);
|
||||||
|
|||||||
@@ -338,7 +338,11 @@ pub const XMLHttpRequest = struct {
|
|||||||
// dispatch request event.
|
// dispatch request event.
|
||||||
// errors are logged only.
|
// errors are logged only.
|
||||||
fn dispatchEvt(self: *XMLHttpRequest, typ: []const u8) void {
|
fn dispatchEvt(self: *XMLHttpRequest, typ: []const u8) void {
|
||||||
log.debug(.script_event, "dispatch event", .{ .type = typ, .source = "xhr" });
|
log.debug(.script_event, "dispatch event", .{
|
||||||
|
.type = typ,
|
||||||
|
.source = "xhr",
|
||||||
|
.url = self.url,
|
||||||
|
});
|
||||||
self._dispatchEvt(typ) catch |err| {
|
self._dispatchEvt(typ) catch |err| {
|
||||||
log.err(.app, "dispatch event error", .{ .err = err, .type = typ, .source = "xhr" });
|
log.err(.app, "dispatch event error", .{ .err = err, .type = typ, .source = "xhr" });
|
||||||
};
|
};
|
||||||
@@ -358,7 +362,11 @@ pub const XMLHttpRequest = struct {
|
|||||||
typ: []const u8,
|
typ: []const u8,
|
||||||
opts: ProgressEvent.EventInit,
|
opts: ProgressEvent.EventInit,
|
||||||
) void {
|
) void {
|
||||||
log.debug(.script_event, "dispatch progress event", .{ .type = typ, .source = "xhr" });
|
log.debug(.script_event, "dispatch progress event", .{
|
||||||
|
.type = typ,
|
||||||
|
.source = "xhr",
|
||||||
|
.url = self.url,
|
||||||
|
});
|
||||||
self._dispatchProgressEvent(typ, opts) catch |err| {
|
self._dispatchProgressEvent(typ, opts) catch |err| {
|
||||||
log.err(.app, "dispatch progress event error", .{ .err = err, .type = typ, .source = "xhr" });
|
log.err(.app, "dispatch progress event error", .{ .err = err, .type = typ, .source = "xhr" });
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -412,11 +412,13 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn networkEnable(self: *Self) !void {
|
pub fn networkEnable(self: *Self) !void {
|
||||||
|
try self.cdp.browser.notification.register(.http_request_fail, self, onHttpRequestFail);
|
||||||
try self.cdp.browser.notification.register(.http_request_start, self, onHttpRequestStart);
|
try self.cdp.browser.notification.register(.http_request_start, self, onHttpRequestStart);
|
||||||
try self.cdp.browser.notification.register(.http_request_complete, self, onHttpRequestComplete);
|
try self.cdp.browser.notification.register(.http_request_complete, self, onHttpRequestComplete);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn networkDisable(self: *Self) void {
|
pub fn networkDisable(self: *Self) void {
|
||||||
|
self.cdp.browser.notification.unregister(.http_request_fail, self);
|
||||||
self.cdp.browser.notification.unregister(.http_request_start, self);
|
self.cdp.browser.notification.unregister(.http_request_start, self);
|
||||||
self.cdp.browser.notification.unregister(.http_request_complete, self);
|
self.cdp.browser.notification.unregister(.http_request_complete, self);
|
||||||
}
|
}
|
||||||
@@ -448,6 +450,12 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
|||||||
return @import("domains/network.zig").httpRequestStart(self.notification_arena, self, data);
|
return @import("domains/network.zig").httpRequestStart(self.notification_arena, self, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn onHttpRequestFail(ctx: *anyopaque, data: *const Notification.RequestFail) !void {
|
||||||
|
const self: *Self = @alignCast(@ptrCast(ctx));
|
||||||
|
defer self.resetNotificationArena();
|
||||||
|
return @import("domains/network.zig").httpRequestFail(self.notification_arena, self, data);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn onHttpRequestComplete(ctx: *anyopaque, data: *const Notification.RequestComplete) !void {
|
pub fn onHttpRequestComplete(ctx: *anyopaque, data: *const Notification.RequestComplete) !void {
|
||||||
const self: *Self = @alignCast(@ptrCast(ctx));
|
const self: *Self = @alignCast(@ptrCast(ctx));
|
||||||
defer self.resetNotificationArena();
|
defer self.resetNotificationArena();
|
||||||
|
|||||||
@@ -84,6 +84,24 @@ fn putAssumeCapacity(headers: *std.ArrayListUnmanaged(std.http.Header), extra: s
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn httpRequestFail(arena: Allocator, bc: anytype, request: *const Notification.RequestFail) !void {
|
||||||
|
// Isn't possible to do a network request within a Browser (which our
|
||||||
|
// notification is tied to), without a page.
|
||||||
|
std.debug.assert(bc.session.page != null);
|
||||||
|
|
||||||
|
// all unreachable because we _have_ to have a page.
|
||||||
|
const session_id = bc.session_id orelse unreachable;
|
||||||
|
|
||||||
|
// We're missing a bunch of fields, but, for now, this seems like enough
|
||||||
|
try bc.cdp.sendEvent("Network.loadingFailed", .{
|
||||||
|
.requestId = try std.fmt.allocPrint(arena, "REQ-{d}", .{request.id}),
|
||||||
|
// Seems to be what chrome answers with. I assume it depends on the type of error?
|
||||||
|
.type = "Ping",
|
||||||
|
.errorText = request.err,
|
||||||
|
.canceled = false,
|
||||||
|
}, .{ .session_id = session_id });
|
||||||
|
}
|
||||||
|
|
||||||
pub fn httpRequestStart(arena: Allocator, bc: anytype, request: *const Notification.RequestStart) !void {
|
pub fn httpRequestStart(arena: Allocator, bc: anytype, request: *const Notification.RequestStart) !void {
|
||||||
// Isn't possible to do a network request within a Browser (which our
|
// Isn't possible to do a network request within a Browser (which our
|
||||||
// notification is tied to), without a page.
|
// notification is tied to), without a page.
|
||||||
|
|||||||
@@ -354,6 +354,7 @@ pub const Request = struct {
|
|||||||
// Because of things like redirects and error handling, it is possible for
|
// Because of things like redirects and error handling, it is possible for
|
||||||
// the notification functions to be called multiple times, so we guard them
|
// the notification functions to be called multiple times, so we guard them
|
||||||
// with these booleans
|
// with these booleans
|
||||||
|
_notified_fail: bool,
|
||||||
_notified_start: bool,
|
_notified_start: bool,
|
||||||
_notified_complete: bool,
|
_notified_complete: bool,
|
||||||
|
|
||||||
@@ -414,6 +415,7 @@ pub const Request = struct {
|
|||||||
._keepalive = false,
|
._keepalive = false,
|
||||||
._redirect_count = 0,
|
._redirect_count = 0,
|
||||||
._has_host_header = false,
|
._has_host_header = false,
|
||||||
|
._notified_fail = false,
|
||||||
._notified_start = false,
|
._notified_start = false,
|
||||||
._notified_complete = false,
|
._notified_complete = false,
|
||||||
._connection_from_keepalive = false,
|
._connection_from_keepalive = false,
|
||||||
@@ -428,6 +430,7 @@ pub const Request = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn abort(self: *Request) void {
|
pub fn abort(self: *Request) void {
|
||||||
|
self.requestFailed("aborted");
|
||||||
const aborter = self._aborter orelse {
|
const aborter = self._aborter orelse {
|
||||||
self.deinit();
|
self.deinit();
|
||||||
return;
|
return;
|
||||||
@@ -555,6 +558,10 @@ pub const Request = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn doSendSync(self: *Request, use_pool: bool) anyerror!Response {
|
fn doSendSync(self: *Request, use_pool: bool) anyerror!Response {
|
||||||
|
// https://github.com/ziglang/zig/issues/20369
|
||||||
|
// errdefer |err| self.requestFailed(@errorName(err));
|
||||||
|
errdefer self.requestFailed("network error");
|
||||||
|
|
||||||
if (use_pool) {
|
if (use_pool) {
|
||||||
if (self.findExistingConnection(true)) |connection| {
|
if (self.findExistingConnection(true)) |connection| {
|
||||||
self._connection = connection;
|
self._connection = connection;
|
||||||
@@ -847,6 +854,19 @@ pub const Request = struct {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn requestFailed(self: *Request, err: []const u8) void {
|
||||||
|
const notification = self.notification orelse return;
|
||||||
|
if (self._notified_fail) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self._notified_fail = true;
|
||||||
|
notification.dispatch(.http_request_fail, &.{
|
||||||
|
.id = self.id,
|
||||||
|
.err = err,
|
||||||
|
.url = self.request_uri,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn requestCompleted(self: *Request, response: ResponseHeader) void {
|
fn requestCompleted(self: *Request, response: ResponseHeader) void {
|
||||||
const notification = self.notification orelse return;
|
const notification = self.notification orelse return;
|
||||||
if (self._notified_complete) {
|
if (self._notified_complete) {
|
||||||
@@ -1290,6 +1310,8 @@ fn AsyncHandler(comptime H: type, comptime L: type) type {
|
|||||||
self.handler.onHttpResponse(err) catch {};
|
self.handler.onHttpResponse(err) catch {};
|
||||||
// just to be safe
|
// just to be safe
|
||||||
self.request._keepalive = false;
|
self.request._keepalive = false;
|
||||||
|
|
||||||
|
self.request.requestFailed(@errorName(err));
|
||||||
self.request.deinit();
|
self.request.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ pub const Notification = struct {
|
|||||||
page_created: List = .{},
|
page_created: List = .{},
|
||||||
page_navigate: List = .{},
|
page_navigate: List = .{},
|
||||||
page_navigated: List = .{},
|
page_navigated: List = .{},
|
||||||
|
http_request_fail: List = .{},
|
||||||
http_request_start: List = .{},
|
http_request_start: List = .{},
|
||||||
http_request_complete: List = .{},
|
http_request_complete: List = .{},
|
||||||
notification_created: List = .{},
|
notification_created: List = .{},
|
||||||
@@ -69,6 +70,7 @@ pub const Notification = struct {
|
|||||||
page_created: *page.Page,
|
page_created: *page.Page,
|
||||||
page_navigate: *const PageNavigate,
|
page_navigate: *const PageNavigate,
|
||||||
page_navigated: *const PageNavigated,
|
page_navigated: *const PageNavigated,
|
||||||
|
http_request_fail: *const RequestFail,
|
||||||
http_request_start: *const RequestStart,
|
http_request_start: *const RequestStart,
|
||||||
http_request_complete: *const RequestComplete,
|
http_request_complete: *const RequestComplete,
|
||||||
notification_created: *Notification,
|
notification_created: *Notification,
|
||||||
@@ -97,6 +99,12 @@ pub const Notification = struct {
|
|||||||
has_body: bool,
|
has_body: bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const RequestFail = struct {
|
||||||
|
id: usize,
|
||||||
|
url: *const std.Uri,
|
||||||
|
err: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
pub const RequestComplete = struct {
|
pub const RequestComplete = struct {
|
||||||
id: usize,
|
id: usize,
|
||||||
url: *const std.Uri,
|
url: *const std.Uri,
|
||||||
|
|||||||
@@ -127,7 +127,6 @@ pub const Loop = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// JS callbacks APIs
|
// JS callbacks APIs
|
||||||
// -----------------
|
// -----------------
|
||||||
|
|
||||||
@@ -255,7 +254,6 @@ pub const Loop = struct {
|
|||||||
}
|
}
|
||||||
}.onConnect;
|
}.onConnect;
|
||||||
|
|
||||||
|
|
||||||
const callback = try self.event_callback_pool.create();
|
const callback = try self.event_callback_pool.create();
|
||||||
errdefer self.event_callback_pool.destroy(callback);
|
errdefer self.event_callback_pool.destroy(callback);
|
||||||
callback.* = .{ .loop = self, .ctx = ctx };
|
callback.* = .{ .loop = self, .ctx = ctx };
|
||||||
|
|||||||
Reference in New Issue
Block a user