mirror of
https://github.com/CloakHQ/CloakBrowser.git
synced 2026-06-23 11:41:46 +02:00
feat: rewrite cloakserve as CDP multiplexer with per-connection fingerprint seeds
Spawns a separate Chrome process per unique fingerprint seed, all behind
a single port (9222). Clients specify seeds and fingerprint params via
query string on the CDP URL:
connect_over_cdp("http://host:9222?fingerprint=12345&timezone=Asia/Tokyo")
Supports all --fingerprint-* flags as query params, geoip=true for
auto timezone/locale from proxy IP, and proxy= for per-process proxies.
- Rewrite bin/cloakserve from 57-line wrapper to aiohttp CDP multiplexer
- Add ChromePool with per-seed process management and port allocation
- Bidirectional WebSocket proxy for CDP traffic
- URL rewriting for /json/version, /json/list, and WS paths
- Rename _build_args -> build_args, _maybe_resolve_geoip -> maybe_resolve_geoip
- Add aiohttp + websockets to serve optional deps
- Dockerfile installs .[serve] extras
- Add 20 unit tests for cloakserve (param parsing, CLI args, URL rewriting)
This commit is contained in:
@@ -11,7 +11,7 @@ Usage:
|
||||
browser.close()
|
||||
"""
|
||||
|
||||
from .browser import launch, launch_async, launch_context, launch_persistent_context, launch_persistent_context_async, ProxySettings
|
||||
from .browser import launch, launch_async, launch_context, launch_persistent_context, launch_persistent_context_async, ProxySettings, build_args, maybe_resolve_geoip
|
||||
from .config import CHROMIUM_VERSION, get_default_stealth_args
|
||||
from .download import binary_info, check_for_update, clear_cache, ensure_binary
|
||||
from ._version import __version__
|
||||
@@ -40,6 +40,8 @@ __all__ = [
|
||||
"check_for_update",
|
||||
"CHROMIUM_VERSION",
|
||||
"get_default_stealth_args",
|
||||
"build_args",
|
||||
"maybe_resolve_geoip",
|
||||
"ProxySettings",
|
||||
"HumanConfig",
|
||||
"resolve_human_config",
|
||||
|
||||
+11
-11
@@ -101,8 +101,8 @@ def launch(
|
||||
sync_playwright = _import_sync_playwright(_resolve_backend(backend))
|
||||
|
||||
binary_path = ensure_binary()
|
||||
timezone, locale = _maybe_resolve_geoip(geoip, proxy, timezone, locale)
|
||||
chrome_args = _build_args(stealth_args, args, timezone=timezone, locale=locale, headless=headless)
|
||||
timezone, locale = maybe_resolve_geoip(geoip, proxy, timezone, locale)
|
||||
chrome_args = build_args(stealth_args, args, timezone=timezone, locale=locale, headless=headless)
|
||||
|
||||
logger.debug("Launching stealth Chromium (headless=%s, args=%d)", headless, len(chrome_args))
|
||||
|
||||
@@ -186,8 +186,8 @@ async def launch_async( # noqa: C901
|
||||
async_playwright = _import_async_playwright(_resolve_backend(backend))
|
||||
|
||||
binary_path = ensure_binary()
|
||||
timezone, locale = _maybe_resolve_geoip(geoip, proxy, timezone, locale)
|
||||
chrome_args = _build_args(stealth_args, args, timezone=timezone, locale=locale, headless=headless)
|
||||
timezone, locale = maybe_resolve_geoip(geoip, proxy, timezone, locale)
|
||||
chrome_args = build_args(stealth_args, args, timezone=timezone, locale=locale, headless=headless)
|
||||
|
||||
logger.debug("Launching stealth Chromium async (headless=%s, args=%d)", headless, len(chrome_args))
|
||||
|
||||
@@ -284,8 +284,8 @@ def launch_persistent_context(
|
||||
timezone = _resolve_timezone(timezone, kwargs)
|
||||
|
||||
binary_path = ensure_binary()
|
||||
timezone, locale = _maybe_resolve_geoip(geoip, proxy, timezone, locale)
|
||||
chrome_args = _build_args(stealth_args, args, timezone=timezone, locale=locale, headless=headless)
|
||||
timezone, locale = maybe_resolve_geoip(geoip, proxy, timezone, locale)
|
||||
chrome_args = build_args(stealth_args, args, timezone=timezone, locale=locale, headless=headless)
|
||||
|
||||
logger.debug(
|
||||
"Launching persistent stealth Chromium (headless=%s, user_data_dir=%s)",
|
||||
@@ -399,8 +399,8 @@ async def launch_persistent_context_async(
|
||||
timezone = _resolve_timezone(timezone, kwargs)
|
||||
|
||||
binary_path = ensure_binary()
|
||||
timezone, locale = _maybe_resolve_geoip(geoip, proxy, timezone, locale)
|
||||
chrome_args = _build_args(stealth_args, args, timezone=timezone, locale=locale, headless=headless)
|
||||
timezone, locale = maybe_resolve_geoip(geoip, proxy, timezone, locale)
|
||||
chrome_args = build_args(stealth_args, args, timezone=timezone, locale=locale, headless=headless)
|
||||
|
||||
logger.debug(
|
||||
"Launching persistent stealth Chromium async (headless=%s, user_data_dir=%s)",
|
||||
@@ -497,7 +497,7 @@ def launch_context(
|
||||
|
||||
# Resolve geoip BEFORE launch() to avoid double-resolution and ensure
|
||||
# resolved values flow to binary flags
|
||||
timezone, locale = _maybe_resolve_geoip(geoip, proxy, timezone, locale)
|
||||
timezone, locale = maybe_resolve_geoip(geoip, proxy, timezone, locale)
|
||||
# --fingerprint-timezone is process-wide (reads CommandLine in renderer),
|
||||
# so it applies to ALL contexts, not just the default one.
|
||||
# locale and timezone are set via binary flags only — no CDP emulation.
|
||||
@@ -590,7 +590,7 @@ def _ensure_proxy_scheme(proxy_url: str) -> str:
|
||||
return proxy_url if "://" in proxy_url else f"http://{proxy_url}"
|
||||
|
||||
|
||||
def _maybe_resolve_geoip(
|
||||
def maybe_resolve_geoip(
|
||||
geoip: bool,
|
||||
proxy: str | ProxySettings | None,
|
||||
timezone: str | None,
|
||||
@@ -614,7 +614,7 @@ def _maybe_resolve_geoip(
|
||||
return timezone, locale
|
||||
|
||||
|
||||
def _build_args(
|
||||
def build_args(
|
||||
stealth_args: bool,
|
||||
extra_args: list[str] | None,
|
||||
timezone: str | None = None,
|
||||
|
||||
Reference in New Issue
Block a user