Skip to content

Commit b307473

Browse files
committed
prefer URL instead of std.Uri everywhere
1 parent 8d0958c commit b307473

File tree

9 files changed

+354
-256
lines changed

9 files changed

+354
-256
lines changed

src/browser/html/document.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ pub const HTMLDocument = struct {
8585

8686
pub fn get_cookie(_: *parser.DocumentHTML, page: *Page) ![]const u8 {
8787
var buf: std.ArrayListUnmanaged(u8) = .{};
88-
try page.cookie_jar.forRequest(&page.url.uri, buf.writer(page.arena), .{
88+
try page.cookie_jar.forRequest(page.url, buf.writer(page.arena), .{
8989
.is_http = false,
9090
.is_navigation = true,
9191
});
@@ -95,7 +95,7 @@ pub const HTMLDocument = struct {
9595
pub fn set_cookie(_: *parser.DocumentHTML, cookie_str: []const u8, page: *Page) ![]const u8 {
9696
// we use the cookie jar's allocator to parse the cookie because it
9797
// outlives the page's arena.
98-
const c = try Cookie.parse(page.cookie_jar.allocator, &page.url.uri, cookie_str);
98+
const c = try Cookie.parse(page.cookie_jar.allocator, page.url, cookie_str);
9999
errdefer c.deinit();
100100
if (c.http_only) {
101101
c.deinit();

src/browser/page.zig

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ pub const Page = struct {
153153
}
154154
}
155155

156+
// FIXME: Deinit self.url.
156157
pub fn deinit(self: *Page) void {
157158
self.script_manager.shutdown = true;
158159

@@ -229,7 +230,7 @@ pub const Page = struct {
229230

230231
const doc = parser.documentHTMLToDocument(self.window.document);
231232

232-
// if the base si requested, add the base's node in the document's headers.
233+
// if the base is requested, add the base's node in the document's headers.
233234
if (opts.with_base) {
234235
try self.addDOMTreeBase();
235236
}
@@ -515,10 +516,11 @@ pub const Page = struct {
515516
is_http: bool = true,
516517
is_navigation: bool = false,
517518
};
519+
518520
pub fn requestCookie(self: *const Page, opts: RequestCookieOpts) Http.Client.RequestCookie {
519521
return .{
520-
.jar = self.cookie_jar,
521-
.origin = &self.url.uri,
522+
.cookie_jar = self.cookie_jar,
523+
.origin_url = self.url,
522524
.is_http = opts.is_http,
523525
.is_navigation = opts.is_navigation,
524526
};
@@ -849,7 +851,7 @@ pub const Page = struct {
849851
self.window.setStorageShelf(
850852
try self.session.storage_shed.getOrPut(try self.origin(self.arena)),
851853
);
852-
try self.window.replaceLocation(.{ .url = try self.url.toWebApi(self.arena) });
854+
//try self.window.replaceLocation(.{ .url = try self.url.toWebApi(self.arena) });
853855
}
854856

855857
pub const MouseEvent = struct {

src/browser/storage/cookie.zig

Lines changed: 123 additions & 120 deletions
Large diffs are not rendered by default.

src/browser/url/url.zig

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,27 +84,45 @@ pub const URL = struct {
8484
break :blk ada.parse(url_str);
8585
};
8686

87-
// Prepare search_params.
88-
const params: URLSearchParams = blk: {
89-
const search = ada.getSearch(internal);
90-
if (search.data == null) {
91-
break :blk .{};
92-
}
93-
94-
break :blk try .initFromString(page.arena, search.data[0..search.length]);
87+
return .{
88+
.internal = internal,
89+
.search_params = try prepareSearchParams(page.arena, internal),
9590
};
96-
97-
// We're doing this since we track search params separately.
98-
ada.clearSearch(internal);
99-
100-
return .{ .internal = internal, .search_params = params };
10191
}
10292

10393
pub fn destructor(self: *const URL) void {
10494
// Not tracked by arena.
10595
return ada.free(self.internal);
10696
}
10797

98+
/// Initializes a `URL` from given `internal`.
99+
/// Note that this copies the given `internal`; meaning 2 instances
100+
/// of it has to be tracked separately.
101+
pub fn constructFromInternal(arena: Allocator, internal: ada.URL) !URL {
102+
const copy = ada.copy(internal);
103+
104+
return .{
105+
.internal = copy,
106+
.search_params = try prepareSearchParams(arena, copy),
107+
};
108+
}
109+
110+
/// Prepares a `URLSearchParams` from given `internal`.
111+
/// Resets `search` of `internal`.
112+
fn prepareSearchParams(arena: Allocator, internal: ada.URL) !URLSearchParams {
113+
const search = ada.getSearch(internal);
114+
// Empty.
115+
if (search.data == null) return .{};
116+
117+
const slice = search.data[0..search.length];
118+
const search_params = URLSearchParams.initFromString(arena, slice);
119+
// After a call to this function, search params are tracked by
120+
// `search_params`. So we reset the internal's search.
121+
ada.clearSearch(internal);
122+
123+
return search_params;
124+
}
125+
108126
// Alias to get_href.
109127
pub fn _toString(self: *const URL, page: *Page) ![]const u8 {
110128
return self.get_href(page);
@@ -176,7 +194,13 @@ pub const URL = struct {
176194
}
177195

178196
pub fn get_pathname(self: *const URL) []const u8 {
179-
return ada.getPathname(self.internal);
197+
const path = ada.getPathnameNullable(self.internal);
198+
// Return a slash if path is null.
199+
if (path.data == null) {
200+
return "/";
201+
}
202+
203+
return path.data[0..path.length];
180204
}
181205

182206
// get_search depends on the current state of `search_params`.

src/cdp/domains/fetch.zig

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ pub fn requestIntercept(arena: Allocator, bc: anytype, intercept: *const Notific
208208
log.debug(.cdp, "request intercept", .{
209209
.state = "paused",
210210
.id = transfer.id,
211-
.url = transfer.uri,
211+
.url = transfer.url,
212212
});
213213
// Await either continueRequest, failRequest or fulfillRequest
214214

@@ -237,7 +237,7 @@ fn continueRequest(cmd: anytype) !void {
237237
log.debug(.cdp, "request intercept", .{
238238
.state = "continue",
239239
.id = transfer.id,
240-
.url = transfer.uri,
240+
.url = transfer.url,
241241
.new_url = params.url,
242242
});
243243

@@ -342,7 +342,7 @@ fn fulfillRequest(cmd: anytype) !void {
342342
log.debug(.cdp, "request intercept", .{
343343
.state = "fulfilled",
344344
.id = transfer.id,
345-
.url = transfer.uri,
345+
.url = transfer.url,
346346
.status = params.responseCode,
347347
.body = params.body != null,
348348
});
@@ -376,7 +376,7 @@ fn failRequest(cmd: anytype) !void {
376376
log.info(.cdp, "request intercept", .{
377377
.state = "fail",
378378
.id = request_id,
379-
.url = transfer.uri,
379+
.url = transfer.url,
380380
.reason = params.errorReason,
381381
});
382382
return cmd.sendResult(null, .{});
@@ -420,7 +420,7 @@ pub fn requestAuthRequired(arena: Allocator, bc: anytype, intercept: *const Noti
420420
log.debug(.cdp, "request auth required", .{
421421
.state = "paused",
422422
.id = transfer.id,
423-
.url = transfer.uri,
423+
.url = transfer.url,
424424
});
425425
// Await continueWithAuth
426426

src/cdp/domains/network.zig

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const Allocator = std.mem.Allocator;
2222
const CdpStorage = @import("storage.zig");
2323
const Transfer = @import("../../http/Client.zig").Transfer;
2424
const Notification = @import("../../notification.zig").Notification;
25+
const URL = @import("../../url.zig").URL;
2526

2627
pub fn processMessage(cmd: anytype) !void {
2728
const action = std.meta.stringToEnum(enum {
@@ -117,22 +118,33 @@ fn deleteCookies(cmd: anytype) !void {
117118
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
118119
const cookies = &bc.session.cookie_jar.cookies;
119120

120-
const uri = if (params.url) |url| std.Uri.parse(url) catch return error.InvalidParams else null;
121-
const uri_ptr = if (uri) |u| &u else null;
121+
const maybe_url: ?URL = blk: {
122+
if (params.url) |url| {
123+
break :blk URL.parse(url, null) catch return error.InvalidParams;
124+
}
125+
126+
break :blk null;
127+
};
122128

123129
var index = cookies.items.len;
124130
while (index > 0) {
125131
index -= 1;
126132
const cookie = &cookies.items[index];
127-
const domain = try Cookie.parseDomain(cmd.arena, uri_ptr, params.domain);
128-
const path = try Cookie.parsePath(cmd.arena, uri_ptr, params.path);
133+
const domain = try Cookie.parseDomain(cmd.arena, maybe_url, params.domain);
134+
const path = try Cookie.parsePath(cmd.arena, maybe_url, params.path);
129135

130136
// We do not want to use Cookie.appliesTo here. As a Cookie with a shorter path would match.
131137
// Similar to deduplicating with areCookiesEqual, except domain and path are optional.
132138
if (cookieMatches(cookie, params.name, domain, path)) {
133139
cookies.swapRemove(index).deinit();
134140
}
135141
}
142+
143+
// Deinit URL if we had.
144+
if (maybe_url) |url| {
145+
url.deinit();
146+
}
147+
136148
return cmd.sendResult(null, .{});
137149
}
138150

@@ -177,13 +189,14 @@ fn getCookies(cmd: anytype) !void {
177189
const param_urls = params.urls orelse &[_][]const u8{page_url orelse return error.InvalidParams};
178190

179191
var urls = try std.ArrayListUnmanaged(CdpStorage.PreparedUri).initCapacity(cmd.arena, param_urls.len);
180-
for (param_urls) |url| {
181-
const uri = std.Uri.parse(url) catch return error.InvalidParams;
192+
for (param_urls) |url_str| {
193+
const url = URL.parse(url_str, null) catch return error.InvalidParams;
194+
defer url.deinit();
182195

183196
urls.appendAssumeCapacity(.{
184-
.host = try Cookie.parseDomain(cmd.arena, &uri, null),
185-
.path = try Cookie.parsePath(cmd.arena, &uri, null),
186-
.secure = std.mem.eql(u8, uri.scheme, "https"),
197+
.host = try Cookie.parseDomain(cmd.arena, url, null),
198+
.path = try Cookie.parsePath(cmd.arena, url, null),
199+
.secure = url.isSecure(),
187200
});
188201
}
189202

@@ -247,7 +260,7 @@ pub fn httpRequestStart(arena: Allocator, bc: anytype, msg: *const Notification.
247260
.requestId = try std.fmt.allocPrint(arena, "REQ-{d}", .{transfer.id}),
248261
.frameId = target_id,
249262
.loaderId = bc.loader_id,
250-
.documentUrl = DocumentUrlWriter.init(&page.url.uri),
263+
.documentUrl = DocumentUrlWriter.init(page.url),
251264
.request = TransferAsRequestWriter.init(transfer),
252265
.initiator = .{ .type = "other" },
253266
}, .{ .session_id = session_id });
@@ -300,23 +313,17 @@ pub const TransferAsRequestWriter = struct {
300313
try jws.objectField("url");
301314
try jws.beginWriteRaw();
302315
try writer.writeByte('\"');
303-
try transfer.uri.writeToStream(writer, .{
304-
.scheme = true,
305-
.authentication = true,
306-
.authority = true,
307-
.path = true,
308-
.query = true,
309-
});
316+
try transfer.url.writeToStream(writer);
310317
try writer.writeByte('\"');
311318
jws.endWriteRaw();
312319
}
313320

314321
{
315-
if (transfer.uri.fragment) |frag| {
322+
if (transfer.url.getFragment()) |frag| {
316323
try jws.objectField("urlFragment");
317324
try jws.beginWriteRaw();
318325
try writer.writeAll("\"#");
319-
try writer.writeAll(frag.percent_encoded);
326+
try writer.writeAll(frag);
320327
try writer.writeByte('\"');
321328
jws.endWriteRaw();
322329
}
@@ -370,13 +377,7 @@ const TransferAsResponseWriter = struct {
370377
try jws.objectField("url");
371378
try jws.beginWriteRaw();
372379
try writer.writeByte('\"');
373-
try transfer.uri.writeToStream(writer, .{
374-
.scheme = true,
375-
.authentication = true,
376-
.authority = true,
377-
.path = true,
378-
.query = true,
379-
});
380+
try transfer.url.writeToStream(writer);
380381
try writer.writeByte('\"');
381382
jws.endWriteRaw();
382383
}
@@ -417,29 +418,22 @@ const TransferAsResponseWriter = struct {
417418
};
418419

419420
const DocumentUrlWriter = struct {
420-
uri: *std.Uri,
421+
url: URL,
421422

422-
fn init(uri: *std.Uri) DocumentUrlWriter {
423-
return .{
424-
.uri = uri,
425-
};
423+
fn init(url: URL) DocumentUrlWriter {
424+
return .{ .url = url };
426425
}
427426

428427
pub fn jsonStringify(self: *const DocumentUrlWriter, jws: anytype) !void {
429428
self._jsonStringify(jws) catch return error.WriteFailed;
430429
}
430+
431431
fn _jsonStringify(self: *const DocumentUrlWriter, jws: anytype) !void {
432432
const writer = jws.writer;
433433

434434
try jws.beginWriteRaw();
435435
try writer.writeByte('\"');
436-
try self.uri.writeToStream(writer, .{
437-
.scheme = true,
438-
.authentication = true,
439-
.authority = true,
440-
.path = true,
441-
.query = true,
442-
});
436+
try self.url.writeToStream(writer);
443437
try writer.writeByte('\"');
444438
jws.endWriteRaw();
445439
}

src/cdp/domains/storage.zig

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const std = @import("std");
2121
const log = @import("../../log.zig");
2222
const Cookie = @import("../../browser/storage/storage.zig").Cookie;
2323
const CookieJar = @import("../../browser/storage/storage.zig").CookieJar;
24+
const URL = @import("../../url.zig").URL;
2425
pub const PreparedUri = @import("../../browser/storage/cookie.zig").PreparedUri;
2526

2627
pub fn processMessage(cmd: anytype) !void {
@@ -136,12 +137,25 @@ pub fn setCdpCookie(cookie_jar: *CookieJar, param: CdpCookie) !void {
136137
const a = arena.allocator();
137138

138139
// NOTE: The param.url can affect the default domain, (NOT path), secure, source port, and source scheme.
139-
const uri = if (param.url) |url| std.Uri.parse(url) catch return error.InvalidParams else null;
140-
const uri_ptr = if (uri) |*u| u else null;
141-
const domain = try Cookie.parseDomain(a, uri_ptr, param.domain);
140+
const maybe_url: ?URL = blk: {
141+
if (param.url) |url| {
142+
break :blk URL.parse(url, null) catch return error.InvalidParams;
143+
}
144+
145+
break :blk null;
146+
};
147+
148+
const domain = try Cookie.parseDomain(a, maybe_url, param.domain);
142149
const path = if (param.path == null) "/" else try Cookie.parsePath(a, null, param.path);
143150

144-
const secure = if (param.secure) |s| s else if (uri) |uri_| std.mem.eql(u8, uri_.scheme, "https") else false;
151+
const secure: bool = blk: {
152+
// Check if params indicate security.
153+
if (param.secure) |s| break :blk s;
154+
// Check if protocol is secure.
155+
if (maybe_url) |url| break :blk url.isSecure();
156+
// If all fails, insecure.
157+
break :blk false;
158+
};
145159

146160
const cookie = Cookie{
147161
.arena = arena,
@@ -158,6 +172,12 @@ pub fn setCdpCookie(cookie_jar: *CookieJar, param: CdpCookie) !void {
158172
.None => .none,
159173
},
160174
};
175+
176+
// Free if we had.
177+
if (maybe_url) |url| {
178+
url.deinit();
179+
}
180+
161181
try cookie_jar.add(cookie, std.time.timestamp());
162182
}
163183

0 commit comments

Comments
 (0)