Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/cdp/cdp.zig
Original file line number Diff line number Diff line change
Expand Up @@ -455,12 +455,14 @@ pub fn BrowserContext(comptime CDP_T: type) type {
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_headers_done, self, onHttpHeadersDone);
try self.cdp.browser.notification.register(.http_request_done, self, onHttpRequestDone);
}

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_headers_done, self);
self.cdp.browser.notification.unregister(.http_request_done, self);
}

pub fn fetchEnable(self: *Self) !void {
Expand Down Expand Up @@ -516,6 +518,12 @@ pub fn BrowserContext(comptime CDP_T: type) type {
return @import("domains/network.zig").httpHeadersDone(self.notification_arena, self, data);
}

pub fn onHttpRequestDone(ctx: *anyopaque, data: *const Notification.RequestDone) !void {
const self: *Self = @alignCast(@ptrCast(ctx));
defer self.resetNotificationArena();
return @import("domains/network.zig").httpRequestDone(self.notification_arena, self, data);
}

fn resetNotificationArena(self: *Self) void {
defer _ = self.cdp.notification_arena.reset(.{ .retain_with_limit = 1024 * 64 });
}
Expand Down
31 changes: 31 additions & 0 deletions src/cdp/domains/network.zig
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub fn processMessage(cmd: anytype) !void {
setCookie,
setCookies,
getCookies,
getResponseBody,
}, cmd.input.action) orelse return error.UnknownMethod;

switch (action) {
Expand All @@ -49,6 +50,7 @@ pub fn processMessage(cmd: anytype) !void {
.setCookie => return setCookie(cmd),
.setCookies => return setCookies(cmd),
.getCookies => return getCookies(cmd),
.getResponseBody => return getResponseBody(cmd),
}
}

Expand Down Expand Up @@ -202,6 +204,19 @@ fn getCookies(cmd: anytype) !void {
try cmd.sendResult(.{ .cookies = writer }, .{});
}

fn getResponseBody(cmd: anytype) !void {
const params = (try cmd.params(struct {
requestId: []const u8, // "REQ-{d}"
})) orelse return error.InvalidParams;

_ = params;

try cmd.sendResult(.{
.body = "TODO",
.base64Encoded = false,
}, .{});
}

pub fn httpRequestFail(arena: Allocator, bc: anytype, data: *const Notification.RequestFail) !void {
// It's possible that the request failed because we aborted when the client
// sent Target.closeTarget. In that case, bc.session_id will be cleared
Expand Down Expand Up @@ -264,6 +279,22 @@ pub fn httpHeadersDone(arena: Allocator, bc: anytype, data: *const Notification.
}, .{ .session_id = session_id });
}

pub fn httpRequestDone(arena: Allocator, bc: anytype, data: *const Notification.RequestDone) !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);

var cdp = bc.cdp;

// all unreachable because we _have_ to have a page.
const session_id = bc.session_id orelse unreachable;

try cdp.sendEvent("Network.loadingFinished", .{
.requestId = try std.fmt.allocPrint(arena, "REQ-{d}", .{data.transfer.id}),
.encodedDataLength = data.transfer.bytes_received,
}, .{ .session_id = session_id });
}

pub const TransferAsRequestWriter = struct {
transfer: *Transfer,

Expand Down
17 changes: 15 additions & 2 deletions src/http/Client.zig
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +376,14 @@ fn perform(self: *Client, timeout_ms: c_int) !void {
// transfer isn't valid at this point, don't use it.
log.err(.http, "done_callback", .{ .err = err });
self.requestFailed(transfer, err);
continue;
};
// self.requestComplete(transfer);

if (transfer.client.notification) |notification| {
notification.dispatch(.http_request_done, &.{
.transfer = transfer,
});
}
} else |err| {
self.requestFailed(transfer, err);
}
Expand Down Expand Up @@ -552,11 +558,15 @@ pub const Transfer = struct {
uri: std.Uri, // used for setting/getting the cookie
ctx: *anyopaque, // copied from req.ctx to make it easier for callback handlers
client: *Client,
_notified_fail: bool = false,
// total bytes received in the response, including the response status line,
// the headers, and the [encoded] body.
bytes_received: usize = 0,

// We'll store the response header here
response_header: ?ResponseHeader = null,

_notified_fail: bool = false,

_handle: ?*Handle = null,

_redirecting: bool = false,
Expand Down Expand Up @@ -716,9 +726,11 @@ pub const Transfer = struct {
.url = url,
.status = status,
};
transfer.bytes_received = buf_len;
return buf_len;
}

transfer.bytes_received += buf_len;
if (buf_len == 2) {
if (getResponseHeader(easy, "content-type", 0)) |ct| {
var hdr = &transfer.response_header.?;
Expand Down Expand Up @@ -777,6 +789,7 @@ pub const Transfer = struct {
return chunk_len;
}

transfer.bytes_received += chunk_len;
transfer.req.data_callback(transfer, buffer[0..chunk_len]) catch |err| {
log.err(.http, "data_callback", .{ .err = err, .req = transfer });
return c.CURL_WRITEFUNC_ERROR;
Expand Down
6 changes: 6 additions & 0 deletions src/notification.zig
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ pub const Notification = struct {
http_request_start: List = .{},
http_request_intercept: List = .{},
http_headers_done: List = .{},
http_request_done: List = .{},
notification_created: List = .{},
};

Expand All @@ -76,6 +77,7 @@ pub const Notification = struct {
http_request_start: *const RequestStart,
http_request_intercept: *const RequestIntercept,
http_headers_done: *const ResponseHeadersDone,
http_request_done: *const RequestDone,
notification_created: *Notification,
};
const EventType = std.meta.FieldEnum(Events);
Expand Down Expand Up @@ -106,6 +108,10 @@ pub const Notification = struct {
transfer: *Transfer,
};

pub const RequestDone = struct {
transfer: *Transfer,
};

pub const RequestFail = struct {
transfer: *Transfer,
err: anyerror,
Expand Down