mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-02-04 14:33:47 +00:00
re-enable minimum viable CDP server
This commit is contained in:
@@ -122,6 +122,135 @@ pub fn isCompleteHTTPUrl(url: []const u8) bool {
|
|||||||
std.ascii.startsWithIgnoreCase(url, "ftp://");
|
std.ascii.startsWithIgnoreCase(url, "ftp://");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn getUsername(raw: [:0]const u8) []const u8 {
|
||||||
|
const user_info = getUserInfo(raw) orelse return "";
|
||||||
|
const pos = std.mem.indexOfScalarPos(u8, user_info, 0, ':') orelse return user_info;
|
||||||
|
return user_info[0..pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getPassword(raw: [:0]const u8) []const u8 {
|
||||||
|
const user_info = getUserInfo(raw) orelse return "";
|
||||||
|
const pos = std.mem.indexOfScalarPos(u8, user_info, 0, ':') orelse return "";
|
||||||
|
return user_info[pos + 1 ..];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getPathname(raw: [:0]const u8) []const u8 {
|
||||||
|
const protocol_end = std.mem.indexOf(u8, raw, "://") orelse 0;
|
||||||
|
const path_start = std.mem.indexOfScalarPos(u8, raw, if (protocol_end > 0) protocol_end + 3 else 0, '/') orelse raw.len;
|
||||||
|
|
||||||
|
const query_or_hash_start = std.mem.indexOfAnyPos(u8, raw, path_start, "?#") orelse raw.len;
|
||||||
|
|
||||||
|
if (path_start >= query_or_hash_start) {
|
||||||
|
if (std.mem.indexOf(u8, raw, "://") != null) return "/";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return raw[path_start..query_or_hash_start];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getProtocol(raw: [:0]const u8) []const u8 {
|
||||||
|
const pos = std.mem.indexOfScalarPos(u8, raw, 0, ':') orelse return "";
|
||||||
|
return raw[0 .. pos + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getHostname(raw: [:0]const u8) []const u8 {
|
||||||
|
const host = getHost(raw);
|
||||||
|
const pos = std.mem.lastIndexOfScalar(u8, host, ':') orelse return host;
|
||||||
|
return host[0..pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getPort(raw: [:0]const u8) []const u8 {
|
||||||
|
const host = getHost(raw);
|
||||||
|
const pos = std.mem.lastIndexOfScalar(u8, host, ':') orelse return "";
|
||||||
|
|
||||||
|
if (pos + 1 >= host.len) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (host[pos + 1 ..]) |c| {
|
||||||
|
if (c < '0' or c > '9') {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return host[pos + 1 ..];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getSearch(raw: [:0]const u8) []const u8 {
|
||||||
|
const pos = std.mem.indexOfScalarPos(u8, raw, 0, '?') orelse return "";
|
||||||
|
const query_part = raw[pos..];
|
||||||
|
|
||||||
|
if (std.mem.indexOfScalarPos(u8, query_part, 0, '#')) |fragment_start| {
|
||||||
|
return query_part[0..fragment_start];
|
||||||
|
}
|
||||||
|
|
||||||
|
return query_part;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getHash(raw: [:0]const u8) []const u8 {
|
||||||
|
const start = std.mem.indexOfScalarPos(u8, raw, 0, '#') orelse return "";
|
||||||
|
return raw[start..];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getOrigin(allocator: Allocator, raw: [:0]const u8) !?[]const u8 {
|
||||||
|
const port = getPort(raw);
|
||||||
|
const protocol = getProtocol(raw);
|
||||||
|
const hostname = getHostname(raw);
|
||||||
|
|
||||||
|
const p = std.meta.stringToEnum(KnownProtocol, getProtocol(raw)) orelse return null;
|
||||||
|
|
||||||
|
const include_port = blk: {
|
||||||
|
if (port.len == 0) {
|
||||||
|
break :blk false;
|
||||||
|
}
|
||||||
|
if (p == .@"https:" and std.mem.eql(u8, port, "443")) {
|
||||||
|
break :blk false;
|
||||||
|
}
|
||||||
|
if (p == .@"http:" and std.mem.eql(u8, port, "80")) {
|
||||||
|
break :blk false;
|
||||||
|
}
|
||||||
|
break :blk true;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (include_port) {
|
||||||
|
return try std.fmt.allocPrint(allocator, "{s}//{s}:{s}", .{ protocol, hostname, port });
|
||||||
|
}
|
||||||
|
return try std.fmt.allocPrint(allocator, "{s}//{s}", .{ protocol, hostname });
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getUserInfo(raw: [:0]const u8) ?[]const u8 {
|
||||||
|
const scheme_end = std.mem.indexOf(u8, raw, "://") orelse return null;
|
||||||
|
const authority_start = scheme_end + 3;
|
||||||
|
|
||||||
|
const pos = std.mem.indexOfScalar(u8, raw[authority_start..], '@') orelse return null;
|
||||||
|
const path_start = std.mem.indexOfScalarPos(u8, raw, authority_start, '/') orelse raw.len;
|
||||||
|
|
||||||
|
const full_pos = authority_start + pos;
|
||||||
|
if (full_pos < path_start) {
|
||||||
|
return raw[authority_start..full_pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getHost(raw: [:0]const u8) []const u8 {
|
||||||
|
const scheme_end = std.mem.indexOf(u8, raw, "://") orelse return "";
|
||||||
|
|
||||||
|
var authority_start = scheme_end + 3;
|
||||||
|
if (std.mem.indexOf(u8, raw[authority_start..], "@")) |pos| {
|
||||||
|
authority_start += pos + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const authority = raw[authority_start..];
|
||||||
|
const path_start = std.mem.indexOfAny(u8, authority, "/?#") orelse return authority;
|
||||||
|
return authority[0..path_start];
|
||||||
|
}
|
||||||
|
|
||||||
|
const KnownProtocol = enum {
|
||||||
|
@"http:",
|
||||||
|
@"https:",
|
||||||
|
};
|
||||||
|
|
||||||
const testing = @import("../testing.zig");
|
const testing = @import("../testing.zig");
|
||||||
test "URL: isCompleteHTTPUrl" {
|
test "URL: isCompleteHTTPUrl" {
|
||||||
try testing.expectEqual(true, isCompleteHTTPUrl("http://example.com/about"));
|
try testing.expectEqual(true, isCompleteHTTPUrl("http://example.com/about"));
|
||||||
|
|||||||
@@ -467,4 +467,5 @@ pub const JsApis = flattenTypes(&.{
|
|||||||
@import("../webapi/storage/storage.zig"),
|
@import("../webapi/storage/storage.zig"),
|
||||||
@import("../webapi/URL.zig"),
|
@import("../webapi/URL.zig"),
|
||||||
@import("../webapi/Window.zig"),
|
@import("../webapi/Window.zig"),
|
||||||
|
@import("../webapi/MutationObserver.zig"),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ pub fn wait(self: *Session, wait_ms: u32) WaitResult {
|
|||||||
return .done;
|
return .done;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (self.page) |*page| {
|
if (self.page) |page| {
|
||||||
return page.wait(wait_ms);
|
return page.wait(wait_ms);
|
||||||
}
|
}
|
||||||
return .no_page;
|
return .no_page;
|
||||||
|
|||||||
23
src/browser/webapi/MutationObserver.zig
Normal file
23
src/browser/webapi/MutationObserver.zig
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
const js = @import("../js/js.zig");
|
||||||
|
|
||||||
|
// @ZIGDOM (haha, bet you wish you hadn't opened this file)
|
||||||
|
// puppeteer's startup script creates a MutationObserver, even if it doesn't use
|
||||||
|
// it in simple scripts. This not-even-a-skeleton is required for puppeteer/cdp.js
|
||||||
|
// to run
|
||||||
|
const MutationObserver = @This();
|
||||||
|
|
||||||
|
pub fn init() MutationObserver {
|
||||||
|
return .{};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const JsApi = struct {
|
||||||
|
pub const bridge = js.Bridge(MutationObserver);
|
||||||
|
|
||||||
|
pub const Meta = struct {
|
||||||
|
pub const name = "MutationObserver";
|
||||||
|
pub const prototype_chain = bridge.prototypeChain();
|
||||||
|
pub var class_index: u16 = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const constructor = bridge.constructor(MutationObserver.init, .{});
|
||||||
|
};
|
||||||
@@ -340,6 +340,9 @@ pub fn setNodeValue(self: *const Node, value: ?[]const u8, page: *Page) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn format(self: *Node, writer: *std.Io.Writer) !void {
|
pub fn format(self: *Node, writer: *std.Io.Writer) !void {
|
||||||
|
// // If you need extra debugging:
|
||||||
|
// return @import("../dump.zig").deep(self, .{}, writer);
|
||||||
|
|
||||||
return switch (self._type) {
|
return switch (self._type) {
|
||||||
.cdata => |cd| cd.format(writer),
|
.cdata => |cd| cd.format(writer),
|
||||||
.element => |el| writer.print("{f}", .{el}),
|
.element => |el| writer.print("{f}", .{el}),
|
||||||
|
|||||||
@@ -39,15 +39,23 @@ pub fn TreeWalker(comptime mode: Mode) type {
|
|||||||
self._next = children.first();
|
self._next = children.first();
|
||||||
} else if (node._child_link.next) |n| {
|
} else if (node._child_link.next) |n| {
|
||||||
self._next = Node.linkToNode(n);
|
self._next = Node.linkToNode(n);
|
||||||
} else if (node._parent) |n| {
|
|
||||||
if (n == self._root) {
|
|
||||||
self._next = null;
|
|
||||||
} else {
|
} else {
|
||||||
self._next = Node.linkToNodeOrNull(n._child_link.next);
|
// No children, no next sibling - walk up until we find a next sibling or hit root
|
||||||
|
var current = node._parent;
|
||||||
|
while (current) |parent| {
|
||||||
|
if (parent == self._root) {
|
||||||
|
self._next = null;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
if (parent._child_link.next) |next_sibling| {
|
||||||
|
self._next = Node.linkToNode(next_sibling);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
current = parent._parent;
|
||||||
} else {
|
} else {
|
||||||
self._next = null;
|
self._next = null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const js = @import("../js/js.zig");
|
const js = @import("../js/js.zig");
|
||||||
|
|
||||||
|
const U = @import("../URL.zig");
|
||||||
const Page = @import("../Page.zig");
|
const Page = @import("../Page.zig");
|
||||||
const URLSearchParams = @import("net/URLSearchParams.zig");
|
const URLSearchParams = @import("net/URLSearchParams.zig");
|
||||||
|
|
||||||
@@ -42,106 +43,42 @@ pub fn init(url: [:0]const u8, base_: ?[:0]const u8, page: *Page) !*URL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getUsername(self: *const URL) []const u8 {
|
pub fn getUsername(self: *const URL) []const u8 {
|
||||||
const user_info = self.getUserInfo() orelse return "";
|
return U.getUsername(self._raw);
|
||||||
const pos = std.mem.indexOfScalarPos(u8, user_info, 0, ':') orelse return user_info;
|
|
||||||
return user_info[0..pos];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getPassword(self: *const URL) []const u8 {
|
pub fn getPassword(self: *const URL) []const u8 {
|
||||||
const user_info = self.getUserInfo() orelse return "";
|
return U.getPassword(self._raw);
|
||||||
const pos = std.mem.indexOfScalarPos(u8, user_info, 0, ':') orelse return "";
|
|
||||||
return user_info[pos + 1 ..];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getPathname(self: *const URL) []const u8 {
|
pub fn getPathname(self: *const URL) []const u8 {
|
||||||
const raw = self._raw;
|
return U.getPathname(self._raw);
|
||||||
const protocol_end = std.mem.indexOf(u8, raw, "://") orelse 0;
|
|
||||||
const path_start = std.mem.indexOfScalarPos(u8, raw, if (protocol_end > 0) protocol_end + 3 else 0, '/') orelse raw.len;
|
|
||||||
|
|
||||||
const query_or_hash_start = std.mem.indexOfAnyPos(u8, raw, path_start, "?#") orelse raw.len;
|
|
||||||
|
|
||||||
if (path_start >= query_or_hash_start) {
|
|
||||||
if (std.mem.indexOf(u8, raw, "://") != null) return "/";
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return raw[path_start..query_or_hash_start];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getProtocol(self: *const URL) []const u8 {
|
pub fn getProtocol(self: *const URL) []const u8 {
|
||||||
const raw = self._raw;
|
return U.getProtocol(self._raw);
|
||||||
const pos = std.mem.indexOfScalarPos(u8, raw, 0, ':') orelse return "";
|
|
||||||
return raw[0 .. pos + 1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getHostname(self: *const URL) []const u8 {
|
pub fn getHostname(self: *const URL) []const u8 {
|
||||||
const host = self.getHost();
|
return U.getHostname(self._raw);
|
||||||
const pos = std.mem.lastIndexOfScalar(u8, host, ':') orelse return host;
|
|
||||||
return host[0..pos];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getPort(self: *const URL) []const u8 {
|
pub fn getPort(self: *const URL) []const u8 {
|
||||||
const host = self.getHost();
|
return U.getPort(self._raw);
|
||||||
const pos = std.mem.lastIndexOfScalar(u8, host, ':') orelse return "";
|
|
||||||
|
|
||||||
if (pos + 1 >= host.len) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (host[pos + 1 ..]) |c| {
|
|
||||||
if (c < '0' or c > '9') {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return host[pos + 1 ..];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getOrigin(self: *const URL, page: *const Page) ![]const u8 {
|
pub fn getOrigin(self: *const URL, page: *const Page) ![]const u8 {
|
||||||
const port = self.getPort();
|
return (try U.getOrigin(page.call_arena, self._raw)) orelse {
|
||||||
const protocol = self.getProtocol();
|
|
||||||
const hostname = self.getHostname();
|
|
||||||
|
|
||||||
const p = std.meta.stringToEnum(KnownProtocol, self.getProtocol()) orelse {
|
|
||||||
// yes, a null string, that's what the spec wants
|
// yes, a null string, that's what the spec wants
|
||||||
return "null";
|
return "null";
|
||||||
};
|
};
|
||||||
|
|
||||||
const include_port = blk: {
|
|
||||||
if (port.len == 0) {
|
|
||||||
break :blk false;
|
|
||||||
}
|
|
||||||
if (p == .@"https:" and std.mem.eql(u8, port, "443")) {
|
|
||||||
break :blk false;
|
|
||||||
}
|
|
||||||
if (p == .@"http:" and std.mem.eql(u8, port, "80")) {
|
|
||||||
break :blk false;
|
|
||||||
}
|
|
||||||
break :blk true;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (include_port) {
|
|
||||||
return std.fmt.allocPrint(page.call_arena, "{s}//{s}:{s}", .{ protocol, hostname, port });
|
|
||||||
}
|
|
||||||
return std.fmt.allocPrint(page.call_arena, "{s}//{s}", .{ protocol, hostname });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getSearch(self: *const URL) []const u8 {
|
pub fn getSearch(self: *const URL) []const u8 {
|
||||||
const raw = self._raw;
|
return U.getSearch(self._raw);
|
||||||
const pos = std.mem.indexOfScalarPos(u8, raw, 0, '?') orelse return "";
|
|
||||||
const query_part = raw[pos..];
|
|
||||||
|
|
||||||
if (std.mem.indexOfScalarPos(u8, query_part, 0, '#')) |fragment_start| {
|
|
||||||
return query_part[0..fragment_start];
|
|
||||||
}
|
|
||||||
|
|
||||||
return query_part;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getHash(self: *const URL) []const u8 {
|
pub fn getHash(self: *const URL) []const u8 {
|
||||||
const raw = self._raw;
|
return U.getHash(self._raw);
|
||||||
const start = std.mem.indexOfScalarPos(u8, raw, 0, '#') orelse return "";
|
|
||||||
return raw[start..];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getSearchParams(self: *URL, page: *Page) !*URLSearchParams {
|
pub fn getSearchParams(self: *URL, page: *Page) !*URLSearchParams {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ pub fn registerTypes() []const type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub const Jar = @import("cookie.zig").Jar;
|
pub const Jar = @import("cookie.zig").Jar;
|
||||||
|
pub const Cookie =@import("cookie.zig").Cookie;
|
||||||
|
|
||||||
pub const Shed = struct {
|
pub const Shed = struct {
|
||||||
_origins: std.StringHashMapUnmanaged(*Bucket) = .empty,
|
_origins: std.StringHashMapUnmanaged(*Bucket) = .empty,
|
||||||
|
|||||||
1137
src/cdp/Node.zig
1137
src/cdp/Node.zig
File diff suppressed because it is too large
Load Diff
@@ -24,12 +24,12 @@ const log = @import("../log.zig");
|
|||||||
const js = @import("../browser/js/js.zig");
|
const js = @import("../browser/js/js.zig");
|
||||||
const polyfill = @import("../browser/polyfill/polyfill.zig");
|
const polyfill = @import("../browser/polyfill/polyfill.zig");
|
||||||
|
|
||||||
const App = @import("../app.zig").App;
|
const App = @import("../App.zig");
|
||||||
const Browser = @import("../browser/browser.zig").Browser;
|
const Browser = @import("../browser/Browser.zig");
|
||||||
const Session = @import("../browser/session.zig").Session;
|
const Session = @import("../browser/Session.zig");
|
||||||
const Page = @import("../browser/page.zig").Page;
|
const Page = @import("../browser/Page.zig");
|
||||||
const Incrementing = @import("../id.zig").Incrementing;
|
const Incrementing = @import("../id.zig").Incrementing;
|
||||||
const Notification = @import("../notification.zig").Notification;
|
const Notification = @import("../Notification.zig");
|
||||||
const LogInterceptor = @import("domains/log.zig").LogInterceptor;
|
const LogInterceptor = @import("domains/log.zig").LogInterceptor;
|
||||||
const InterceptState = @import("domains/fetch.zig").InterceptState;
|
const InterceptState = @import("domains/fetch.zig").InterceptState;
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ pub const URL_BASE = "chrome://newtab/";
|
|||||||
pub const LOADER_ID = "LOADERID24DD2FD56CF1EF33C965C79C";
|
pub const LOADER_ID = "LOADERID24DD2FD56CF1EF33C965C79C";
|
||||||
|
|
||||||
pub const CDP = CDPT(struct {
|
pub const CDP = CDPT(struct {
|
||||||
const Client = *@import("../server.zig").Client;
|
const Client = *@import("../Server.zig").Client;
|
||||||
});
|
});
|
||||||
|
|
||||||
const SessionIdGen = Incrementing(u32, "SID");
|
const SessionIdGen = Incrementing(u32, "SID");
|
||||||
@@ -117,7 +117,7 @@ pub fn CDPT(comptime TypeProvider: type) type {
|
|||||||
// timeouts (or http events) which are ready to be processed.
|
// timeouts (or http events) which are ready to be processed.
|
||||||
|
|
||||||
pub fn hasPage() bool {}
|
pub fn hasPage() bool {}
|
||||||
pub fn pageWait(self: *Self, ms: i32) Session.WaitResult {
|
pub fn pageWait(self: *Self, ms: u32) Session.WaitResult {
|
||||||
const session = &(self.browser.session orelse return .no_page);
|
const session = &(self.browser.session orelse return .no_page);
|
||||||
return session.wait(ms);
|
return session.wait(ms);
|
||||||
}
|
}
|
||||||
@@ -203,7 +203,8 @@ pub fn CDPT(comptime TypeProvider: type) type {
|
|||||||
},
|
},
|
||||||
5 => switch (@as(u40, @bitCast(domain[0..5].*))) {
|
5 => switch (@as(u40, @bitCast(domain[0..5].*))) {
|
||||||
asUint(u40, "Fetch") => return @import("domains/fetch.zig").processMessage(command),
|
asUint(u40, "Fetch") => return @import("domains/fetch.zig").processMessage(command),
|
||||||
asUint(u40, "Input") => return @import("domains/input.zig").processMessage(command),
|
// @ZIGDOM
|
||||||
|
// asUint(u40, "Input") => return @import("domains/input.zig").processMessage(command),
|
||||||
else => {},
|
else => {},
|
||||||
},
|
},
|
||||||
6 => switch (@as(u48, @bitCast(domain[0..6].*))) {
|
6 => switch (@as(u48, @bitCast(domain[0..6].*))) {
|
||||||
@@ -286,7 +287,8 @@ pub fn CDPT(comptime TypeProvider: type) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn BrowserContext(comptime CDP_T: type) type {
|
pub fn BrowserContext(comptime CDP_T: type) type {
|
||||||
const Node = @import("Node.zig");
|
// @ZIGMOD
|
||||||
|
// const Node = @import("Node.zig");
|
||||||
|
|
||||||
return struct {
|
return struct {
|
||||||
id: []const u8,
|
id: []const u8,
|
||||||
@@ -326,8 +328,9 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
|||||||
security_origin: []const u8,
|
security_origin: []const u8,
|
||||||
page_life_cycle_events: bool,
|
page_life_cycle_events: bool,
|
||||||
secure_context_type: []const u8,
|
secure_context_type: []const u8,
|
||||||
node_registry: Node.Registry,
|
// @ZIGDOM
|
||||||
node_search_list: Node.Search.List,
|
// node_registry: Node.Registry,
|
||||||
|
// node_search_list: Node.Search.List,
|
||||||
|
|
||||||
inspector: js.Inspector,
|
inspector: js.Inspector,
|
||||||
isolated_worlds: std.ArrayListUnmanaged(IsolatedWorld),
|
isolated_worlds: std.ArrayListUnmanaged(IsolatedWorld),
|
||||||
@@ -360,8 +363,9 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
|||||||
|
|
||||||
const inspector = try cdp.browser.env.newInspector(arena, self);
|
const inspector = try cdp.browser.env.newInspector(arena, self);
|
||||||
|
|
||||||
var registry = Node.Registry.init(allocator);
|
// @ZIGDOM
|
||||||
errdefer registry.deinit();
|
// var registry = Node.Registry.init(allocator);
|
||||||
|
// errdefer registry.deinit();
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.id = id,
|
.id = id,
|
||||||
@@ -374,8 +378,9 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
|||||||
.secure_context_type = "Secure", // TODO = enum
|
.secure_context_type = "Secure", // TODO = enum
|
||||||
.loader_id = LOADER_ID,
|
.loader_id = LOADER_ID,
|
||||||
.page_life_cycle_events = false, // TODO; Target based value
|
.page_life_cycle_events = false, // TODO; Target based value
|
||||||
.node_registry = registry,
|
// @ZIGDOM
|
||||||
.node_search_list = undefined,
|
// .node_registry = registry,
|
||||||
|
// .node_search_list = undefined,
|
||||||
.isolated_worlds = .empty,
|
.isolated_worlds = .empty,
|
||||||
.inspector = inspector,
|
.inspector = inspector,
|
||||||
.notification_arena = cdp.notification_arena.allocator(),
|
.notification_arena = cdp.notification_arena.allocator(),
|
||||||
@@ -383,7 +388,8 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
|||||||
.captured_responses = .empty,
|
.captured_responses = .empty,
|
||||||
.log_interceptor = LogInterceptor(Self).init(allocator, self),
|
.log_interceptor = LogInterceptor(Self).init(allocator, self),
|
||||||
};
|
};
|
||||||
self.node_search_list = Node.Search.List.init(allocator, &self.node_registry);
|
// ZIGDOM
|
||||||
|
// self.node_search_list = Node.Search.List.init(allocator, &self.node_registry);
|
||||||
errdefer self.deinit();
|
errdefer self.deinit();
|
||||||
|
|
||||||
try cdp.browser.notification.register(.page_remove, self, onPageRemove);
|
try cdp.browser.notification.register(.page_remove, self, onPageRemove);
|
||||||
@@ -418,8 +424,9 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
|||||||
world.deinit();
|
world.deinit();
|
||||||
}
|
}
|
||||||
self.isolated_worlds.clearRetainingCapacity();
|
self.isolated_worlds.clearRetainingCapacity();
|
||||||
self.node_registry.deinit();
|
// @ZIGDOM
|
||||||
self.node_search_list.deinit();
|
// self.node_registry.deinit();
|
||||||
|
// self.node_search_list.deinit();
|
||||||
self.cdp.browser.notification.unregisterAll(self);
|
self.cdp.browser.notification.unregisterAll(self);
|
||||||
|
|
||||||
if (self.http_proxy_changed) {
|
if (self.http_proxy_changed) {
|
||||||
@@ -433,8 +440,10 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset(self: *Self) void {
|
pub fn reset(self: *Self) void {
|
||||||
self.node_registry.reset();
|
// @ZIGDOM
|
||||||
self.node_search_list.reset();
|
_ = self;
|
||||||
|
// self.node_registry.reset();
|
||||||
|
// self.node_search_list.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn createIsolatedWorld(self: *Self, world_name: []const u8, grant_universal_access: bool) !*IsolatedWorld {
|
pub fn createIsolatedWorld(self: *Self, world_name: []const u8, grant_universal_access: bool) !*IsolatedWorld {
|
||||||
@@ -453,19 +462,20 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
|||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeWriter(self: *Self, root: *const Node, opts: Node.Writer.Opts) Node.Writer {
|
// @ZIGDOM
|
||||||
return .{
|
// pub fn nodeWriter(self: *Self, root: *const Node, opts: Node.Writer.Opts) Node.Writer {
|
||||||
.root = root,
|
// return .{
|
||||||
.depth = opts.depth,
|
// .root = root,
|
||||||
.exclude_root = opts.exclude_root,
|
// .depth = opts.depth,
|
||||||
.registry = &self.node_registry,
|
// .exclude_root = opts.exclude_root,
|
||||||
};
|
// .registry = &self.node_registry,
|
||||||
}
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
pub fn getURL(self: *const Self) ?[]const u8 {
|
pub fn getURL(self: *const Self) ?[:0]const u8 {
|
||||||
const page = self.session.currentPage() orelse return null;
|
const page = self.session.currentPage() orelse return null;
|
||||||
const raw_url = page.url.raw;
|
const url = page.url;
|
||||||
return if (raw_url.len == 0) null else raw_url;
|
return if (url.len == 0) null else url;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn networkEnable(self: *Self) !void {
|
pub fn networkEnable(self: *Self) !void {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,7 @@ const log = @import("../../log.zig");
|
|||||||
const network = @import("network.zig");
|
const network = @import("network.zig");
|
||||||
|
|
||||||
const Http = @import("../../http/Http.zig");
|
const Http = @import("../../http/Http.zig");
|
||||||
const Notification = @import("../../notification.zig").Notification;
|
const Notification = @import("../../Notification.zig");
|
||||||
|
|
||||||
pub fn processMessage(cmd: anytype) !void {
|
pub fn processMessage(cmd: anytype) !void {
|
||||||
const action = std.meta.stringToEnum(enum {
|
const action = std.meta.stringToEnum(enum {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Page = @import("../../browser/page.zig").Page;
|
const Page = @import("../../browser/Page.zig");
|
||||||
|
|
||||||
pub fn processMessage(cmd: anytype) !void {
|
pub fn processMessage(cmd: anytype) !void {
|
||||||
const action = std.meta.stringToEnum(enum {
|
const action = std.meta.stringToEnum(enum {
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ pub fn LogInterceptor(comptime BC: type) type {
|
|||||||
.fatal => "error",
|
.fatal => "error",
|
||||||
},
|
},
|
||||||
.text = self.allocating.written(),
|
.text = self.allocating.written(),
|
||||||
.timestamp = @import("../../datetime.zig").milliTimestamp(),
|
.timestamp = @import("../../datetime.zig").milliTimestamp(.monotonic),
|
||||||
},
|
},
|
||||||
}, .{
|
}, .{
|
||||||
.session_id = self.bc.session_id,
|
.session_id = self.bc.session_id,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const Allocator = std.mem.Allocator;
|
|||||||
|
|
||||||
const CdpStorage = @import("storage.zig");
|
const CdpStorage = @import("storage.zig");
|
||||||
const Transfer = @import("../../http/Client.zig").Transfer;
|
const Transfer = @import("../../http/Client.zig").Transfer;
|
||||||
const Notification = @import("../../notification.zig").Notification;
|
const Notification = @import("../../Notification.zig");
|
||||||
|
|
||||||
pub fn processMessage(cmd: anytype) !void {
|
pub fn processMessage(cmd: anytype) !void {
|
||||||
const action = std.meta.stringToEnum(enum {
|
const action = std.meta.stringToEnum(enum {
|
||||||
@@ -87,7 +87,7 @@ fn setExtraHTTPHeaders(cmd: anytype) !void {
|
|||||||
return cmd.sendResult(null, .{});
|
return cmd.sendResult(null, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
const Cookie = @import("../../browser/storage/storage.zig").Cookie;
|
const Cookie = @import("../../browser/webapi/storage/storage.zig").Cookie;
|
||||||
|
|
||||||
// Only matches the cookie on provided parameters
|
// Only matches the cookie on provided parameters
|
||||||
fn cookieMatches(cookie: *const Cookie, name: []const u8, domain: ?[]const u8, path: ?[]const u8) bool {
|
fn cookieMatches(cookie: *const Cookie, name: []const u8, domain: ?[]const u8, path: ?[]const u8) bool {
|
||||||
@@ -173,7 +173,7 @@ fn getCookies(cmd: anytype) !void {
|
|||||||
const params = (try cmd.params(GetCookiesParam)) orelse GetCookiesParam{};
|
const params = (try cmd.params(GetCookiesParam)) orelse GetCookiesParam{};
|
||||||
|
|
||||||
// If not specified, use the URLs of the page and all of its subframes. TODO subframes
|
// 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.raw else null; // @speed: avoid repasing the URL
|
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 &[_][]const u8{page_url orelse return error.InvalidParams};
|
||||||
|
|
||||||
var urls = try std.ArrayListUnmanaged(CdpStorage.PreparedUri).initCapacity(cmd.arena, param_urls.len);
|
var urls = try std.ArrayListUnmanaged(CdpStorage.PreparedUri).initCapacity(cmd.arena, param_urls.len);
|
||||||
@@ -247,7 +247,7 @@ pub fn httpRequestStart(arena: Allocator, bc: anytype, msg: *const Notification.
|
|||||||
.requestId = try std.fmt.allocPrint(arena, "REQ-{d}", .{transfer.id}),
|
.requestId = try std.fmt.allocPrint(arena, "REQ-{d}", .{transfer.id}),
|
||||||
.frameId = target_id,
|
.frameId = target_id,
|
||||||
.loaderId = bc.loader_id,
|
.loaderId = bc.loader_id,
|
||||||
.documentUrl = DocumentUrlWriter.init(&page.url.uri),
|
.documentUrl = page.url,
|
||||||
.request = TransferAsRequestWriter.init(transfer),
|
.request = TransferAsRequestWriter.init(transfer),
|
||||||
.initiator = .{ .type = "other" },
|
.initiator = .{ .type = "other" },
|
||||||
}, .{ .session_id = session_id });
|
}, .{ .session_id = session_id });
|
||||||
@@ -416,34 +416,35 @@ const TransferAsResponseWriter = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const DocumentUrlWriter = struct {
|
// @ZIGDOM - do we still need this? just send the full URL?
|
||||||
uri: *std.Uri,
|
// const DocumentUrlWriter = struct {
|
||||||
|
// uri: *std.Uri,
|
||||||
|
|
||||||
fn init(uri: *std.Uri) DocumentUrlWriter {
|
// fn init(uri: *std.Uri) DocumentUrlWriter {
|
||||||
return .{
|
// return .{
|
||||||
.uri = uri,
|
// .uri = uri,
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn jsonStringify(self: *const DocumentUrlWriter, jws: anytype) !void {
|
// pub fn jsonStringify(self: *const DocumentUrlWriter, jws: anytype) !void {
|
||||||
self._jsonStringify(jws) catch return error.WriteFailed;
|
// self._jsonStringify(jws) catch return error.WriteFailed;
|
||||||
}
|
// }
|
||||||
fn _jsonStringify(self: *const DocumentUrlWriter, jws: anytype) !void {
|
// fn _jsonStringify(self: *const DocumentUrlWriter, jws: anytype) !void {
|
||||||
const writer = jws.writer;
|
// const writer = jws.writer;
|
||||||
|
|
||||||
try jws.beginWriteRaw();
|
// try jws.beginWriteRaw();
|
||||||
try writer.writeByte('\"');
|
// try writer.writeByte('\"');
|
||||||
try self.uri.writeToStream(writer, .{
|
// try self.uri.writeToStream(writer, .{
|
||||||
.scheme = true,
|
// .scheme = true,
|
||||||
.authentication = true,
|
// .authentication = true,
|
||||||
.authority = true,
|
// .authority = true,
|
||||||
.path = true,
|
// .path = true,
|
||||||
.query = true,
|
// .query = true,
|
||||||
});
|
// });
|
||||||
try writer.writeByte('\"');
|
// try writer.writeByte('\"');
|
||||||
jws.endWriteRaw();
|
// jws.endWriteRaw();
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
fn idFromRequestId(request_id: []const u8) !u64 {
|
fn idFromRequestId(request_id: []const u8) !u64 {
|
||||||
if (!std.mem.startsWith(u8, request_id, "REQ-")) {
|
if (!std.mem.startsWith(u8, request_id, "REQ-")) {
|
||||||
|
|||||||
@@ -17,8 +17,8 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Page = @import("../../browser/page.zig").Page;
|
const Page = @import("../../browser/Page.zig");
|
||||||
const Notification = @import("../../notification.zig").Notification;
|
const Notification = @import("../../Notification.zig");
|
||||||
|
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ fn createIsolatedWorld(cmd: anytype) !void {
|
|||||||
|
|
||||||
fn navigate(cmd: anytype) !void {
|
fn navigate(cmd: anytype) !void {
|
||||||
const params = (try cmd.params(struct {
|
const params = (try cmd.params(struct {
|
||||||
url: []const u8,
|
url: [:0]const u8,
|
||||||
// referrer: ?[]const u8 = null,
|
// referrer: ?[]const u8 = null,
|
||||||
// transitionType: ?[]const u8 = null, // TODO: enum
|
// transitionType: ?[]const u8 = null, // TODO: enum
|
||||||
// frameId: ?[]const u8 = null,
|
// frameId: ?[]const u8 = null,
|
||||||
@@ -253,7 +253,8 @@ pub fn pageNavigate(arena: Allocator, bc: anytype, event: *const Notification.Pa
|
|||||||
bc.inspector.contextCreated(
|
bc.inspector.contextCreated(
|
||||||
page.js,
|
page.js,
|
||||||
"",
|
"",
|
||||||
try page.origin(arena),
|
"", // @ZIGDOM
|
||||||
|
// try page.origin(arena),
|
||||||
aux_data,
|
aux_data,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
@@ -360,7 +361,7 @@ pub fn pageNetworkAlmostIdle(bc: anytype, event: *const Notification.PageNetwork
|
|||||||
return sendPageLifecycle(bc, "networkAlmostIdle", event.timestamp);
|
return sendPageLifecycle(bc, "networkAlmostIdle", event.timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sendPageLifecycle(bc: anytype, name: []const u8, timestamp: u32) !void {
|
fn sendPageLifecycle(bc: anytype, name: []const u8, timestamp: u64) !void {
|
||||||
// detachTarget could be called, in which case, we still have a page doing
|
// detachTarget could be called, in which case, we still have a page doing
|
||||||
// things, but no session.
|
// things, but no session.
|
||||||
const session_id = bc.session_id orelse return;
|
const session_id = bc.session_id orelse return;
|
||||||
@@ -379,7 +380,7 @@ const LifecycleEvent = struct {
|
|||||||
frameId: []const u8,
|
frameId: []const u8,
|
||||||
loaderId: ?[]const u8,
|
loaderId: ?[]const u8,
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
timestamp: u32,
|
timestamp: u64,
|
||||||
};
|
};
|
||||||
|
|
||||||
const testing = @import("../testing.zig");
|
const testing = @import("../testing.zig");
|
||||||
|
|||||||
@@ -19,9 +19,9 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const log = @import("../../log.zig");
|
const log = @import("../../log.zig");
|
||||||
const Cookie = @import("../../browser/storage/storage.zig").Cookie;
|
const Cookie = @import("../../browser/webapi/storage/storage.zig").Cookie;
|
||||||
const CookieJar = @import("../../browser/storage/storage.zig").CookieJar;
|
const CookieJar = @import("../../browser/webapi/storage/storage.zig").Jar;
|
||||||
pub const PreparedUri = @import("../../browser/storage/cookie.zig").PreparedUri;
|
pub const PreparedUri = @import("../../browser/webapi/storage/cookie.zig").PreparedUri;
|
||||||
|
|
||||||
pub fn processMessage(cmd: anytype) !void {
|
pub fn processMessage(cmd: anytype) !void {
|
||||||
const action = std.meta.stringToEnum(enum {
|
const action = std.meta.stringToEnum(enum {
|
||||||
|
|||||||
@@ -143,13 +143,14 @@ fn createTarget(cmd: anytype) !void {
|
|||||||
|
|
||||||
bc.target_id = target_id;
|
bc.target_id = target_id;
|
||||||
|
|
||||||
var page = try bc.session.createPage();
|
const page = try bc.session.createPage();
|
||||||
{
|
{
|
||||||
const aux_data = try std.fmt.allocPrint(cmd.arena, "{{\"isDefault\":true,\"type\":\"default\",\"frameId\":\"{s}\"}}", .{target_id});
|
const aux_data = try std.fmt.allocPrint(cmd.arena, "{{\"isDefault\":true,\"type\":\"default\",\"frameId\":\"{s}\"}}", .{target_id});
|
||||||
bc.inspector.contextCreated(
|
bc.inspector.contextCreated(
|
||||||
page.js,
|
page.js,
|
||||||
"",
|
"",
|
||||||
try page.origin(cmd.arena),
|
"", // @ZIGDOM
|
||||||
|
// try page.origin(arena),
|
||||||
aux_data,
|
aux_data,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ const ArenaAllocator = std.heap.ArenaAllocator;
|
|||||||
const Testing = @This();
|
const Testing = @This();
|
||||||
|
|
||||||
const main = @import("cdp.zig");
|
const main = @import("cdp.zig");
|
||||||
const parser = @import("../browser/netsurf.zig");
|
|
||||||
|
|
||||||
const base = @import("../testing.zig");
|
const base = @import("../testing.zig");
|
||||||
pub const allocator = base.allocator;
|
pub const allocator = base.allocator;
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ pub fn abort(self: *Client) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(self: *Client, timeout_ms: i32) !PerformStatus {
|
pub fn tick(self: *Client, timeout_ms: u32) !PerformStatus {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (self.handles.hasAvailable() == false) {
|
if (self.handles.hasAvailable() == false) {
|
||||||
break;
|
break;
|
||||||
@@ -188,7 +188,7 @@ pub fn tick(self: *Client, timeout_ms: i32) !PerformStatus {
|
|||||||
const handle = self.handles.getFreeHandle().?;
|
const handle = self.handles.getFreeHandle().?;
|
||||||
try self.makeRequest(handle, transfer);
|
try self.makeRequest(handle, transfer);
|
||||||
}
|
}
|
||||||
return self.perform(timeout_ms);
|
return self.perform(@intCast(timeout_ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn request(self: *Client, req: Request) !void {
|
pub fn request(self: *Client, req: Request) !void {
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ pub fn deinit(self: *Http) void {
|
|||||||
self.arena.deinit();
|
self.arena.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll(self: *Http, timeout_ms: i32) Client.PerformStatus {
|
pub fn poll(self: *Http, timeout_ms: u32) Client.PerformStatus {
|
||||||
return self.client.tick(timeout_ms) catch |err| {
|
return self.client.tick(timeout_ms) catch |err| {
|
||||||
log.err(.app, "http poll", .{ .err = err });
|
log.err(.app, "http poll", .{ .err = err });
|
||||||
return .normal;
|
return .normal;
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
pub const App = @import("App.zig");
|
pub const App = @import("App.zig");
|
||||||
|
pub const Server = @import("Server.zig");
|
||||||
|
|
||||||
pub const log = @import("log.zig");
|
pub const log = @import("log.zig");
|
||||||
pub const dump = @import("browser/dump.zig");
|
pub const dump = @import("browser/dump.zig");
|
||||||
pub const build_config = @import("build_config");
|
pub const build_config = @import("build_config");
|
||||||
|
|||||||
35
src/main.zig
35
src/main.zig
@@ -99,27 +99,24 @@ fn run(allocator: Allocator, main_arena: Allocator) !void {
|
|||||||
app.telemetry.record(.{ .run = {} });
|
app.telemetry.record(.{ .run = {} });
|
||||||
|
|
||||||
switch (args.mode) {
|
switch (args.mode) {
|
||||||
.serve => {
|
.serve => |opts| {
|
||||||
return;
|
log.debug(.app, "startup", .{ .mode = "serve" });
|
||||||
// @ZIGDOM-CDP
|
const address = std.net.Address.parseIp4(opts.host, opts.port) catch |err| {
|
||||||
// .serve => |opts| {
|
log.fatal(.app, "invalid server address", .{ .err = err, .host = opts.host, .port = opts.port });
|
||||||
// log.debug(.app, "startup", .{ .mode = "serve" });
|
return args.printUsageAndExit(false);
|
||||||
// const address = std.net.Address.parseIp4(opts.host, opts.port) catch |err| {
|
};
|
||||||
// log.fatal(.app, "invalid server address", .{ .err = err, .host = opts.host, .port = opts.port });
|
|
||||||
// return args.printUsageAndExit(false);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // _server is global to handle graceful shutdown.
|
// _server is global to handle graceful shutdown.
|
||||||
// _server = try lp.Server.init(app, address);
|
_server = try lp.Server.init(app, address);
|
||||||
// const server = &_server.?;
|
const server = &_server.?;
|
||||||
// defer server.deinit();
|
defer server.deinit();
|
||||||
|
|
||||||
// // max timeout of 1 week.
|
// max timeout of 1 week.
|
||||||
// const timeout = if (opts.timeout > 604_800) 604_800_000 else @as(i32, opts.timeout) * 1000;
|
const timeout = if (opts.timeout > 604_800) 604_800_000 else @as(u32, opts.timeout) * 1000;
|
||||||
// server.run(address, timeout) catch |err| {
|
server.run(address, timeout) catch |err| {
|
||||||
// log.fatal(.app, "server run error", .{ .err = err });
|
log.fatal(.app, "server run error", .{ .err = err });
|
||||||
// return err;
|
return err;
|
||||||
// };
|
};
|
||||||
},
|
},
|
||||||
.fetch => |opts| {
|
.fetch => |opts| {
|
||||||
const url = opts.url;
|
const url = opts.url;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const Allocator = std.mem.Allocator;
|
|||||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||||
|
|
||||||
const log = @import("log.zig");
|
const log = @import("log.zig");
|
||||||
const App = @import("app.zig").App;
|
const App = @import("App.zig");
|
||||||
const CDP = @import("cdp/cdp.zig").CDP;
|
const CDP = @import("cdp/cdp.zig").CDP;
|
||||||
|
|
||||||
const MAX_HTTP_REQUEST_SIZE = 4096;
|
const MAX_HTTP_REQUEST_SIZE = 4096;
|
||||||
@@ -69,7 +69,7 @@ pub fn deinit(self: *Server) void {
|
|||||||
self.allocator.free(self.json_version_response);
|
self.allocator.free(self.json_version_response);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(self: *Server, address: net.Address, timeout_ms: i32) !void {
|
pub fn run(self: *Server, address: net.Address, timeout_ms: u32) !void {
|
||||||
const flags = posix.SOCK.STREAM | posix.SOCK.CLOEXEC;
|
const flags = posix.SOCK.STREAM | posix.SOCK.CLOEXEC;
|
||||||
const listener = try posix.socket(address.any.family, flags, posix.IPPROTO.TCP);
|
const listener = try posix.socket(address.any.family, flags, posix.IPPROTO.TCP);
|
||||||
self.listener = listener;
|
self.listener = listener;
|
||||||
@@ -112,7 +112,7 @@ pub fn run(self: *Server, address: net.Address, timeout_ms: i32) !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn readLoop(self: *Server, socket: posix.socket_t, timeout_ms: i32) !void {
|
fn readLoop(self: *Server, socket: posix.socket_t, timeout_ms: u32) !void {
|
||||||
// This shouldn't be necessary, but the Client is HUGE (> 512KB) because
|
// This shouldn't be necessary, but the Client is HUGE (> 512KB) because
|
||||||
// it has a large read buffer. I don't know why, but v8 crashes if this
|
// it has a large read buffer. I don't know why, but v8 crashes if this
|
||||||
// is on the stack (and I assume it's related to its size).
|
// is on the stack (and I assume it's related to its size).
|
||||||
@@ -143,7 +143,7 @@ fn readLoop(self: *Server, socket: posix.socket_t, timeout_ms: i32) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var cdp = &client.mode.cdp;
|
var cdp = &client.mode.cdp;
|
||||||
var last_message = timestamp();
|
var last_message = timestamp(.monotonic);
|
||||||
var ms_remaining = timeout_ms;
|
var ms_remaining = timeout_ms;
|
||||||
while (true) {
|
while (true) {
|
||||||
switch (cdp.pageWait(ms_remaining)) {
|
switch (cdp.pageWait(ms_remaining)) {
|
||||||
@@ -151,7 +151,7 @@ fn readLoop(self: *Server, socket: posix.socket_t, timeout_ms: i32) !void {
|
|||||||
if (try client.readSocket() == false) {
|
if (try client.readSocket() == false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
last_message = timestamp();
|
last_message = timestamp(.monotonic);
|
||||||
ms_remaining = timeout_ms;
|
ms_remaining = timeout_ms;
|
||||||
},
|
},
|
||||||
.no_page => {
|
.no_page => {
|
||||||
@@ -162,16 +162,16 @@ fn readLoop(self: *Server, socket: posix.socket_t, timeout_ms: i32) !void {
|
|||||||
if (try client.readSocket() == false) {
|
if (try client.readSocket() == false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
last_message = timestamp();
|
last_message = timestamp(.monotonic);
|
||||||
ms_remaining = timeout_ms;
|
ms_remaining = timeout_ms;
|
||||||
},
|
},
|
||||||
.done => {
|
.done => {
|
||||||
const elapsed = timestamp() - last_message;
|
const elapsed = timestamp(.monotonic) - last_message;
|
||||||
if (elapsed > ms_remaining) {
|
if (elapsed > ms_remaining) {
|
||||||
log.info(.app, "CDP timeout", .{});
|
log.info(.app, "CDP timeout", .{});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ms_remaining -= @as(i32, @intCast(elapsed));
|
ms_remaining -= @intCast(elapsed);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -928,9 +928,7 @@ fn buildJSONVersionResponse(
|
|||||||
return try std.fmt.allocPrint(allocator, response_format, .{ body_len, address });
|
return try std.fmt.allocPrint(allocator, response_format, .{ body_len, address });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn timestamp() u32 {
|
pub const timestamp = @import("datetime.zig").timestamp;
|
||||||
return @import("datetime.zig").timestamp();
|
|
||||||
}
|
|
||||||
|
|
||||||
// In-place string lowercase
|
// In-place string lowercase
|
||||||
fn toLower(str: []u8) []u8 {
|
fn toLower(str: []u8) []u8 {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const Thread = std.Thread;
|
|||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
const log = @import("../log.zig");
|
const log = @import("../log.zig");
|
||||||
const App = @import("../app.zig").App;
|
const App = @import("../App.zig");
|
||||||
const Http = @import("../http/Http.zig");
|
const Http = @import("../http/Http.zig");
|
||||||
const telemetry = @import("telemetry.zig");
|
const telemetry = @import("telemetry.zig");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user