mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-09-14 15:03:27 -04:00
ops: Allow serving both cdp and bidi on the same port
--protocol can now be specified multiple times. This just makes ops/dev easier by only requiring 1 instance.
This commit is contained in:
7 files changed
+30
-19
No files matched your search
@@ -116,8 +116,7 @@ jobs:
|
||||
echo "value=$args" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- run: |
|
||||
./lightpanda serve --port 9222 --protocol cdp ${{ steps.args.outputs.value }} &
|
||||
./lightpanda serve --port 9223 --protocol webdriver ${{ steps.args.outputs.value }} &
|
||||
./lightpanda serve --port 9222 --protocol cdp --protocol webdriver ${{ steps.args.outputs.value }} &
|
||||
|
||||
- run: |
|
||||
go run runner/main.go
|
||||
|
||||
+5
-4
@@ -386,7 +386,8 @@ const Commands = cli.Builder(.{
|
||||
.{ .name = "host", .type = []const u8, .default = "127.0.0.1" },
|
||||
.{ .name = "port", .type = u16, .default = 9222 },
|
||||
.{ .name = "advertise_host", .type = ?[]const u8 },
|
||||
.{ .name = "protocol", .type = Protocol, .default = Protocol.cdp },
|
||||
// Repeatable; one server can speak several on the same port.
|
||||
.{ .name = "protocol", .type = Protocol, .multiple = true },
|
||||
.{ .name = "cdp_max_connections", .type = u16, .default = 16 },
|
||||
.{ .name = "cdp_max_pending_connections", .type = u16, .default = 128 },
|
||||
.{ .name = "cdp_max_message_size", .type = u32, .default = 1024 * 1024 },
|
||||
@@ -827,10 +828,10 @@ pub const Protocol = enum {
|
||||
webdriver,
|
||||
};
|
||||
|
||||
pub fn protocol(self: *const Config) Protocol {
|
||||
pub fn protocols(self: *const Config) []const Protocol {
|
||||
return switch (self.mode) {
|
||||
.serve => |opts| opts.protocol,
|
||||
.mcp => .cdp,
|
||||
.serve => |opts| if (opts.protocol.items.len == 0) &.{.cdp} else opts.protocol.items,
|
||||
.mcp => &.{.cdp},
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
// Synthetic user input driving the DOM: mouse, wheel, keyboard, focus
|
||||
// navigation and text insertion. These are mostly fed by CDP's Input domain
|
||||
// (src/cdp/domains/input.zig) and by EventManager's default activation
|
||||
// (src/server/cdp/domains/input.zig) and by EventManager's default activation
|
||||
// behavior. Form submission itself lives on the Frame (it's a navigation
|
||||
// concern); the activation paths here call into it.
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ const lp = @import("lightpanda");
|
||||
const zenai = @import("zenai");
|
||||
|
||||
const NodeRegistry = @import("../NodeRegistry.zig");
|
||||
const LimitedWriter = @import("../LimitedWriter.zig");
|
||||
|
||||
const DOMNode = @import("webapi/Node.zig");
|
||||
const Selector = @import("webapi/selector/Selector.zig");
|
||||
|
||||
@@ -48,6 +48,14 @@
|
||||
\\ --port <INT>
|
||||
\\ Port of the CDP server.
|
||||
\\ Defaults to 9222.
|
||||
\\ --protocol <PROTOCOL>
|
||||
\\ Automation protocol to serve. Can be passed multiple times to
|
||||
\\ serve several on the same port.
|
||||
\\ Defaults to cdp.
|
||||
\\ Allowed values:
|
||||
\\ cdp Chrome DevTools Protocol (WebSocket on /).
|
||||
\\ webdriver WebDriver BiDi (WebSocket on /session) plus the
|
||||
\\ classic WebDriver session endpoints.
|
||||
,
|
||||
.fetch =
|
||||
\\usage: {0s} fetch <url>... [OPTIONS] [COMMON_OPTIONS]
|
||||
|
||||
@@ -160,6 +160,12 @@ pub fn init(app: *App, address: sys_net.IpAddress) !*Server {
|
||||
const bidi_session_url = try std.fmt.allocPrint(allocator, "ws://{s}:{d}/session/", .{ app.config.advertiseHost(), port });
|
||||
errdefer allocator.free(bidi_session_url);
|
||||
|
||||
var protocols: Handshake.Protocols = .{};
|
||||
for (app.config.protocols()) |p| switch (p) {
|
||||
.cdp => protocols.cdp = true,
|
||||
.webdriver => protocols.webdriver = true,
|
||||
};
|
||||
|
||||
self.* = .{
|
||||
.app = app,
|
||||
.cdp_pool = .empty,
|
||||
@@ -170,10 +176,7 @@ pub fn init(app: *App, address: sys_net.IpAddress) !*Server {
|
||||
.pollfds = pollfds,
|
||||
.wakeup_pipe = pipe,
|
||||
.poll_snapshot = poll_snapshot,
|
||||
.protocols = switch (app.config.protocol()) {
|
||||
.cdp => .{ .cdp = true },
|
||||
.webdriver => .{ .webdriver = true },
|
||||
},
|
||||
.protocols = protocols,
|
||||
};
|
||||
return self;
|
||||
}
|
||||
@@ -1468,7 +1471,7 @@ test "server: classic session bootstrap errors" {
|
||||
}
|
||||
|
||||
test "server: protocol gate" {
|
||||
// The test server serves both; the CLI only ever enables one.
|
||||
// The test server serves both; --protocol picks which a real server does.
|
||||
const protocols = &testing.test_cdp_server.?.protocols;
|
||||
defer protocols.* = .{ .cdp = true, .webdriver = true };
|
||||
|
||||
|
||||
@@ -484,12 +484,13 @@ pub const Serializer = struct {
|
||||
defer self.unsee();
|
||||
|
||||
const next_depth = depth + 1;
|
||||
var names = try object.nameIterator();
|
||||
var list: std.ArrayList(Property) = try .initCapacity(self.arena, names.count);
|
||||
while (try names.next()) |name| {
|
||||
const owned = try self.arena.dupe(u8, name);
|
||||
const value = try object.get(owned);
|
||||
list.appendAssumeCapacity(.{ .name = owned, .value = try self.remote(value, next_depth, false) });
|
||||
var it = try object.iterator();
|
||||
var list: std.ArrayList(Property) = try .initCapacity(self.arena, it.count);
|
||||
while (try it.next()) |entry| {
|
||||
list.appendAssumeCapacity(.{
|
||||
.name = try self.arena.dupe(u8, entry.name),
|
||||
.value = try self.remote(entry.value, next_depth, false),
|
||||
});
|
||||
}
|
||||
return list.items;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user