fix header done callback

This commit is contained in:
Karl Seguin
2025-08-14 14:51:02 +08:00
parent 35e2fa5058
commit 5100e06f38
2 changed files with 25 additions and 22 deletions

View File

@@ -53,32 +53,36 @@ pub fn processMessage(cmd: anytype) !void {
const Response = struct { const Response = struct {
status: u16, status: u16,
headers: std.StringArrayHashMapUnmanaged([]const u8) = .empty, // These may not be complete yet, but we only tell the client Network.responseReceived when all the headers are in headers: std.StringArrayHashMapUnmanaged([]const u8) = .empty,
// Later should store body as well to support getResponseBody which should only work once Network.loadingFinished is sent // These may not be complete yet, but we only tell the client
// but the body itself would be loaded with each chunks as Network.dataReceiveds are coming in. // Network.responseReceived when all the headers are in.
// Later should store body as well to support getResponseBody which should
// only work once Network.loadingFinished is sent but the body itself would
// be loaded with each chunks as Network.dataReceiveds are coming in.
}; };
// Stored in CDP // Stored in CDP
pub const NetworkState = struct { pub const NetworkState = struct {
const Self = @This();
received: std.AutoArrayHashMap(u64, Response),
arena: std.heap.ArenaAllocator, arena: std.heap.ArenaAllocator,
received: std.AutoArrayHashMap(u64, Response),
pub fn init(allocator: Allocator) !NetworkState { pub fn init(allocator: Allocator) !NetworkState {
return .{ return .{
.received = std.AutoArrayHashMap(u64, Response).init(allocator),
.arena = std.heap.ArenaAllocator.init(allocator), .arena = std.heap.ArenaAllocator.init(allocator),
.received = std.AutoArrayHashMap(u64, Response).init(allocator),
}; };
} }
pub fn deinit(self: *Self) void { pub fn deinit(self: *NetworkState) void {
self.received.deinit(); self.received.deinit();
self.arena.deinit(); self.arena.deinit();
} }
pub fn putOrAppendReceivedHeader(self: *NetworkState, request_id: u64, status: u16, header: std.http.Header) !void { pub fn putOrAppendReceivedHeader(self: *NetworkState, request_id: u64, status: u16, header: std.http.Header) !void {
const kv = try self.received.getOrPut(request_id); const kv = try self.received.getOrPut(request_id);
if (!kv.found_existing) kv.value_ptr.* = .{ .status = status }; if (!kv.found_existing) {
kv.value_ptr.* = .{ .status = status };
}
const a = self.arena.allocator(); const a = self.arena.allocator();
const name = try a.dupe(u8, header.name); const name = try a.dupe(u8, header.name);

View File

@@ -247,13 +247,12 @@ fn makeTransfer(self: *Client, req: Request) !*Transfer {
.req = req, .req = req,
.ctx = req.ctx, .ctx = req.ctx,
.client = self, .client = self,
.notification = &self.notification,
}; };
return transfer; return transfer;
} }
fn requestFailed(self: *Client, transfer: *Transfer, err: anyerror) void { fn requestFailed(self: *Client, transfer: *Transfer, err: anyerror) void {
// this shoudln't happen, we'll crash in debug mode. But in release, we'll // this shouldn't happen, we'll crash in debug mode. But in release, we'll
// just noop this state. // just noop this state.
std.debug.assert(transfer._notified_fail == false); std.debug.assert(transfer._notified_fail == false);
if (transfer._notified_fail) { if (transfer._notified_fail) {
@@ -550,8 +549,6 @@ pub const Transfer = struct {
_redirecting: bool = false, _redirecting: bool = false,
notification: *?*Notification, // Points to the Client's notification. TBD if a Browser can remove the notification before all Transfers are gone.
fn deinit(self: *Transfer) void { fn deinit(self: *Transfer) void {
self.req.headers.deinit(); self.req.headers.deinit();
if (self._handle) |handle| { if (self._handle) |handle| {
@@ -676,7 +673,8 @@ pub const Transfer = struct {
// returning < buf_len terminates the request // returning < buf_len terminates the request
return 0; return 0;
}; };
if (transfer.notification.*) |notification| { // TBD before or after callback?
if (transfer.client.notification) |notification| {
notification.dispatch(.http_headers_done_receiving, &.{ notification.dispatch(.http_headers_done_receiving, &.{
.transfer = transfer, .transfer = transfer,
}); });
@@ -687,15 +685,16 @@ pub const Transfer = struct {
log.err(.http, "header_callback", .{ .err = err, .req = transfer }); log.err(.http, "header_callback", .{ .err = err, .req = transfer });
return 0; return 0;
}; };
if (transfer.notification.*) |notification| { // TBD before or after callback? }
if (Http.Headers.parseHeader(header)) |hdr_name_value| {
notification.dispatch(.http_header_received, &.{ if (transfer.client.notification) |notification| {
.request_id = transfer.id, if (Http.Headers.parseHeader(header)) |hdr_name_value| {
.status = hdr.status, notification.dispatch(.http_header_received, &.{
.header = hdr_name_value, .request_id = transfer.id,
}); .status = hdr.status,
} else log.err(.http, "invalid header", .{ .line = header }); .header = hdr_name_value,
} });
} else log.err(.http, "invalid header", .{ .line = header });
} }
} }
return buf_len; return buf_len;