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, .{}); };