From 5100e06f381de3f5e56e272f9d4ddbb8ad5275f6 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Thu, 14 Aug 2025 14:51:02 +0800 Subject: [PATCH] fix header done callback --- src/cdp/domains/network.zig | 20 ++++++++++++-------- src/http/Client.zig | 27 +++++++++++++-------------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/cdp/domains/network.zig b/src/cdp/domains/network.zig index 548c323a..aa88f6f8 100644 --- a/src/cdp/domains/network.zig +++ b/src/cdp/domains/network.zig @@ -53,32 +53,36 @@ pub fn processMessage(cmd: anytype) !void { const Response = struct { 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 - // 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. + 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. + // 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 pub const NetworkState = struct { - const Self = @This(); - received: std.AutoArrayHashMap(u64, Response), arena: std.heap.ArenaAllocator, + received: std.AutoArrayHashMap(u64, Response), pub fn init(allocator: Allocator) !NetworkState { return .{ - .received = std.AutoArrayHashMap(u64, Response).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.arena.deinit(); } pub fn putOrAppendReceivedHeader(self: *NetworkState, request_id: u64, status: u16, header: std.http.Header) !void { 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 name = try a.dupe(u8, header.name); diff --git a/src/http/Client.zig b/src/http/Client.zig index 58e99112..e66ba9ec 100644 --- a/src/http/Client.zig +++ b/src/http/Client.zig @@ -247,13 +247,12 @@ fn makeTransfer(self: *Client, req: Request) !*Transfer { .req = req, .ctx = req.ctx, .client = self, - .notification = &self.notification, }; return transfer; } 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. std.debug.assert(transfer._notified_fail == false); if (transfer._notified_fail) { @@ -550,8 +549,6 @@ pub const Transfer = struct { _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 { self.req.headers.deinit(); if (self._handle) |handle| { @@ -676,7 +673,8 @@ pub const Transfer = struct { // returning < buf_len terminates the request return 0; }; - if (transfer.notification.*) |notification| { // TBD before or after callback? + + if (transfer.client.notification) |notification| { notification.dispatch(.http_headers_done_receiving, &.{ .transfer = transfer, }); @@ -687,15 +685,16 @@ pub const Transfer = struct { log.err(.http, "header_callback", .{ .err = err, .req = transfer }); return 0; }; - if (transfer.notification.*) |notification| { // TBD before or after callback? - if (Http.Headers.parseHeader(header)) |hdr_name_value| { - notification.dispatch(.http_header_received, &.{ - .request_id = transfer.id, - .status = hdr.status, - .header = hdr_name_value, - }); - } else log.err(.http, "invalid header", .{ .line = header }); - } + } + + if (transfer.client.notification) |notification| { + if (Http.Headers.parseHeader(header)) |hdr_name_value| { + notification.dispatch(.http_header_received, &.{ + .request_id = transfer.id, + .status = hdr.status, + .header = hdr_name_value, + }); + } else log.err(.http, "invalid header", .{ .line = header }); } } return buf_len;