Skip to content

Commit ff8a847

Browse files
Merge pull request #957 from lightpanda-io/remove_header_callback
Remove the http/Client.zig header_callback.
2 parents 00c11d9 + 5759c88 commit ff8a847

File tree

4 files changed

+70
-39
lines changed

4 files changed

+70
-39
lines changed

src/browser/ScriptManager.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ pub fn addFromElement(self: *ScriptManager, element: *parser.Element) !void {
240240
.cookie_jar = page.cookie_jar,
241241
.resource_type = .script,
242242
.start_callback = if (log.enabled(.http, .debug)) startCallback else null,
243-
.header_done_callback = headerCallback,
243+
.header_callback = headerCallback,
244244
.data_callback = dataCallback,
245245
.done_callback = doneCallback,
246246
.error_callback = errorCallback,
@@ -309,7 +309,7 @@ pub fn blockingGet(self: *ScriptManager, url: [:0]const u8) !BlockingResult {
309309
.ctx = &blocking,
310310
.resource_type = .script,
311311
.start_callback = if (log.enabled(.http, .debug)) Blocking.startCallback else null,
312-
.header_done_callback = Blocking.headerCallback,
312+
.header_callback = Blocking.headerCallback,
313313
.data_callback = Blocking.dataCallback,
314314
.done_callback = Blocking.doneCallback,
315315
.error_callback = Blocking.errorCallback,

src/browser/page.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ pub const Page = struct {
520520
.body = opts.body,
521521
.cookie_jar = self.cookie_jar,
522522
.resource_type = .document,
523-
.header_done_callback = pageHeaderDoneCallback,
523+
.header_callback = pageHeaderDoneCallback,
524524
.data_callback = pageDataCallback,
525525
.done_callback = pageDoneCallback,
526526
.error_callback = pageErrorCallback,

src/browser/xhr/xhr.zig

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,7 @@ pub const XMLHttpRequest = struct {
385385
.cookie_jar = page.cookie_jar,
386386
.resource_type = .xhr,
387387
.start_callback = httpStartCallback,
388-
.header_callback = httpHeaderCallback,
389-
.header_done_callback = httpHeaderDoneCallback,
388+
.header_callback = httpHeaderDoneCallback,
390389
.data_callback = httpDataCallback,
391390
.done_callback = httpDoneCallback,
392391
.error_callback = httpErrorCallback,
@@ -422,6 +421,12 @@ pub const XMLHttpRequest = struct {
422421
};
423422
}
424423

424+
var it = transfer.responseHeaderIterator();
425+
while (it.next()) |hdr| {
426+
const joined = try std.fmt.allocPrint(self.arena, "{s}: {s}", .{ hdr.name, hdr.value });
427+
try self.response_headers.append(self.arena, joined);
428+
}
429+
425430
// TODO handle override mime type
426431
self.state = .headers_received;
427432
self.dispatchEvt("readystatechange");

src/http/Client.zig

Lines changed: 60 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -532,8 +532,7 @@ pub const Request = struct {
532532
ctx: *anyopaque = undefined,
533533

534534
start_callback: ?*const fn (transfer: *Transfer) anyerror!void = null,
535-
header_callback: ?*const fn (transfer: *Transfer, header: Http.Header) anyerror!void = null,
536-
header_done_callback: *const fn (transfer: *Transfer) anyerror!void,
535+
header_callback: *const fn (transfer: *Transfer) anyerror!void,
537536
data_callback: *const fn (transfer: *Transfer, data: []const u8) anyerror!void,
538537
done_callback: *const fn (ctx: *anyopaque) anyerror!void,
539538
error_callback: *const fn (ctx: *anyopaque, err: anyerror) void,
@@ -739,8 +738,8 @@ pub const Transfer = struct {
739738
if (i >= ct.?.amount) break;
740739
}
741740

742-
transfer.req.header_done_callback(transfer) catch |err| {
743-
log.err(.http, "header_done_callback", .{ .err = err, .req = transfer });
741+
transfer.req.header_callback(transfer) catch |err| {
742+
log.err(.http, "header_callback", .{ .err = err, .req = transfer });
744743
// returning < buf_len terminates the request
745744
return 0;
746745
};
@@ -750,15 +749,6 @@ pub const Transfer = struct {
750749
.transfer = transfer,
751750
});
752751
}
753-
} else {
754-
if (transfer.req.header_callback) |cb| {
755-
if (Http.Headers.parseHeader(header)) |hdr| {
756-
cb(transfer, hdr) catch |err| {
757-
log.err(.http, "header_callback", .{ .err = err, .req = transfer });
758-
return 0;
759-
};
760-
}
761-
}
762752
}
763753
return buf_len;
764754
}
@@ -784,10 +774,17 @@ pub const Transfer = struct {
784774
return chunk_len;
785775
}
786776

787-
// we assume that the caller is smart and only calling this after being
788-
// told that the header was ready.
789777
pub fn responseHeaderIterator(self: *Transfer) HeaderIterator {
790-
return .{ .easy = self._handle.?.conn.easy };
778+
if (self._handle) |handle| {
779+
// If we have a handle, than this is a real curl request and we
780+
// iterate through the header that curl maintains.
781+
return .{ .curl = .{ .easy = handle.conn.easy } };
782+
}
783+
// If there's no handle, it either means this is being called before
784+
// the request is even being made (which would be a bug in the code)
785+
// or when a response was injected via transfer.fulfill. The injected
786+
// header should be iterated, since there is no handle/easy.
787+
return .{ .list = .{ .list = self.response_header.?._injected_headers } };
791788
}
792789

793790
// pub because Page.printWaitAnalysis uses it
@@ -817,15 +814,10 @@ pub const Transfer = struct {
817814
try cb(transfer);
818815
}
819816

820-
if (req.header_callback) |cb| {
821-
for (headers) |hdr| {
822-
try cb(transfer, hdr);
823-
}
824-
}
825-
826817
transfer.response_header = .{
827818
.status = status,
828819
.url = req.url,
820+
._injected_headers = headers,
829821
};
830822
for (headers) |hdr| {
831823
if (std.ascii.eqlIgnoreCase(hdr.name, "content-type")) {
@@ -835,7 +827,7 @@ pub const Transfer = struct {
835827
}
836828
}
837829

838-
try req.header_done_callback(transfer);
830+
try req.header_callback(transfer);
839831

840832
if (body) |b| {
841833
try req.data_callback(transfer, b);
@@ -852,6 +844,11 @@ pub const ResponseHeader = struct {
852844
url: [*c]const u8,
853845
_content_type_len: usize = 0,
854846
_content_type: [MAX_CONTENT_TYPE_LEN]u8 = undefined,
847+
// this is normally an empty list, but if the response is being injected
848+
// than it'll be populated. It isn't meant to be used directly, but should
849+
// be used through the transfer.responseHeaderIterator() which abstracts
850+
// whether the headers are from a live curl easy handle, or injected.
851+
_injected_headers: []const Http.Header = &.{},
855852

856853
pub fn contentType(self: *ResponseHeader) ?[]u8 {
857854
if (self._content_type_len == 0) {
@@ -861,20 +858,49 @@ pub const ResponseHeader = struct {
861858
}
862859
};
863860

864-
const HeaderIterator = struct {
865-
easy: *c.CURL,
866-
prev: ?*c.curl_header = null,
861+
// In normal cases, the header iterator comes from the curl linked list.
862+
// But it's also possible to inject a response, via `transfer.fulfill`. In that
863+
// case, the resposne headers are a list, []const Http.Header.
864+
// This union, is an iterator that exposes the same API for either case.
865+
const HeaderIterator = union(enum) {
866+
curl: CurlHeaderIterator,
867+
list: ListHeaderIterator,
867868

868869
pub fn next(self: *HeaderIterator) ?Http.Header {
869-
const h = c.curl_easy_nextheader(self.easy, c.CURLH_HEADER, -1, self.prev) orelse return null;
870-
self.prev = h;
871-
872-
const header = h.*;
873-
return .{
874-
.name = std.mem.span(header.name),
875-
.value = std.mem.span(header.value),
876-
};
870+
switch (self.*) {
871+
inline else => |*it| return it.next(),
872+
}
877873
}
874+
875+
const CurlHeaderIterator = struct {
876+
easy: *c.CURL,
877+
prev: ?*c.curl_header = null,
878+
879+
pub fn next(self: *CurlHeaderIterator) ?Http.Header {
880+
const h = c.curl_easy_nextheader(self.easy, c.CURLH_HEADER, -1, self.prev) orelse return null;
881+
self.prev = h;
882+
883+
const header = h.*;
884+
return .{
885+
.name = std.mem.span(header.name),
886+
.value = std.mem.span(header.value),
887+
};
888+
}
889+
};
890+
891+
const ListHeaderIterator = struct {
892+
index: usize = 0,
893+
list: []const Http.Header,
894+
895+
pub fn next(self: *ListHeaderIterator) ?Http.Header {
896+
const index = self.index;
897+
if (index == self.list.len) {
898+
return null;
899+
}
900+
self.index = index + 1;
901+
return self.list[index];
902+
}
903+
};
878904
};
879905

880906
const CurlHeaderValue = struct {

0 commit comments

Comments
 (0)