from http.server import BaseHTTPRequestHandler, HTTPServer from urllib.parse import urlsplit, parse_qs from subprocess import run from sys import argv, exit from os import environ if len(argv) <= 1: print("Arg: addr:port, or port (localhost), or :port (all interfaces)") exit(0) if ':' in argv[1]: ADDR = argv[1].rsplit(':', 1) PORT = int(ADDR[1]) ADDR = ADDR[0] else: ADDR = 'localhost' PORT = int(argv[1]) print(f'Listening on {ADDR or '*'}:{PORT}') try: with open('index.html', 'rb') as f: IX = f.read() except: IX = None def alnum(v): return all((c in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-.' for c in v)) and not v.startswith(".") class Handler(BaseHTTPRequestHandler): def do_GET(self): u = urlsplit(self.path) p = u.path a = parse_qs(u.query) if p.startswith('/'): p = p[1:] if not alnum(p): self.send_response(400) self.end_headers() return ct = None if len(p) == 0: p = 'index' ct = IX try: env = None if len(a) > 0: env = dict(environ) for k in a: if alnum(k) and len(a[k]) == 1 and alnum(a[k][0]): env[f'ARG_{k}'] = a[k][0] c = run(args=[f'./{p}'], env=env, check=True, capture_output=True) ct = c.stdout except: pass if ct is None and (IX is None or p != 'index'): self.send_response(400) self.end_headers() return self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(ct) HTTPServer((ADDR, PORT), Handler).serve_forever()