Skip to content

Commit 47aa966

Browse files
committed
working Header iterators
1 parent 8074d72 commit 47aa966

File tree

4 files changed

+71
-14
lines changed

4 files changed

+71
-14
lines changed

src/browser/fetch/Headers.zig

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,17 @@ pub fn constructor(_init: ?HeadersInit, page: *Page) !Headers {
7979
return error.TypeError;
8080
}
8181

82-
const key = try page.arena.dupe(u8, pair[0]);
83-
const value = try page.arena.dupe(u8, pair[1]);
82+
const key = try arena.dupe(u8, pair[0]);
83+
const value = try arena.dupe(u8, pair[1]);
8484

8585
try headers.put(arena, key, value);
8686
}
8787
},
8888
.headers => |hdrs| {
8989
var iter = hdrs.headers.iterator();
9090
while (iter.next()) |entry| {
91-
const key = try page.arena.dupe(u8, entry.key_ptr.*);
92-
const value = try page.arena.dupe(u8, entry.value_ptr.*);
91+
const key = try arena.dupe(u8, entry.key_ptr.*);
92+
const value = try arena.dupe(u8, entry.value_ptr.*);
9393
try headers.put(arena, key, value);
9494
}
9595
},
@@ -129,10 +129,29 @@ pub fn _delete(self: *Headers, name: []const u8) void {
129129
_ = self.headers.remove(name);
130130
}
131131

132-
// TODO: entries iterator
133-
// They should be:
134-
// 1. Sorted in lexicographical order.
135-
// 2. Duplicate header names should be combined.
132+
pub const HeaderEntryIterator = struct {
133+
slot: [][]const u8,
134+
iter: *HeaderHashMap.Iterator,
135+
136+
// TODO: these SHOULD be in lexigraphical order but I'm not sure how actually
137+
// important that is.
138+
pub fn _next(self: *HeaderEntryIterator) !?[]const []const u8 {
139+
if (self.iter.next()) |entry| {
140+
self.slot[0] = entry.key_ptr.*;
141+
self.slot[1] = entry.value_ptr.*;
142+
return self.slot;
143+
} else {
144+
return null;
145+
}
146+
}
147+
};
148+
149+
pub fn _entries(self: *const Headers, page: *Page) !HeaderEntryIterator {
150+
const iter = try page.arena.create(HeaderHashMap.Iterator);
151+
iter.* = self.headers.iterator();
152+
153+
return .{ .slot = try page.arena.alloc([]const u8, 2), .iter = iter };
154+
}
136155

