076914e5b7
- Split client, native, remote, serve, markdown, and SDK internals into focused packages with direct imports. - Move local and remote transport framing/protocol helpers behind clearer module boundaries. - Break up the extension injected DOM logic into a separate content dispatch bundle and dedicated content modules. - Add explicit client handling for passive remote discovery without noisy PQ warnings. - Keep behavior covered with updated unit, integration, and extension tests.
56 lines
2.1 KiB
Python
56 lines
2.1 KiB
Python
"""Remote endpoint string handling — parsing, normalization, display.
|
|
|
|
Pure helpers (no sockets, no I/O) for turning user-facing ``host[:port]``
|
|
strings into the canonical forms the rest of the client uses, and back into the
|
|
short forms shown to humans.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
|
|
from browser_cli.constants import DEFAULT_REMOTE_PORT
|
|
from browser_cli.errors import BrowserNotConnected
|
|
|
|
def _looks_like_domain(host: str) -> bool:
|
|
"""True if host looks like a domain name rather than an IP address or localhost."""
|
|
if host in {"localhost", "127.0.0.1", "::1"}:
|
|
return False
|
|
if re.match(r'^\d{1,3}(\.\d{1,3}){3}$', host):
|
|
return False
|
|
return '.' in host and any(c.isalpha() for c in host)
|
|
|
|
def _normalize_endpoint(endpoint: str) -> str:
|
|
"""Strip :443 from domain-like endpoints so they are stored without the default port."""
|
|
if not endpoint:
|
|
return endpoint
|
|
host, sep, port = endpoint.rpartition(":")
|
|
if sep and port == "443" and _looks_like_domain(host):
|
|
return host
|
|
return endpoint
|
|
|
|
def _resolve_connect_endpoint(endpoint: str) -> str:
|
|
"""Return host:port for TCP connection; domain without port defaults to :443."""
|
|
_, sep, _ = endpoint.rpartition(":")
|
|
if not sep:
|
|
if _looks_like_domain(endpoint):
|
|
return f"{endpoint}:{DEFAULT_REMOTE_PORT}"
|
|
raise BrowserNotConnected(
|
|
f"Invalid remote endpoint '{endpoint}': expected host:port"
|
|
)
|
|
return endpoint
|
|
|
|
def display_browser_name(profile_name: str, sock_path: str) -> str:
|
|
from pathlib import Path
|
|
|
|
if profile_name != "default":
|
|
return profile_name
|
|
return Path(sock_path).stem or profile_name
|
|
|
|
def _remote_display_name(endpoint: str, profile_name: str, display_name: str) -> str:
|
|
host, sep, port = endpoint.rpartition(":")
|
|
if sep and (port == "8765" or (port == "443" and _looks_like_domain(host))):
|
|
display_endpoint = host
|
|
else:
|
|
display_endpoint = endpoint # normalized domain (no port) or non-default port
|
|
return f"{display_endpoint}:{display_name or profile_name}"
|