diff --git a/src/browser/HttpClient.zig b/src/browser/HttpClient.zig index c1f6b4fb..7c07cbb1 100644 --- a/src/browser/HttpClient.zig +++ b/src/browser/HttpClient.zig @@ -866,27 +866,6 @@ fn ensureNoActiveConnection(self: *const Client) !void { } } -pub const RequestCookie = struct { - is_http: bool, - jar: *CookieJar, - is_navigation: bool, - origin: [:0]const u8, - - pub fn headersForRequest(self: *const RequestCookie, temp: Allocator, url: [:0]const u8, headers: *http.Headers) !void { - var arr: std.ArrayList(u8) = .{}; - try self.jar.forRequest(url, arr.writer(temp), .{ - .is_http = self.is_http, - .is_navigation = self.is_navigation, - .origin_url = self.origin, - }); - - if (arr.items.len > 0) { - try arr.append(temp, 0); //null terminate - headers.cookies = @as([*c]const u8, @ptrCast(arr.items.ptr)); - } - } -}; - pub const Request = struct { frame_id: u32, method: Method, @@ -1075,9 +1054,20 @@ pub const Transfer = struct { try wba.signRequest(self.arena.allocator(), &header_list, authority); } - // Add cookies. - if (header_list.cookies) |cookies| { - try conn.setCookies(cookies); + // Add cookies from cookie jar. + if (req.cookie_jar) |jar| { + const arena = self.arena.allocator(); + var aw: std.Io.Writer.Allocating = .init(arena); + try jar.forRequest(req.url, &aw.writer, .{ + .is_http = true, + .origin_url = req.url, + .is_navigation = req.resource_type == .document, + }); + const written = aw.written(); + if (written.len > 0) { + try aw.writer.writeByte(0); + try conn.setCookies(@ptrCast(written.ptr)); + } } try conn.setPrivate(self); @@ -1150,13 +1140,10 @@ pub const Transfer = struct { return error.TooManyRedirects; } - lp.log.warn(.bug, "Redirecting...", .{}); - // retrieve cookies from the redirect's response. if (req.cookie_jar) |jar| { var i: usize = 0; while (conn.getResponseHeader("set-cookie", i)) |ct| : (i += 1) { - lp.log.warn(.bug, "set-cookie", .{ i, ct.value }); try jar.populateFromResponse(transfer.url, ct.value); if (i >= ct.amount) { @@ -1181,23 +1168,6 @@ pub const Transfer = struct { req.method = .GET; req.body = null; } - - // set cookies for the following request. - if (req.cookie_jar) |jar| { - var cookies: std.ArrayList(u8) = .{}; - try jar.forRequest(url, cookies.writer(arena), .{ - .is_http = true, - .origin_url = url, - .is_navigation = req.resource_type == .document, - }); - if (cookies.items.len > 0) { - try cookies.append(arena, 0); // null terminate - req.headers.cookies = @ptrCast(cookies.items.ptr); - } else { - req.headers.cookies = null; - } - lp.log.warn(.bug, "cookie", .{cookies.items[0..]}); - } } fn detectAuthChallenge(transfer: *Transfer, conn: *const http.Connection) void { diff --git a/src/browser/Page.zig b/src/browser/Page.zig index c3a6b5a3..2344be12 100644 --- a/src/browser/Page.zig +++ b/src/browser/Page.zig @@ -371,12 +371,9 @@ pub fn getTitle(self: *Page) !?[]const u8 { return null; } -// Add comon headers for a request: -// * cookies +// Add common headers for a request: // * referer -pub fn headersForRequest(self: *Page, temp: Allocator, url: [:0]const u8, headers: *HttpClient.Headers) !void { - try self.requestCookie(.{}).headersForRequest(temp, url, headers); - +pub fn headersForRequest(self: *Page, headers: *HttpClient.Headers) !void { // Build the referer const referer = blk: { if (self.referer_header == null) { @@ -525,8 +522,6 @@ pub fn navigate(self: *Page, request_url: [:0]const u8, opts: NavigateOpts) !voi if (opts.header) |hdr| { try headers.add(hdr); } - try self.requestCookie(.{ .is_navigation = true }).headersForRequest(self.arena, self.url, &headers); - // We dispatch page_navigate event before sending the request. // It ensures the event page_navigated is not dispatched before this one. session.notification.dispatch(.page_navigate, &.{ @@ -3497,19 +3492,6 @@ pub fn insertText(self: *Page, v: []const u8) !void { } } -const RequestCookieOpts = struct { - is_http: bool = true, - is_navigation: bool = false, -}; -pub fn requestCookie(self: *const Page, opts: RequestCookieOpts) HttpClient.RequestCookie { - return .{ - .jar = &self._session.cookie_jar, - .origin = self.url, - .is_http = opts.is_http, - .is_navigation = opts.is_navigation, - }; -} - fn asUint(comptime string: anytype) std.meta.Int( .unsigned, @bitSizeOf(@TypeOf(string.*)) - 8, // (- 8) to exclude sentinel 0 diff --git a/src/browser/ScriptManager.zig b/src/browser/ScriptManager.zig index fc38acf0..001d4781 100644 --- a/src/browser/ScriptManager.zig +++ b/src/browser/ScriptManager.zig @@ -138,9 +138,9 @@ fn clearList(list: *std.DoublyLinkedList) void { } } -fn getHeaders(self: *ScriptManager, arena: Allocator, url: [:0]const u8) !net_http.Headers { +fn getHeaders(self: *ScriptManager) !net_http.Headers { var headers = try self.client.newHeaders(); - try self.page.headersForRequest(arena, url, &headers); + try self.page.headersForRequest(&headers); return headers; } @@ -280,7 +280,7 @@ pub fn addFromElement(self: *ScriptManager, comptime from_parser: bool, script_e .ctx = script, .method = .GET, .frame_id = page._frame_id, - .headers = try self.getHeaders(arena, url), + .headers = try self.getHeaders(), .blocking = is_blocking, .cookie_jar = &page._session.cookie_jar, .resource_type = .script, @@ -405,7 +405,7 @@ pub fn preloadImport(self: *ScriptManager, url: [:0]const u8, referrer: []const .ctx = script, .method = .GET, .frame_id = page._frame_id, - .headers = try self.getHeaders(arena, url), + .headers = try self.getHeaders(), .cookie_jar = &page._session.cookie_jar, .resource_type = .script, .notification = page._session.notification, @@ -508,7 +508,7 @@ pub fn getAsyncImport(self: *ScriptManager, url: [:0]const u8, cb: ImportAsync.C .url = url, .method = .GET, .frame_id = page._frame_id, - .headers = try self.getHeaders(arena, url), + .headers = try self.getHeaders(), .ctx = script, .resource_type = .script, .cookie_jar = &page._session.cookie_jar, diff --git a/src/browser/webapi/net/Fetch.zig b/src/browser/webapi/net/Fetch.zig index 7ab7b8ec..fc353b52 100644 --- a/src/browser/webapi/net/Fetch.zig +++ b/src/browser/webapi/net/Fetch.zig @@ -69,7 +69,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.headersForRequest(page.arena, request._url, &headers); + try page.headersForRequest(&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 399e4217..a5571303 100644 --- a/src/browser/webapi/net/XMLHttpRequest.zig +++ b/src/browser/webapi/net/XMLHttpRequest.zig @@ -225,7 +225,7 @@ pub fn send(self: *XMLHttpRequest, body_: ?[]const u8) !void { try self._request_headers.populateHttpHeader(page.call_arena, &headers); if (cookie_support) { - try page.headersForRequest(self._arena, self._url, &headers); + try page.headersForRequest(&headers); } try http_client.request(.{ diff --git a/src/cdp/domains/network.zig b/src/cdp/domains/network.zig index 5b9a49df..9e6da6c2 100644 --- a/src/cdp/domains/network.zig +++ b/src/cdp/domains/network.zig @@ -340,6 +340,19 @@ pub const TransferAsRequestWriter = struct { try jws.objectField(hdr.name); try jws.write(hdr.value); } + if (transfer.req.cookie_jar) |jar| { + var aw: std.Io.Writer.Allocating = .init(transfer.arena.allocator()); + try jar.forRequest(transfer.req.url, &aw.writer, .{ + .is_http = true, + .origin_url = transfer.req.url, + .is_navigation = transfer.req.resource_type == .document, + }); + const cookie_str = aw.written(); + if (cookie_str.len > 0) { + try jws.objectField("Cookie"); + try jws.write(cookie_str); + } + } try jws.endObject(); } try jws.endObject(); diff --git a/src/network/http.zig b/src/network/http.zig index d4338104..f77d0d66 100644 --- a/src/network/http.zig +++ b/src/network/http.zig @@ -64,14 +64,13 @@ pub const Header = struct { pub const Headers = struct { headers: ?*libcurl.CurlSList, - cookies: ?[*c]const u8, pub fn init(user_agent: [:0]const u8) !Headers { const header_list = libcurl.curl_slist_append(null, user_agent); if (header_list == null) { return error.OutOfMemory; } - return .{ .headers = header_list, .cookies = null }; + return .{ .headers = header_list }; } pub fn deinit(self: *const Headers) void { @@ -102,20 +101,14 @@ pub const Headers = struct { pub fn iterator(self: *Headers) Iterator { return .{ .header = self.headers, - .cookies = self.cookies, }; } const Iterator = struct { header: [*c]libcurl.CurlSList, - cookies: ?[*c]const u8, pub fn next(self: *Iterator) ?Header { - const h = self.header orelse { - const cookies = self.cookies orelse return null; - self.cookies = null; - return .{ .name = "Cookie", .value = std.mem.span(@as([*:0]const u8, cookies)) }; - }; + const h = self.header orelse return null; self.header = h.*.next; return parseHeader(std.mem.span(@as([*:0]const u8, @ptrCast(h.*.data)))); @@ -458,11 +451,6 @@ pub const Connection = struct { try self.secretHeaders(&header_list, http_headers); try self.setHeaders(&header_list); - // Add cookies. - if (header_list.cookies) |cookies| { - try self.setCookies(cookies); - } - try libcurl.curl_easy_perform(self._easy); return self.getResponseCode(); }