#!/usr/bin/env python3 """Fake icecast + fake MQTT broker for the radio-go e2e test. Listens on 18000 (icecast SOURCE) and 18883 (MQTT). Logs the handshake, received byte counts, and MQTT CONNECT/PUBLISH contents to stdout. Accepts repeatedly: connections that send nothing (port probes) are ignored so the real client always gets served. """ import socket, threading, time def icecast(port=18000): srv = socket.socket(); srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) srv.bind(('127.0.0.1', port)); srv.listen(4) print("[icecast] listening", flush=True) while True: c, _ = srv.accept() c.settimeout(5) try: req = c.recv(4096).decode(errors='replace') except Exception: c.close(); continue if not req.strip(): c.close(); continue # port probe print(f"[icecast] HANDSHAKE:\n{req}", flush=True) c.sendall(b"HTTP/1.1 200 OK\r\nicestreamid: e2e\r\n\r\n") total = 0 try: while True: b = c.recv(65536) if not b: break total += len(b) except Exception: pass print(f"[icecast] RECEIVED_BYTES: {total}", flush=True) c.close() def mqtt(port=18883): srv = socket.socket(); srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) srv.bind(('127.0.0.1', port)); srv.listen(4) print("[mqtt] listening", flush=True) while True: c, _ = srv.accept() c.settimeout(5) try: data = c.recv(4096) except Exception: c.close(); continue if not data or data[0] != 0x10: c.close(); continue # probe or not CONNECT print(f"[mqtt] CONNECT packet len={len(data)}", flush=True) c.sendall(bytes([0x20, 0x02, 0x00, 0x00])) # CONNACK accepted deadline = time.time() + 90 while time.time() < deadline: try: data = c.recv(4096) except socket.timeout: continue except Exception: break if not data: break if data[0] == 0x30: # PUBLISH QoS0 tl = int(data[2]) << 8 | int(data[3]) topic = data[4:4+tl].decode() payload = data[4+tl:].decode(errors='replace') print(f"[mqtt] PUBLISH topic={topic} payload={payload}", flush=True) c.close() threading.Thread(target=icecast, daemon=True).start() threading.Thread(target=mqtt, daemon=True).start() time.sleep(180) print("[fakes] done", flush=True)