137156
pub fn _forEach(self: *Headers, callback_fn: Env.Function, this_arg: ?Env.JsObject) !void {
138157
var iter = self.headers.iterator();
@@ -163,7 +182,24 @@ pub fn _has(self: *const Headers, name: []const u8) bool {
163182
return self.headers.contains(name);
164183
}
165184

166-
// TODO: keys iterator
185+
pub const HeaderKeyIterator = struct {
186+
iter: *HeaderHashMap.KeyIterator,
187+
188+
pub fn _next(self: *HeaderKeyIterator) !?[]const u8 {
189+
if (self.iter.next()) |key| {
190+
return key.*;
191+
} else {
192+
return null;
193+
}
194+
}
195+
};
196+
197+
pub fn _keys(self: *const Headers, page: *Page) !HeaderKeyIterator {
198+
const iter = try page.arena.create(HeaderHashMap.KeyIterator);
199+
iter.* = self.headers.keyIterator();
200+
201+
return .{ .iter = iter };
202+
}
167203

168204
pub fn _set(self: *Headers, name: []const u8, value: []const u8, page: *Page) !void {
169205
const arena = page.arena;
@@ -172,7 +208,23 @@ pub fn _set(self: *Headers, name: []const u8, value: []const u8, page: *Page) !v
172208
gop.value_ptr.* = try arena.dupe(u8, value);
173209
}
174210

175-
// TODO: values iterator
211+
pub const HeaderValueIterator = struct {
212+
iter: *HeaderHashMap.ValueIterator,
213+
214+
pub fn _next(self: *HeaderValueIterator) !?[]const u8 {
215+
if (self.iter.next()) |value| {
216+
return value.*;
217+
} else {
218+
return null;
219+
}
220+
}
221+
};
222+
223+
pub fn _values(self: *const Headers, page: *Page) !HeaderValueIterator {
224+
const iter = try page.arena.create(HeaderHashMap.ValueIterator);
225+
iter.* = self.headers.valueIterator();
226+
return .{ .iter = iter };
227+
}
176228

177229
const testing = @import("../../testing.zig");
178230
test "fetch: headers" {

src/browser/fetch/Request.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ pub fn constructor(input: RequestInput, _options: ?RequestInit, page: *Page) !Re
9898
const arena = page.arena;
9999
const options: RequestInit = _options orelse .{};
100100

101-
const url = blk: switch (input) {
101+
const url: [:0]const u8 = blk: switch (input) {
102102
.string => |str| {
103103
break :blk try URL.stitch(arena, str, page.url.raw, .{ .null_terminated = true });
104104
},
@@ -111,7 +111,7 @@ pub fn constructor(input: RequestInput, _options: ?RequestInit, page: *Page) !Re
111111
const cache = (if (options.cache) |cache| RequestCache.fromString(cache) else null) orelse RequestCache.default;
112112
const credentials = (if (options.credentials) |creds| RequestCredentials.fromString(creds) else null) orelse RequestCredentials.@"same-origin";
113113
const integrity = if (options.integrity) |integ| try arena.dupe(u8, integ) else "";
114-
const headers = if (options.headers) |hdrs| try Headers.constructor(hdrs, page) else Headers{};
114+
const headers: Headers = if (options.headers) |hdrs| try Headers.constructor(hdrs, page) else .{};
115115

116116
const method: Http.Method = blk: {
117117
if (options.method) |given_method| {

src/browser/fetch/Response.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const Page = @import("../page.zig").Page;
3737
const Response = @This();
3838

3939
status: u16 = 0,
40-
headers: Headers = .{},
40+
headers: Headers,
4141
mime: ?Mime = null,
4242
url: []const u8 = "",
4343
body: []const u8 = "",

src/browser/fetch/fetch.zig

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const Page = @import("../page.zig").Page;
2626
const Http = @import("../../http/Http.zig");
2727
const HttpClient = @import("../../http/Client.zig");
2828
const Mime = @import("../mime.zig").Mime;
29+
2930
const Headers = @import("Headers.zig");
3031

3132
const RequestInput = @import("Request.zig").RequestInput;
@@ -35,6 +36,9 @@ const Response = @import("Response.zig");
3536

3637
pub const Interfaces = .{
3738
@import("Headers.zig"),
39+
@import("Headers.zig").HeaderEntryIterator,
40+
@import("Headers.zig").HeaderKeyIterator,
41+
@import("Headers.zig").HeaderValueIterator,
3842
@import("Request.zig"),
3943
@import("Response.zig"),
4044
};
@@ -157,6 +161,7 @@ pub fn fetch(input: RequestInput, options: ?RequestInit, page: *Page) !Env.Promi
157161
.done_callback = struct {
158162
fn doneCallback(ctx: *anyopaque) !void {
159163
const self: *FetchContext = @ptrCast(@alignCast(ctx));
164+
self.transfer = null;
160165

161166
log.info(.http, "request complete", .{
162167
.source = "fetch",
@@ -177,8 +182,8 @@ pub fn fetch(input: RequestInput, options: ?RequestInit, page: *Page) !Env.Promi
177182
.error_callback = struct {
178183
fn errorCallback(ctx: *anyopaque, err: anyerror) void {
179184
const self: *FetchContext = @ptrCast(@alignCast(ctx));
180-
181185
self.transfer = null;
186+
182187
const promise_resolver: Env.PromiseResolver = .{
183188
.js_context = self.js_ctx,
184189
.resolver = self.promise_resolver.castToPromiseResolver(),

0 commit comments

Comments
 (0)