From 00d75584dbcd015f9406bfa208ce569bcb9d5c7c Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Tue, 23 Apr 2024 12:09:41 +0200 Subject: [PATCH] usrctx: use ctx http client with xhr --- src/browser/browser.zig | 13 +++++++++++++ src/main_shell.zig | 5 +++++ src/run_tests.zig | 15 +++++++++------ src/user_context.zig | 2 ++ src/wpt/run.zig | 6 ++++++ src/xhr/xhr.zig | 12 +++++------- 6 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/browser/browser.zig b/src/browser/browser.zig index b17173da..19982663 100644 --- a/src/browser/browser.zig +++ b/src/browser/browser.zig @@ -39,6 +39,9 @@ const storage = @import("../storage/storage.zig"); const FetchResult = std.http.Client.FetchResult; +const UserContext = @import("../user_context.zig").UserContext; +const HttpClient = @import("../async/Client.zig"); + const log = std.log.scoped(.browser); // Browser is an instance of the browser. @@ -92,6 +95,7 @@ pub const Session = struct { // TODO move the shed to the browser? storageShed: storage.Shed, page: ?*Page = null, + httpClient: HttpClient, jstypes: [Types.len]usize = undefined, @@ -105,9 +109,11 @@ pub const Session = struct { .loader = Loader.init(alloc), .loop = try Loop.init(alloc), .storageShed = storage.Shed.init(alloc), + .httpClient = undefined, }; self.env = try Env.init(self.arena.allocator(), &self.loop, null); + self.httpClient = .{ .allocator = alloc, .loop = &self.loop }; try self.env.load(&self.jstypes); return self; @@ -122,6 +128,7 @@ pub const Session = struct { self.loader.deinit(); self.loop.deinit(); self.storageShed.deinit(); + self.httpClient.deinit(); self.alloc.destroy(self); } @@ -289,6 +296,12 @@ pub const Page = struct { log.debug("start js env", .{}); try self.session.env.start(alloc); + // replace the user context document with the new one. + try self.session.env.setUserContext(.{ + .document = html_doc, + .httpClient = &self.session.httpClient, + }); + // add global objects log.debug("setup global env", .{}); try self.session.env.bindGlobal(&self.session.window); diff --git a/src/main_shell.zig b/src/main_shell.zig index 8560861a..6eb6c11a 100644 --- a/src/main_shell.zig +++ b/src/main_shell.zig @@ -29,6 +29,7 @@ const html_test = @import("html_test.zig").html; pub const Types = jsruntime.reflect(apiweb.Interfaces); pub const UserContext = apiweb.UserContext; +const Client = @import("async/Client.zig"); var doc: *parser.DocumentHTML = undefined; @@ -40,8 +41,12 @@ fn execJS( try js_env.start(alloc); defer js_env.stop(); + var cli = Client{ .allocator = alloc, .loop = js_env.nat_ctx.loop }; + defer cli.deinit(); + try js_env.setUserContext(UserContext{ .document = doc, + .httpClient = &cli, }); var storageShelf = storage.Shelf.init(alloc); diff --git a/src/run_tests.zig b/src/run_tests.zig index 5eb470be..700d15c0 100644 --- a/src/run_tests.zig +++ b/src/run_tests.zig @@ -30,6 +30,7 @@ const xhr = @import("xhr/xhr.zig"); const storage = @import("storage/storage.zig"); const url = @import("url/url.zig"); const urlquery = @import("url/query.zig"); +const Client = @import("async/Client.zig"); const documentTestExecFn = @import("dom/document.zig").testExecFn; const HTMLDocumentTestExecFn = @import("html/document.zig").testExecFn; @@ -84,7 +85,13 @@ fn testExecFn( std.debug.print("documentHTMLClose error: {s}\n", .{@errorName(err)}); }; - js_env.getUserContext().?.document = doc; + var cli = Client{ .allocator = alloc, .loop = js_env.nat_ctx.loop }; + defer cli.deinit(); + + try js_env.setUserContext(.{ + .document = doc, + .httpClient = &cli, + }); // alias global as self and window var window = Window.create(null); @@ -322,11 +329,7 @@ fn testJSRuntime(alloc: std.mem.Allocator) !void { var arena_alloc = std.heap.ArenaAllocator.init(alloc); defer arena_alloc.deinit(); - const userctx = UserContext{ - .document = null, - }; - - try jsruntime.loadEnv(&arena_alloc, userctx, testsAllExecFn); + try jsruntime.loadEnv(&arena_alloc, null, testsAllExecFn); } test "DocumentHTMLParseFromStr" { diff --git a/src/user_context.zig b/src/user_context.zig index 0a90bfd4..4860100d 100644 --- a/src/user_context.zig +++ b/src/user_context.zig @@ -1,6 +1,8 @@ const std = @import("std"); const parser = @import("netsurf.zig"); +const Client = @import("async/Client.zig"); pub const UserContext = struct { document: *parser.DocumentHTML, + httpClient: *Client, }; diff --git a/src/wpt/run.zig b/src/wpt/run.zig index 8b0e7516..4322ee40 100644 --- a/src/wpt/run.zig +++ b/src/wpt/run.zig @@ -31,6 +31,7 @@ const storage = @import("../storage/storage.zig"); const Types = @import("../main_wpt.zig").Types; const UserContext = @import("../main_wpt.zig").UserContext; +const Client = @import("../async/Client.zig"); // runWPT parses the given HTML file, starts a js env and run the first script // tags containing javascript sources. @@ -51,8 +52,13 @@ pub fn run(arena: *std.heap.ArenaAllocator, comptime dir: []const u8, f: []const // create JS env var loop = try Loop.init(alloc); defer loop.deinit(); + + var cli = Client{ .allocator = alloc, .loop = &loop }; + defer cli.deinit(); + var js_env = try Env.init(alloc, &loop, UserContext{ .document = html_doc, + .httpClient = &cli, }); defer js_env.deinit(); diff --git a/src/xhr/xhr.zig b/src/xhr/xhr.zig index 8719e2fc..e395144a 100644 --- a/src/xhr/xhr.zig +++ b/src/xhr/xhr.zig @@ -37,6 +37,8 @@ const Client = @import("../async/Client.zig"); const parser = @import("../netsurf.zig"); +const UserContext = @import("../user_context.zig").UserContext; + const log = std.log.scoped(.xhr); // XHR interfaces @@ -149,7 +151,7 @@ pub const XMLHttpRequest = struct { proto: XMLHttpRequestEventTarget = XMLHttpRequestEventTarget{}, alloc: std.mem.Allocator, - cli: Client, + cli: *Client, impl: YieldImpl, priv_state: PrivState = .new, @@ -185,7 +187,7 @@ pub const XMLHttpRequest = struct { const min_delay: u64 = 50000000; // 50ms - pub fn constructor(alloc: std.mem.Allocator, loop: *Loop) !XMLHttpRequest { + pub fn constructor(alloc: std.mem.Allocator, loop: *Loop, userctx: UserContext) !XMLHttpRequest { return .{ .alloc = alloc, .headers = .{ .allocator = alloc, .owned = true }, @@ -195,8 +197,7 @@ pub const XMLHttpRequest = struct { .url = null, .uri = undefined, .state = UNSENT, - // TODO retrieve the HTTP client globally to reuse existing connections. - .cli = .{ .allocator = alloc, .loop = loop }, + .cli = userctx.httpClient, }; } @@ -235,9 +236,6 @@ pub const XMLHttpRequest = struct { self.response_headers.deinit(); self.proto.deinit(alloc); - - // TODO the client must be shared between requests. - self.cli.deinit(); } pub fn get_readyState(self: *XMLHttpRequest) u16 {