diff --git a/src/browser/webapi/element/html/Image.zig b/src/browser/webapi/element/html/Image.zig
index 86f82d1d..9576fde7 100644
--- a/src/browser/webapi/element/html/Image.zig
+++ b/src/browser/webapi/element/html/Image.zig
@@ -5,13 +5,6 @@ const Node = @import("../../Node.zig");
const Element = @import("../../Element.zig");
const HtmlElement = @import("../Html.zig");
-pub fn registerTypes() []const type {
- return &.{
- Image,
- // Factory,
- };
-}
-
const Image = @This();
_proto: *HtmlElement,
diff --git a/src/browser/webapi/net/Fetch.zig b/src/browser/webapi/net/Fetch.zig
index 547a6ab1..d3589ee2 100644
--- a/src/browser/webapi/net/Fetch.zig
+++ b/src/browser/webapi/net/Fetch.zig
@@ -24,6 +24,7 @@ const Http = @import("../../../http/Http.zig");
const js = @import("../../js/js.zig");
const Page = @import("../../Page.zig");
+const Headers = @import("Headers.zig");
const Request = @import("Request.zig");
const Response = @import("Response.zig");
@@ -32,20 +33,22 @@ const Allocator = std.mem.Allocator;
const Fetch = @This();
_page: *Page,
-_response: std.ArrayList(u8),
+_buf: std.ArrayList(u8),
+_response: *Response,
_resolver: js.PersistentPromiseResolver,
pub const Input = Request.Input;
-// @ZIGDOM just enough to get campire demo working
+// @ZIGDOM just enough to get campfire demo working
pub fn init(input: Input, page: *Page) !js.Promise {
const request = try Request.init(input, null, page);
const fetch = try page.arena.create(Fetch);
fetch.* = .{
._page = page,
- ._response = .empty,
+ ._buf = .empty,
._resolver = try page.js.createPromiseResolver(.page),
+ ._response = try Response.init(null, .{ .status = 0 }, page),
};
const http_client = page._session.browser.http_client;
@@ -68,20 +71,28 @@ pub fn init(input: Input, page: *Page) !js.Promise {
fn httpHeaderDoneCallback(transfer: *Http.Transfer) !void {
const self: *Fetch = @ptrCast(@alignCast(transfer.ctx));
- _ = self;
+
+ if (transfer.getContentLength()) |cl| {
+ try self._buf.ensureTotalCapacity(self._page.arena, cl);
+ }
+
+ const res = self._response;
+ res._status = transfer.response_header.?.status;
+ var it = transfer.responseHeaderIterator();
+ while (it.next()) |hdr| {
+ try res._headers.append(hdr.name, hdr.value, self._page);
+ }
}
fn httpDataCallback(transfer: *Http.Transfer, data: []const u8) !void {
const self: *Fetch = @ptrCast(@alignCast(transfer.ctx));
- try self._response.appendSlice(self._page.arena, data);
+ try self._buf.appendSlice(self._page.arena, data);
}
fn httpDoneCallback(ctx: *anyopaque) !void {
const self: *Fetch = @ptrCast(@alignCast(ctx));
-
- const page = self._page;
- const res = try Response.initFromFetch(page.arena, self._response.items, page);
- return self._resolver.resolve(res);
+ self._response._body = self._buf.items;
+ return self._resolver.resolve(self._response);
}
fn httpErrorCallback(ctx: *anyopaque, err: anyerror) void {
diff --git a/src/browser/webapi/net/Response.zig b/src/browser/webapi/net/Response.zig
index de1c151b..bc66fb00 100644
--- a/src/browser/webapi/net/Response.zig
+++ b/src/browser/webapi/net/Response.zig
@@ -26,8 +26,9 @@ const Allocator = std.mem.Allocator;
const Response = @This();
_status: u16,
-_data: []const u8,
_arena: Allocator,
+_headers: *Headers,
+_body: []const u8,
const InitOpts = struct {
status: u16 = 200,
@@ -39,17 +40,10 @@ pub fn init(body_: ?[]const u8, opts_: ?InitOpts, page: *Page) !*Response {
const opts = opts_ orelse InitOpts{};
return page._factory.create(Response{
- ._status = opts.status,
- ._data = if (body_) |b| try page.arena.dupe(u8, b) else "",
._arena = page.arena,
- });
-}
-
-pub fn initFromFetch(arena: Allocator, data: []const u8, page: *Page) !*Response {
- return page._factory.create(Response{
- ._status = 200,
- ._data = data,
- ._arena = arena,
+ ._status = opts.status,
+ ._body = if (body_) |b| try page.arena.dupe(u8, b) else "",
+ ._headers = opts.headers orelse try Headers.init(page),
});
}
@@ -57,6 +51,10 @@ pub fn getStatus(self: *const Response) u16 {
return self._status;
}
+pub fn getHeaders(self: *const Response) *Headers {
+ return self._headers;
+}
+
pub fn isOK(self: *const Response) bool {
return self._status >= 200 and self._status <= 299;
}
@@ -65,7 +63,7 @@ pub fn getJson(self: *Response, page: *Page) !js.Promise {
const value = std.json.parseFromSliceLeaky(
std.json.Value,
page.call_arena,
- self._data,
+ self._body,
.{},
) catch |err| {
return page.js.rejectPromise(.{@errorName(err)});
@@ -86,4 +84,5 @@ pub const JsApi = struct {
pub const ok = bridge.accessor(Response.isOK, null, .{});
pub const status = bridge.accessor(Response.getStatus, null, .{});
pub const json = bridge.function(Response.getJson, .{});
+ pub const headers = bridge.accessor(Response.getHeaders, null, .{});
};