Files
cc-ci/tests/rustdesk-server/custom/test_websocket_handshake.py
T

53 lines
1.7 KiB
Python

"""rustdesk-server — real websocket handshakes against hbbs/hbbr's ws listeners.
21118 (hbbs) and 21119 (hbbr) are the servers' websocket endpoints — the surface a real
RustDesk web client uses. A completed `101 Switching Protocols` upgrade is the app's own
protocol answering (verified live against 1.1.12 and 1.1.16 during enrollment); a bare GET
without upgrade headers gets NO response, so this can only pass against a genuinely serving
listener, never a proxy or placeholder.
"""
from __future__ import annotations
import socket
import time
WS_PORTS = {21118: "hbbs", 21119: "hbbr"}
_REQ = (
b"GET / HTTP/1.1\r\n"
b"Host: rustdesk\r\n"
b"Upgrade: websocket\r\n"
b"Connection: Upgrade\r\n"
b"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
b"Sec-WebSocket-Version: 13\r\n"
b"\r\n"
)
def _handshake(port: int, timeout: float = 5.0) -> bytes:
with socket.create_connection(("127.0.0.1", port), timeout=timeout) as s:
s.sendall(_REQ)
s.settimeout(timeout)
return s.recv(200)
def test_websocket_upgrades(meta):
"""Both ws endpoints complete an HTTP->websocket upgrade with 101 (poll per §5)."""
deadline = time.time() + meta.HTTP_TIMEOUT
pending = dict(WS_PORTS)
while pending and time.time() < deadline:
for port in list(pending):
try:
data = _handshake(port)
except OSError:
data = b""
if data.startswith(b"HTTP/1.1 101"):
del pending[port]
if pending:
time.sleep(3)
assert not pending, (
f"websocket endpoints did not complete 101 upgrades: {pending} "
f"(waited {meta.HTTP_TIMEOUT}s)"
)