mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-16 00:08:59 +00:00
Remove std.Uri from cookies
Everything now works on a [:0]const u8, with browser/URL.zig for parsing
This commit is contained in:
@@ -51,7 +51,7 @@ arena: Allocator,
|
||||
transfer_arena: Allocator,
|
||||
|
||||
executor: js.ExecutionWorld,
|
||||
cookie_jar: storage.Jar,
|
||||
cookie_jar: storage.Cookie.Jar,
|
||||
storage_shed: storage.Shed,
|
||||
|
||||
page: ?*Page = null,
|
||||
@@ -73,7 +73,7 @@ pub fn init(self: *Session, browser: *Browser) !void {
|
||||
.storage_shed = .{},
|
||||
.queued_navigation = null,
|
||||
.arena = browser.session_arena.allocator(),
|
||||
.cookie_jar = storage.Jar.init(allocator),
|
||||
.cookie_jar = storage.Cookie.Jar.init(allocator),
|
||||
.transfer_arena = browser.transfer_arena.allocator(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -171,6 +171,10 @@ pub fn getProtocol(raw: [:0]const u8) []const u8 {
|
||||
return raw[0 .. pos + 1];
|
||||
}
|
||||
|
||||
pub fn isHTTPS(raw: [:0]const u8) bool {
|
||||
return std.mem.startsWith(u8, raw, "https:");
|
||||
}
|
||||
|
||||
pub fn getHostname(raw: [:0]const u8) []const u8 {
|
||||
const host = getHost(raw);
|
||||
const pos = std.mem.lastIndexOfScalar(u8, host, ':') orelse return host;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,8 +26,7 @@ pub fn registerTypes() []const type {
|
||||
return &.{Lookup};
|
||||
}
|
||||
|
||||
pub const Jar = @import("cookie.zig").Jar;
|
||||
pub const Cookie = @import("cookie.zig").Cookie;
|
||||
pub const Cookie = @import("Cookie.zig");
|
||||
|
||||
pub const Shed = struct {
|
||||
_origins: std.StringHashMapUnmanaged(*Bucket) = .empty,
|
||||
|
||||
@@ -208,7 +208,7 @@ pub fn requestIntercept(arena: Allocator, bc: anytype, intercept: *const Notific
|
||||
log.debug(.cdp, "request intercept", .{
|
||||
.state = "paused",
|
||||
.id = transfer.id,
|
||||
.url = transfer.uri,
|
||||
.url = transfer.url,
|
||||
});
|
||||
// Await either continueRequest, failRequest or fulfillRequest
|
||||
|
||||
@@ -237,7 +237,7 @@ fn continueRequest(cmd: anytype) !void {
|
||||
log.debug(.cdp, "request intercept", .{
|
||||
.state = "continue",
|
||||
.id = transfer.id,
|
||||
.url = transfer.uri,
|
||||
.url = transfer.url,
|
||||
.new_url = params.url,
|
||||
});
|
||||
|
||||
@@ -342,7 +342,7 @@ fn fulfillRequest(cmd: anytype) !void {
|
||||
log.debug(.cdp, "request intercept", .{
|
||||
.state = "fulfilled",
|
||||
.id = transfer.id,
|
||||
.url = transfer.uri,
|
||||
.url = transfer.url,
|
||||
.status = params.responseCode,
|
||||
.body = params.body != null,
|
||||
});
|
||||
@@ -376,7 +376,7 @@ fn failRequest(cmd: anytype) !void {
|
||||
log.info(.cdp, "request intercept", .{
|
||||
.state = "fail",
|
||||
.id = request_id,
|
||||
.url = transfer.uri,
|
||||
.url = transfer.url,
|
||||
.reason = params.errorReason,
|
||||
});
|
||||
return cmd.sendResult(null, .{});
|
||||
@@ -420,7 +420,7 @@ pub fn requestAuthRequired(arena: Allocator, bc: anytype, intercept: *const Noti
|
||||
log.debug(.cdp, "request auth required", .{
|
||||
.state = "paused",
|
||||
.id = transfer.id,
|
||||
.url = transfer.uri,
|
||||
.url = transfer.url,
|
||||
});
|
||||
// Await continueWithAuth
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const CdpStorage = @import("storage.zig");
|
||||
const URL = @import("../../browser/URL.zig");
|
||||
const Transfer = @import("../../http/Client.zig").Transfer;
|
||||
const Notification = @import("../../Notification.zig");
|
||||
|
||||
@@ -107,7 +108,7 @@ fn cookieMatches(cookie: *const Cookie, name: []const u8, domain: ?[]const u8, p
|
||||
fn deleteCookies(cmd: anytype) !void {
|
||||
const params = (try cmd.params(struct {
|
||||
name: []const u8,
|
||||
url: ?[]const u8 = null,
|
||||
url: ?[:0]const u8 = null,
|
||||
domain: ?[]const u8 = null,
|
||||
path: ?[]const u8 = null,
|
||||
partitionKey: ?CdpStorage.CookiePartitionKey = null,
|
||||
@@ -117,15 +118,12 @@ fn deleteCookies(cmd: anytype) !void {
|
||||
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
|
||||
const cookies = &bc.session.cookie_jar.cookies;
|
||||
|
||||
const uri = if (params.url) |url| std.Uri.parse(url) catch return error.InvalidParams else null;
|
||||
const uri_ptr = if (uri) |u| &u else null;
|
||||
|
||||
var index = cookies.items.len;
|
||||
while (index > 0) {
|
||||
index -= 1;
|
||||
const cookie = &cookies.items[index];
|
||||
const domain = try Cookie.parseDomain(cmd.arena, uri_ptr, params.domain);
|
||||
const path = try Cookie.parsePath(cmd.arena, uri_ptr, params.path);
|
||||
const domain = try Cookie.parseDomain(cmd.arena, params.url, params.domain);
|
||||
const path = try Cookie.parsePath(cmd.arena, params.url, params.path);
|
||||
|
||||
// We do not want to use Cookie.appliesTo here. As a Cookie with a shorter path would match.
|
||||
// Similar to deduplicating with areCookiesEqual, except domain and path are optional.
|
||||
@@ -167,23 +165,23 @@ fn setCookies(cmd: anytype) !void {
|
||||
try cmd.sendResult(null, .{});
|
||||
}
|
||||
|
||||
const GetCookiesParam = struct { urls: ?[]const []const u8 = null };
|
||||
const GetCookiesParam = struct {
|
||||
urls: ?[]const [:0]const u8 = null,
|
||||
};
|
||||
fn getCookies(cmd: anytype) !void {
|
||||
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
|
||||
const params = (try cmd.params(GetCookiesParam)) orelse GetCookiesParam{};
|
||||
|
||||
// If not specified, use the URLs of the page and all of its subframes. TODO subframes
|
||||
const page_url = if (bc.session.page) |page| page.url else null;
|
||||
const param_urls = params.urls orelse &[_][]const u8{page_url orelse return error.InvalidParams};
|
||||
const param_urls = params.urls orelse &[_][:0]const u8{page_url orelse return error.InvalidParams};
|
||||
|
||||
var urls = try std.ArrayListUnmanaged(CdpStorage.PreparedUri).initCapacity(cmd.arena, param_urls.len);
|
||||
for (param_urls) |url| {
|
||||
const uri = std.Uri.parse(url) catch return error.InvalidParams;
|
||||
|
||||
urls.appendAssumeCapacity(.{
|
||||
.host = try Cookie.parseDomain(cmd.arena, &uri, null),
|
||||
.path = try Cookie.parsePath(cmd.arena, &uri, null),
|
||||
.secure = std.mem.eql(u8, uri.scheme, "https"),
|
||||
.host = try Cookie.parseDomain(cmd.arena, url, null),
|
||||
.path = try Cookie.parsePath(cmd.arena, url, null),
|
||||
.secure = URL.isHTTPS(url),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -300,23 +298,19 @@ pub const TransferAsRequestWriter = struct {
|
||||
try jws.objectField("url");
|
||||
try jws.beginWriteRaw();
|
||||
try writer.writeByte('\"');
|
||||
try transfer.uri.writeToStream(writer, .{
|
||||
.scheme = true,
|
||||
.authentication = true,
|
||||
.authority = true,
|
||||
.path = true,
|
||||
.query = true,
|
||||
});
|
||||
// #ZIGDOM shouldn't include the hash?
|
||||
try writer.writeAll(transfer.url);
|
||||
try writer.writeByte('\"');
|
||||
jws.endWriteRaw();
|
||||
}
|
||||
|
||||
{
|
||||
if (transfer.uri.fragment) |frag| {
|
||||
const frag = URL.getHash(transfer.url);
|
||||
if (frag.len > 0) {
|
||||
try jws.objectField("urlFragment");
|
||||
try jws.beginWriteRaw();
|
||||
try writer.writeAll("\"#");
|
||||
try writer.writeAll(frag.percent_encoded);
|
||||
try writer.writeAll(frag);
|
||||
try writer.writeByte('\"');
|
||||
jws.endWriteRaw();
|
||||
}
|
||||
@@ -370,13 +364,8 @@ const TransferAsResponseWriter = struct {
|
||||
try jws.objectField("url");
|
||||
try jws.beginWriteRaw();
|
||||
try writer.writeByte('\"');
|
||||
try transfer.uri.writeToStream(writer, .{
|
||||
.scheme = true,
|
||||
.authentication = true,
|
||||
.authority = true,
|
||||
.path = true,
|
||||
.query = true,
|
||||
});
|
||||
// #ZIGDOM shouldn't include the hash?
|
||||
try writer.writeAll(transfer.url);
|
||||
try writer.writeByte('\"');
|
||||
jws.endWriteRaw();
|
||||
}
|
||||
|
||||
@@ -19,9 +19,10 @@
|
||||
const std = @import("std");
|
||||
|
||||
const log = @import("../../log.zig");
|
||||
const URL = @import("../../browser/URL.zig");
|
||||
const Cookie = @import("../../browser/webapi/storage/storage.zig").Cookie;
|
||||
const CookieJar = @import("../../browser/webapi/storage/storage.zig").Jar;
|
||||
pub const PreparedUri = @import("../../browser/webapi/storage/cookie.zig").PreparedUri;
|
||||
const CookieJar = Cookie.Jar;
|
||||
pub const PreparedUri = Cookie.PreparedUri;
|
||||
|
||||
pub fn processMessage(cmd: anytype) !void {
|
||||
const action = std.meta.stringToEnum(enum {
|
||||
@@ -112,9 +113,9 @@ pub const CookiePartitionKey = struct {
|
||||
pub const CdpCookie = struct {
|
||||
name: []const u8,
|
||||
value: []const u8,
|
||||
url: ?[]const u8 = null,
|
||||
url: ?[:0]const u8 = null,
|
||||
domain: ?[]const u8 = null,
|
||||
path: ?[]const u8 = null,
|
||||
path: ?[:0]const u8 = null,
|
||||
secure: ?bool = null, // default: https://www.rfc-editor.org/rfc/rfc6265#section-5.3
|
||||
httpOnly: bool = false, // default: https://www.rfc-editor.org/rfc/rfc6265#section-5.3
|
||||
sameSite: SameSite = .None, // default: https://datatracker.ietf.org/doc/html/draft-west-first-party-cookies
|
||||
@@ -136,12 +137,10 @@ pub fn setCdpCookie(cookie_jar: *CookieJar, param: CdpCookie) !void {
|
||||
const a = arena.allocator();
|
||||
|
||||
// NOTE: The param.url can affect the default domain, (NOT path), secure, source port, and source scheme.
|
||||
const uri = if (param.url) |url| std.Uri.parse(url) catch return error.InvalidParams else null;
|
||||
const uri_ptr = if (uri) |*u| u else null;
|
||||
const domain = try Cookie.parseDomain(a, uri_ptr, param.domain);
|
||||
const domain = try Cookie.parseDomain(a, param.url, param.domain);
|
||||
const path = if (param.path == null) "/" else try Cookie.parsePath(a, null, param.path);
|
||||
|
||||
const secure = if (param.secure) |s| s else if (uri) |uri_| std.mem.eql(u8, uri_.scheme, "https") else false;
|
||||
const secure = if (param.secure) |s| s else if (param.url) |url| URL.isHTTPS(url) else false;
|
||||
|
||||
const cookie = Cookie{
|
||||
.arena = arena,
|
||||
|
||||
@@ -23,7 +23,7 @@ const builtin = @import("builtin");
|
||||
const Http = @import("Http.zig");
|
||||
const URL = @import("../browser/URL.zig");
|
||||
const Notification = @import("../Notification.zig");
|
||||
const CookieJar = @import("../browser/webapi/storage/cookie.zig").Jar;
|
||||
const CookieJar = @import("../browser/webapi/storage/Cookie.zig").Jar;
|
||||
|
||||
const c = Http.c;
|
||||
const posix = std.posix;
|
||||
@@ -257,12 +257,6 @@ pub fn fulfillTransfer(self: *Client, transfer: *Transfer, status: u16, headers:
|
||||
fn makeTransfer(self: *Client, req: Request) !*Transfer {
|
||||
errdefer req.headers.deinit();
|
||||
|
||||
// we need this for cookies
|
||||
const uri = std.Uri.parse(req.url) catch |err| {
|
||||
log.warn(.http, "invalid url", .{ .err = err, .url = req.url });
|
||||
return err;
|
||||
};
|
||||
|
||||
const transfer = try self.transfer_pool.create();
|
||||
errdefer self.transfer_pool.destroy(transfer);
|
||||
|
||||
@@ -271,7 +265,7 @@ fn makeTransfer(self: *Client, req: Request) !*Transfer {
|
||||
transfer.* = .{
|
||||
.arena = ArenaAllocator.init(self.allocator),
|
||||
.id = id,
|
||||
.uri = uri,
|
||||
.url = req.url,
|
||||
.req = req,
|
||||
.ctx = req.ctx,
|
||||
.client = self,
|
||||
@@ -593,26 +587,16 @@ pub const Handle = struct {
|
||||
|
||||
pub const RequestCookie = struct {
|
||||
is_http: bool,
|
||||
jar: *CookieJar,
|
||||
is_navigation: bool,
|
||||
origin: [:0]const u8,
|
||||
jar: *@import("../browser/webapi/storage/cookie.zig").Jar,
|
||||
|
||||
pub fn headersForRequest(self: *const RequestCookie, temp: Allocator, url: [:0]const u8, headers: *Http.Headers) !void {
|
||||
const uri = std.Uri.parse(url) catch |err| {
|
||||
log.warn(.http, "invalid url", .{ .err = err, .url = url });
|
||||
return error.InvalidUrl;
|
||||
};
|
||||
|
||||
const origin_uri = std.Uri.parse(self.origin) catch |err| {
|
||||
log.warn(.http, "invalid url", .{ .err = err, .url = self.origin });
|
||||
return error.InvalidUrl;
|
||||
};
|
||||
|
||||
var arr: std.ArrayListUnmanaged(u8) = .{};
|
||||
try self.jar.forRequest(&uri, arr.writer(temp), .{
|
||||
try self.jar.forRequest(url, arr.writer(temp), .{
|
||||
.is_http = self.is_http,
|
||||
.is_navigation = self.is_navigation,
|
||||
.origin_uri = &origin_uri,
|
||||
.origin_url = self.origin,
|
||||
});
|
||||
|
||||
if (arr.items.len > 0) {
|
||||
@@ -692,7 +676,7 @@ pub const Transfer = struct {
|
||||
arena: ArenaAllocator,
|
||||
id: usize = 0,
|
||||
req: Request,
|
||||
uri: std.Uri, // used for setting/getting the cookie
|
||||
url: [:0]const u8,
|
||||
ctx: *anyopaque, // copied from req.ctx to make it easier for callback handlers
|
||||
client: *Client,
|
||||
// total bytes received in the response, including the response status line,
|
||||
@@ -778,7 +762,7 @@ pub const Transfer = struct {
|
||||
|
||||
pub fn updateURL(self: *Transfer, url: [:0]const u8) !void {
|
||||
// for cookies
|
||||
self.uri = try std.Uri.parse(url);
|
||||
self.url = url;
|
||||
|
||||
// for the request itself
|
||||
self.req.url = url;
|
||||
@@ -846,7 +830,7 @@ pub const Transfer = struct {
|
||||
while (true) {
|
||||
const ct = getResponseHeader(easy, "set-cookie", i);
|
||||
if (ct == null) break;
|
||||
try req.cookie_jar.populateFromResponse(&transfer.uri, ct.?.value);
|
||||
try req.cookie_jar.populateFromResponse(transfer.url, ct.?.value);
|
||||
i += 1;
|
||||
if (i >= ct.?.amount) break;
|
||||
}
|
||||
@@ -860,13 +844,12 @@ pub const Transfer = struct {
|
||||
try errorCheck(c.curl_easy_getinfo(easy, c.CURLINFO_EFFECTIVE_URL, &base_url));
|
||||
|
||||
const url = try URL.resolve(arena, std.mem.span(base_url), location.value, .{});
|
||||
const uri = try std.Uri.parse(url);
|
||||
transfer.uri = uri;
|
||||
transfer.url = url;
|
||||
|
||||
var cookies: std.ArrayListUnmanaged(u8) = .{};
|
||||
try req.cookie_jar.forRequest(&uri, cookies.writer(arena), .{
|
||||
try req.cookie_jar.forRequest(url, cookies.writer(arena), .{
|
||||
.is_http = true,
|
||||
.origin_uri = &transfer.uri,
|
||||
.origin_url = url,
|
||||
// used to enforce samesite cookie rules
|
||||
.is_navigation = req.resource_type == .document,
|
||||
});
|
||||
@@ -895,7 +878,7 @@ pub const Transfer = struct {
|
||||
while (true) {
|
||||
const ct = getResponseHeader(easy, "set-cookie", i);
|
||||
if (ct == null) break;
|
||||
transfer.req.cookie_jar.populateFromResponse(&transfer.uri, ct.?.value) catch |err| {
|
||||
transfer.req.cookie_jar.populateFromResponse(transfer.url, ct.?.value) catch |err| {
|
||||
log.err(.http, "set cookie", .{ .err = err, .req = transfer });
|
||||
return err;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user