#!/usr/bin/env python3 """ Lightweight test server and transparent proxy for the Pando 🌳 cluster. Serves index.html on http://127.0.0.1:8080 and transparently proxies requests to cluster instances, bypassing self-signed TLS certificate checks. """ from http.server import SimpleHTTPRequestHandler, HTTPServer import urllib.request import urllib.error import urllib.parse import ssl import json import os PORT = int(os.environ.get("DASHBOARD_PORT", 8080)) # Create an SSL context that ignores self-signed certificate errors SSL_CTX = ssl._create_unverified_context() class ProxyHandler(SimpleHTTPRequestHandler): def end_headers(self): self.send_header('Access-Control-Allow-Origin', '*') self.send_header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, HEAD') self.send_header('Access-Control-Allow-Headers', '*') super().end_headers() def do_OPTIONS(self): self.send_response(204) self.end_headers() def do_GET(self): if self.path.startswith('/proxy'): self.handle_proxy('GET') else: super().do_GET() def do_HEAD(self): if self.path.startswith('/proxy'): self.handle_proxy('HEAD') else: super().do_HEAD() def do_POST(self): if self.path.startswith('/proxy'): self.handle_proxy('POST') else: self.send_error(405, "Method Not Allowed") def do_PUT(self): if self.path.startswith('/proxy'): self.handle_proxy('PUT') else: self.send_error(405, "Method Not Allowed") def do_DELETE(self): if self.path.startswith('/proxy'): self.handle_proxy('DELETE') else: self.send_error(405, "Method Not Allowed") def extract_target_url(self): parsed = urllib.parse.urlparse(self.path) if parsed.path.rstrip('/') == '/proxy': if '?url=' in self.path: return urllib.parse.unquote(self.path.split('?url=', 1)[1]) qs = urllib.parse.parse_qs(parsed.query) return qs.get('url', [None])[0] elif parsed.path.startswith('/proxy/'): rest = self.path[len('/proxy/'):] if rest.startswith('http://') or rest.startswith('https://'): return rest parts = rest.split('/', 1) host_or_port = parts[0] subpath = '/' + parts[1] if len(parts) > 1 else '' if parsed.query: subpath += '?' + parsed.query if host_or_port.isdigit(): return f"https://127.0.0.1:{host_or_port}{subpath}" return f"https://{host_or_port}{subpath}" return None def handle_proxy(self, method): target_url = self.extract_target_url() if not target_url: self.send_response(400) self.send_header('Content-Type', 'application/json') self.end_headers() self.wfile.write(json.dumps({'error': 'Missing or invalid target URL'}).encode()) return content_length = int(self.headers.get('Content-Length', 0)) body = self.rfile.read(content_length) if content_length > 0 else None # Filter hop-by-hop headers and compression to ensure clean raw data transfer req_headers = {} for k, v in self.headers.items(): if k.lower() in ('host', 'content-length', 'connection', 'transfer-encoding', 'accept-encoding'): continue req_headers[k] = v req = urllib.request.Request(target_url, data=body, headers=req_headers, method=method) try: with urllib.request.urlopen(req, context=SSL_CTX, timeout=15) as resp: status_code = resp.status resp_headers = resp.getheaders() resp_body = resp.read() if method != 'HEAD' else b'' except urllib.error.HTTPError as e: status_code = e.code resp_headers = e.headers.items() resp_body = e.read() if method != 'HEAD' else b'' except urllib.error.URLError as e: self.send_response(502) self.send_header('Content-Type', 'application/json') self.end_headers() err_msg = json.dumps({'error': f'Failed to connect to backend: {e.reason}'}).encode() self.wfile.write(err_msg) return except Exception as e: self.send_response(500) self.send_header('Content-Type', 'application/json') self.end_headers() err_msg = json.dumps({'error': f'Proxy exception: {str(e)}'}).encode() self.wfile.write(err_msg) return self.send_response(status_code) for k, v in resp_headers: if k.lower() in ('transfer-encoding', 'connection', 'content-length', 'access-control-allow-origin', 'access-control-allow-methods', 'access-control-allow-headers'): continue self.send_header(k, v) if method != 'HEAD': self.send_header('Content-Length', str(len(resp_body))) self.end_headers() if method != 'HEAD' and resp_body: self.wfile.write(resp_body) if __name__ == '__main__': print(f"🚀 Dashboard running at http://127.0.0.1:{PORT}") print(f"🔒 TLS unverified proxy active at /proxy?url=") print("Press Ctrl+C to stop.") server = HTTPServer(('127.0.0.1', PORT), ProxyHandler) try: server.serve_forever() except KeyboardInterrupt: print("\nStopping...")