mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-21 20:24:42 +00:00
Fixup cookies management
This commit is contained in:
@@ -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 {
|
pub const Request = struct {
|
||||||
frame_id: u32,
|
frame_id: u32,
|
||||||
method: Method,
|
method: Method,
|
||||||
@@ -1075,9 +1054,20 @@ pub const Transfer = struct {
|
|||||||
try wba.signRequest(self.arena.allocator(), &header_list, authority);
|
try wba.signRequest(self.arena.allocator(), &header_list, authority);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add cookies.
|
// Add cookies from cookie jar.
|
||||||
if (header_list.cookies) |cookies| {
|
if (req.cookie_jar) |jar| {
|
||||||
try conn.setCookies(cookies);
|
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);
|
try conn.setPrivate(self);
|
||||||
@@ -1150,13 +1140,10 @@ pub const Transfer = struct {
|
|||||||
return error.TooManyRedirects;
|
return error.TooManyRedirects;
|
||||||
}
|
}
|
||||||
|
|
||||||
lp.log.warn(.bug, "Redirecting...", .{});
|
|
||||||
|
|
||||||
// retrieve cookies from the redirect's response.
|
// retrieve cookies from the redirect's response.
|
||||||
if (req.cookie_jar) |jar| {
|
if (req.cookie_jar) |jar| {
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
while (conn.getResponseHeader("set-cookie", i)) |ct| : (i += 1) {
|
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);
|
try jar.populateFromResponse(transfer.url, ct.value);
|
||||||
|
|
||||||
if (i >= ct.amount) {
|
if (i >= ct.amount) {
|
||||||
@@ -1181,23 +1168,6 @@ pub const Transfer = struct {
|
|||||||
req.method = .GET;
|
req.method = .GET;
|
||||||
req.body = null;
|
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 {
|
fn detectAuthChallenge(transfer: *Transfer, conn: *const http.Connection) void {
|
||||||
|
|||||||
@@ -371,12 +371,9 @@ pub fn getTitle(self: *Page) !?[]const u8 {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add comon headers for a request:
|
// Add common headers for a request:
|
||||||
// * cookies
|
|
||||||
// * referer
|
// * referer
|
||||||
pub fn headersForRequest(self: *Page, temp: Allocator, url: [:0]const u8, headers: *HttpClient.Headers) !void {
|
pub fn headersForRequest(self: *Page, headers: *HttpClient.Headers) !void {
|
||||||
try self.requestCookie(.{}).headersForRequest(temp, url, headers);
|
|
||||||
|
|
||||||
// Build the referer
|
// Build the referer
|
||||||
const referer = blk: {
|
const referer = blk: {
|
||||||
if (self.referer_header == null) {
|
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| {
|
if (opts.header) |hdr| {
|
||||||
try headers.add(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.
|
// We dispatch page_navigate event before sending the request.
|
||||||
// It ensures the event page_navigated is not dispatched before this one.
|
// It ensures the event page_navigated is not dispatched before this one.
|
||||||
session.notification.dispatch(.page_navigate, &.{
|
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(
|
fn asUint(comptime string: anytype) std.meta.Int(
|
||||||
.unsigned,
|
.unsigned,
|
||||||
@bitSizeOf(@TypeOf(string.*)) - 8, // (- 8) to exclude sentinel 0
|
@bitSizeOf(@TypeOf(string.*)) - 8, // (- 8) to exclude sentinel 0
|
||||||
|
|||||||
@@ -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();
|
var headers = try self.client.newHeaders();
|
||||||
try self.page.headersForRequest(arena, url, &headers);
|
try self.page.headersForRequest(&headers);
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +280,7 @@ pub fn addFromElement(self: *ScriptManager, comptime from_parser: bool, script_e
|
|||||||
.ctx = script,
|
.ctx = script,
|
||||||
.method = .GET,
|
.method = .GET,
|
||||||
.frame_id = page._frame_id,
|
.frame_id = page._frame_id,
|
||||||
.headers = try self.getHeaders(arena, url),
|
.headers = try self.getHeaders(),
|
||||||
.blocking = is_blocking,
|
.blocking = is_blocking,
|
||||||
.cookie_jar = &page._session.cookie_jar,
|
.cookie_jar = &page._session.cookie_jar,
|
||||||
.resource_type = .script,
|
.resource_type = .script,
|
||||||
@@ -405,7 +405,7 @@ pub fn preloadImport(self: *ScriptManager, url: [:0]const u8, referrer: []const
|
|||||||
.ctx = script,
|
.ctx = script,
|
||||||
.method = .GET,
|
.method = .GET,
|
||||||
.frame_id = page._frame_id,
|
.frame_id = page._frame_id,
|
||||||
.headers = try self.getHeaders(arena, url),
|
.headers = try self.getHeaders(),
|
||||||
.cookie_jar = &page._session.cookie_jar,
|
.cookie_jar = &page._session.cookie_jar,
|
||||||
.resource_type = .script,
|
.resource_type = .script,
|
||||||
.notification = page._session.notification,
|
.notification = page._session.notification,
|
||||||
@@ -508,7 +508,7 @@ pub fn getAsyncImport(self: *ScriptManager, url: [:0]const u8, cb: ImportAsync.C
|
|||||||
.url = url,
|
.url = url,
|
||||||
.method = .GET,
|
.method = .GET,
|
||||||
.frame_id = page._frame_id,
|
.frame_id = page._frame_id,
|
||||||
.headers = try self.getHeaders(arena, url),
|
.headers = try self.getHeaders(),
|
||||||
.ctx = script,
|
.ctx = script,
|
||||||
.resource_type = .script,
|
.resource_type = .script,
|
||||||
.cookie_jar = &page._session.cookie_jar,
|
.cookie_jar = &page._session.cookie_jar,
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ pub fn init(input: Input, options: ?InitOpts, page: *Page) !js.Promise {
|
|||||||
if (request._headers) |h| {
|
if (request._headers) |h| {
|
||||||
try h.populateHttpHeader(page.call_arena, &headers);
|
try h.populateHttpHeader(page.call_arena, &headers);
|
||||||
}
|
}
|
||||||
try page.headersForRequest(page.arena, request._url, &headers);
|
try page.headersForRequest(&headers);
|
||||||
|
|
||||||
if (comptime IS_DEBUG) {
|
if (comptime IS_DEBUG) {
|
||||||
log.debug(.http, "fetch", .{ .url = request._url });
|
log.debug(.http, "fetch", .{ .url = request._url });
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ pub fn send(self: *XMLHttpRequest, body_: ?[]const u8) !void {
|
|||||||
|
|
||||||
try self._request_headers.populateHttpHeader(page.call_arena, &headers);
|
try self._request_headers.populateHttpHeader(page.call_arena, &headers);
|
||||||
if (cookie_support) {
|
if (cookie_support) {
|
||||||
try page.headersForRequest(self._arena, self._url, &headers);
|
try page.headersForRequest(&headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
try http_client.request(.{
|
try http_client.request(.{
|
||||||
|
|||||||
@@ -340,6 +340,19 @@ pub const TransferAsRequestWriter = struct {
|
|||||||
try jws.objectField(hdr.name);
|
try jws.objectField(hdr.name);
|
||||||
try jws.write(hdr.value);
|
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();
|
||||||
}
|
}
|
||||||
try jws.endObject();
|
try jws.endObject();
|
||||||
|
|||||||
@@ -64,14 +64,13 @@ pub const Header = struct {
|
|||||||
|
|
||||||
pub const Headers = struct {
|
pub const Headers = struct {
|
||||||
headers: ?*libcurl.CurlSList,
|
headers: ?*libcurl.CurlSList,
|
||||||
cookies: ?[*c]const u8,
|
|
||||||
|
|
||||||
pub fn init(user_agent: [:0]const u8) !Headers {
|
pub fn init(user_agent: [:0]const u8) !Headers {
|
||||||
const header_list = libcurl.curl_slist_append(null, user_agent);
|
const header_list = libcurl.curl_slist_append(null, user_agent);
|
||||||
if (header_list == null) {
|
if (header_list == null) {
|
||||||
return error.OutOfMemory;
|
return error.OutOfMemory;
|
||||||
}
|
}
|
||||||
return .{ .headers = header_list, .cookies = null };
|
return .{ .headers = header_list };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *const Headers) void {
|
pub fn deinit(self: *const Headers) void {
|
||||||
@@ -102,20 +101,14 @@ pub const Headers = struct {
|
|||||||
pub fn iterator(self: *Headers) Iterator {
|
pub fn iterator(self: *Headers) Iterator {
|
||||||
return .{
|
return .{
|
||||||
.header = self.headers,
|
.header = self.headers,
|
||||||
.cookies = self.cookies,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const Iterator = struct {
|
const Iterator = struct {
|
||||||
header: [*c]libcurl.CurlSList,
|
header: [*c]libcurl.CurlSList,
|
||||||
cookies: ?[*c]const u8,
|
|
||||||
|
|
||||||
pub fn next(self: *Iterator) ?Header {
|
pub fn next(self: *Iterator) ?Header {
|
||||||
const h = self.header orelse {
|
const h = self.header orelse return null;
|
||||||
const cookies = self.cookies orelse return null;
|
|
||||||
self.cookies = null;
|
|
||||||
return .{ .name = "Cookie", .value = std.mem.span(@as([*:0]const u8, cookies)) };
|
|
||||||
};
|
|
||||||
|
|
||||||
self.header = h.*.next;
|
self.header = h.*.next;
|
||||||
return parseHeader(std.mem.span(@as([*:0]const u8, @ptrCast(h.*.data))));
|
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.secretHeaders(&header_list, http_headers);
|
||||||
try self.setHeaders(&header_list);
|
try self.setHeaders(&header_list);
|
||||||
|
|
||||||
// Add cookies.
|
|
||||||
if (header_list.cookies) |cookies| {
|
|
||||||
try self.setCookies(cookies);
|
|
||||||
}
|
|
||||||
|
|
||||||
try libcurl.curl_easy_perform(self._easy);
|
try libcurl.curl_easy_perform(self._easy);
|
||||||
return self.getResponseCode();
|
return self.getResponseCode();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user