mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-29 19:25:03 +00:00
feat(browser): support direct WebSocket CDP URLs for Browserbase
Browserbase uses direct WebSocket connections (wss://) rather than the standard HTTP-based /json/version CDP discovery flow used by Browserless. This change teaches the browser tool to accept ws:// and wss:// URLs as cdpUrl values: when a WebSocket URL is detected, OpenClaw connects directly instead of attempting HTTP discovery. Changes: - config.ts: accept ws:// and wss:// in cdpUrl validation - cdp.helpers.ts: add isWebSocketUrl() helper - cdp.ts: skip /json/version when cdpUrl is already a WebSocket URL - chrome.ts: probe WSS endpoints via WebSocket handshake instead of HTTP - cdp.test.ts: add test for direct WebSocket target creation - docs/tools/browser.md: update Browserbase section with correct URL format and notes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
committed by
Peter Steinberger
parent
3cf75f760c
commit
75602014db
@@ -1,8 +1,20 @@
|
||||
import type { SsrFPolicy } from "../infra/net/ssrf.js";
|
||||
import { appendCdpPath, fetchJson, isLoopbackHost, withCdpSocket } from "./cdp.helpers.js";
|
||||
import {
|
||||
appendCdpPath,
|
||||
fetchJson,
|
||||
isLoopbackHost,
|
||||
isWebSocketUrl,
|
||||
withCdpSocket,
|
||||
} from "./cdp.helpers.js";
|
||||
import { assertBrowserNavigationAllowed, withBrowserNavigationPolicy } from "./navigation-guard.js";
|
||||
|
||||
export { appendCdpPath, fetchJson, fetchOk, getHeadersWithAuth } from "./cdp.helpers.js";
|
||||
export {
|
||||
appendCdpPath,
|
||||
fetchJson,
|
||||
fetchOk,
|
||||
getHeadersWithAuth,
|
||||
isWebSocketUrl,
|
||||
} from "./cdp.helpers.js";
|
||||
|
||||
export function normalizeCdpWsUrl(wsUrl: string, cdpUrl: string): string {
|
||||
const ws = new URL(wsUrl);
|
||||
@@ -94,14 +106,21 @@ export async function createTargetViaCdp(opts: {
|
||||
...withBrowserNavigationPolicy(opts.ssrfPolicy),
|
||||
});
|
||||
|
||||
const version = await fetchJson<{ webSocketDebuggerUrl?: string }>(
|
||||
appendCdpPath(opts.cdpUrl, "/json/version"),
|
||||
1500,
|
||||
);
|
||||
const wsUrlRaw = String(version?.webSocketDebuggerUrl ?? "").trim();
|
||||
const wsUrl = wsUrlRaw ? normalizeCdpWsUrl(wsUrlRaw, opts.cdpUrl) : "";
|
||||
if (!wsUrl) {
|
||||
throw new Error("CDP /json/version missing webSocketDebuggerUrl");
|
||||
let wsUrl: string;
|
||||
if (isWebSocketUrl(opts.cdpUrl)) {
|
||||
// Direct WebSocket URL (e.g. Browserbase) — skip /json/version discovery.
|
||||
wsUrl = opts.cdpUrl;
|
||||
} else {
|
||||
// Standard HTTP(S) CDP endpoint — discover WebSocket URL via /json/version.
|
||||
const version = await fetchJson<{ webSocketDebuggerUrl?: string }>(
|
||||
appendCdpPath(opts.cdpUrl, "/json/version"),
|
||||
1500,
|
||||
);
|
||||
const wsUrlRaw = String(version?.webSocketDebuggerUrl ?? "").trim();
|
||||
wsUrl = wsUrlRaw ? normalizeCdpWsUrl(wsUrlRaw, opts.cdpUrl) : "";
|
||||
if (!wsUrl) {
|
||||
throw new Error("CDP /json/version missing webSocketDebuggerUrl");
|
||||
}
|
||||
}
|
||||
|
||||
return await withCdpSocket(wsUrl, async (send) => {
|
||||
|
||||
Reference in New Issue
Block a user