#!/usr/bin/env python3 import argparse import ipaddress import socket import ssl import subprocess from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer from pathlib import Path class IsolatedHandler(SimpleHTTPRequestHandler): def end_headers(self): self.send_header("Cross-Origin-Opener-Policy", "same-origin") self.send_header("Cross-Origin-Embedder-Policy", "require-corp") self.send_header("Cross-Origin-Resource-Policy", "same-origin") super().end_headers() def local_ip(): with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: try: s.connect(("8.8.8.8", 80)) return s.getsockname()[0] except OSError: return "127.0.0.1" def ensure_cert(cert: Path, key: Path): """Generate a self-signed cert covering localhost and the LAN IP, so a headless box can be reached directly over HTTPS (secure context).""" if cert.exists() and key.exists(): return ip = local_ip() san = f"subjectAltName=DNS:localhost,IP:127.0.0.1,IP:{ip}" subprocess.run( ["openssl", "req", "-x509", "-newkey", "rsa:2048", "-sha256", "-days", "3650", "-nodes", "-keyout", str(key), "-out", str(cert), "-subj", "/CN=localhost", "-addext", san], check=True, ) print(f"Generated self-signed cert for localhost and {ip} at {cert}") def main(): parser = argparse.ArgumentParser() parser.add_argument("--port", type=int, default=8000) parser.add_argument("--host", default="0.0.0.0") parser.add_argument("--tls", action="store_true", help="serve over HTTPS with a self-signed cert") parser.add_argument("--cert", default=".serve-cert.pem") parser.add_argument("--key", default=".serve-key.pem") args = parser.parse_args() server = ThreadingHTTPServer((args.host, args.port), IsolatedHandler) scheme = "http" if args.tls: ensure_cert(Path(args.cert), Path(args.key)) context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) context.load_cert_chain(args.cert, args.key) server.socket = context.wrap_socket(server.socket, server_side=True) scheme = "https" print(f"Serving on {scheme}://{args.host}:{args.port}/web/") if args.tls: print(f"Reach it directly at {scheme}://{local_ip()}:{args.port}/web/ " "(accept the self-signed cert warning once).") else: print("Note: WASM pthreads need a secure context — use localhost, an SSH " "tunnel, or --tls; a bare LAN IP over HTTP is not cross-origin isolated.") server.serve_forever() if __name__ == "__main__": main()