diff --git a/src/browser/Page.zig b/src/browser/Page.zig index e270e27c..b417b4ad 100644 --- a/src/browser/Page.zig +++ b/src/browser/Page.zig @@ -171,6 +171,9 @@ url: [:0]const u8, // If null the url must be used. base_url: ?[:0]const u8, +// referer header cache. +referer_header: ?[:0]const u8, + // Arbitrary buffer. Need to temporarily lowercase a value? Use this. No lifetime // guarantee - it's valid until someone else uses it. buf: [BUF_SIZE]u8, @@ -299,6 +302,7 @@ fn reset(self: *Page, comptime initializing: bool) !void { self.version = 0; self.url = "about:blank"; self.base_url = null; + self.referer_header = null; self.document = (try self._factory.document(Node.Document.HTMLDocument{ ._proto = undefined })).asDocument(); @@ -395,6 +399,32 @@ pub fn getOrigin(self: *Page, allocator: Allocator) !?[]const u8 { return try URL.getOrigin(allocator, self.url); } +// Add comon headers for a request: +// * cookies +// * referer +pub fn headersForRequest(self: *Page, temp: Allocator, url: [:0]const u8, headers: *Http.Headers) !void { + try self.requestCookie(.{}).headersForRequest(temp, url, headers); + + // Build the referer + const referer = blk: { + if (self.referer_header == null) { + // build the cache + if (std.mem.startsWith(u8, self.url, "http")) { + self.referer_header = try std.mem.concatWithSentinel(self.arena, u8, &.{ "Referer: ", self.url }, 0); + } else { + self.referer_header = ""; + } + } + + break :blk self.referer_header.?; + }; + + // If the referer is empty, ignore the header. + if (referer.len > 0) { + try headers.add(referer); + } +} + const GetArenaOpts = struct { debug: []const u8, }; diff --git a/src/browser/ScriptManager.zig b/src/browser/ScriptManager.zig index 53ffa10a..be968870 100644 --- a/src/browser/ScriptManager.zig +++ b/src/browser/ScriptManager.zig @@ -138,6 +138,12 @@ fn clearList(list: *std.DoublyLinkedList) void { } } +pub fn getHeaders(self: *ScriptManager, url: [:0]const u8) !Http.Headers { + var headers = try self.client.newHeaders(); + try self.page.headersForRequest(self.page.arena, url, &headers); + return headers; +} + pub fn addFromElement(self: *ScriptManager, comptime from_parser: bool, script_element: *Element.Html.Script, comptime ctx: []const u8) !void { if (script_element._executed) { // If a script tag gets dynamically created and added to the dom: @@ -252,14 +258,11 @@ pub fn addFromElement(self: *ScriptManager, comptime from_parser: bool, script_e script.deinit(true); } - var headers = try self.client.newHeaders(); - try page.requestCookie(.{}).headersForRequest(page.arena, url, &headers); - try self.client.request(.{ .url = url, .ctx = script, .method = .GET, - .headers = headers, + .headers = try self.getHeaders(url), .blocking = is_blocking, .cookie_jar = &page._session.cookie_jar, .resource_type = .script, @@ -357,9 +360,6 @@ pub fn preloadImport(self: *ScriptManager, url: [:0]const u8, referrer: []const .manager = self, }; - var headers = try self.client.newHeaders(); - try self.page.requestCookie(.{}).headersForRequest(self.page.arena, url, &headers); - if (comptime IS_DEBUG) { var ls: js.Local.Scope = undefined; self.page.js.localScope(&ls); @@ -377,7 +377,7 @@ pub fn preloadImport(self: *ScriptManager, url: [:0]const u8, referrer: []const .url = url, .ctx = script, .method = .GET, - .headers = headers, + .headers = try self.getHeaders(url), .cookie_jar = &self.page._session.cookie_jar, .resource_type = .script, .start_callback = if (log.enabled(.http, .debug)) Script.startCallback else null, @@ -452,9 +452,6 @@ pub fn getAsyncImport(self: *ScriptManager, url: [:0]const u8, cb: ImportAsync.C } }, }; - var headers = try self.client.newHeaders(); - try self.page.requestCookie(.{}).headersForRequest(self.page.arena, url, &headers); - if (comptime IS_DEBUG) { var ls: js.Local.Scope = undefined; self.page.js.localScope(&ls); @@ -480,7 +477,7 @@ pub fn getAsyncImport(self: *ScriptManager, url: [:0]const u8, cb: ImportAsync.C try self.client.request(.{ .url = url, .method = .GET, - .headers = headers, + .headers = try self.getHeaders(url), .ctx = script, .resource_type = .script, .cookie_jar = &self.page._session.cookie_jar, diff --git a/src/browser/webapi/net/Fetch.zig b/src/browser/webapi/net/Fetch.zig index 6be804f4..78d77016 100644 --- a/src/browser/webapi/net/Fetch.zig +++ b/src/browser/webapi/net/Fetch.zig @@ -64,7 +64,7 @@ pub fn init(input: Input, options: ?InitOpts, page: *Page) !js.Promise { if (request._headers) |h| { try h.populateHttpHeader(page.call_arena, &headers); } - try page.requestCookie(.{}).headersForRequest(page.arena, request._url, &headers); + try page.headersForRequest(page.arena, request._url, &headers); if (comptime IS_DEBUG) { log.debug(.http, "fetch", .{ .url = request._url }); diff --git a/src/browser/webapi/net/XMLHttpRequest.zig b/src/browser/webapi/net/XMLHttpRequest.zig index dc75b6f7..8a28e200 100644 --- a/src/browser/webapi/net/XMLHttpRequest.zig +++ b/src/browser/webapi/net/XMLHttpRequest.zig @@ -197,7 +197,7 @@ pub fn send(self: *XMLHttpRequest, body_: ?[]const u8) !void { const http_client = page._session.browser.http_client; var headers = try http_client.newHeaders(); try self._request_headers.populateHttpHeader(page.call_arena, &headers); - try page.requestCookie(.{}).headersForRequest(self._arena, self._url, &headers); + try page.headersForRequest(self._arena, self._url, &headers); try http_client.request(.{ .ctx = self,