#!/usr/bin/env python3 """Local dev proxy: serves www/ statically and proxies /api/* to the Pager.""" import argparse import http.server import urllib.request import urllib.error def main(): ap = argparse.ArgumentParser() ap.add_argument('--pager-host', default='172.16.52.1') ap.add_argument('--pager-port', type=int, default=8080) ap.add_argument('--port', type=int, default=8000) ap.add_argument('--www', default='payload/user/remote_access/pager-webui/www') args = ap.parse_args() api_target = 'http://%s:%d' % (args.pager_host, args.pager_port) class Proxy(http.server.SimpleHTTPRequestHandler): def __init__(self, *a, **kw): super().__init__(*a, directory=args.www, **kw) def log_message(self, fmt, *a): pass def _serve_dev_config(self): body = ('window.PAGER_CONFIG = { apiBase: "", wsBase: "", ' 'terminalWs: "ws://%s:1471/api/terminal/openWs", ' 'pagerScreenWs: "ws://%s:1471/api/pager/display/screen.ws", ' 'pagerKeysWs: "ws://%s:1471/api/pager/input/keys.ws" };\n' % (args.pager_host, args.pager_host, args.pager_host)).encode() self.send_response(200) self.send_header('Content-Type', 'text/javascript') self.send_header('Content-Length', str(len(body))) self.send_header('Cache-Control', 'no-cache') self.end_headers() self.wfile.write(body) return True def _proxy(self, method): body = None if self.headers.get('Content-Length'): body = self.rfile.read(int(self.headers['Content-Length'])) req = urllib.request.Request(api_target + self.path, data=body, method=method) if self.headers.get('Cookie'): req.add_header('Cookie', self.headers['Cookie']) req.add_header('Content-Type', self.headers.get('Content-Type', 'application/json')) try: with urllib.request.urlopen(req, timeout=25) as r: data = r.read() self.send_response(r.status) self.send_header('Content-Type', r.headers.get('Content-Type', 'application/octet-stream')) self.send_header('Content-Length', str(len(data))) for sc in r.headers.get_all('Set-Cookie', []): self.send_header('Set-Cookie', sc) self.end_headers() self.wfile.write(data) except urllib.error.HTTPError as e: data = e.read() self.send_response(e.code) self.send_header('Content-Type', e.headers.get('Content-Type', 'application/json')) self.send_header('Content-Length', str(len(data))) for sc in e.headers.get_all('Set-Cookie', []): self.send_header('Set-Cookie', sc) self.end_headers() self.wfile.write(data) def do_GET(self): if self.path == '/js/config.js': return self._serve_dev_config() if self.path.startswith('/api/'): return self._proxy('GET') return super().do_GET() def do_POST(self): return self._proxy('POST') if self.path.startswith('/api/') else self.send_error(404) def do_DELETE(self): return self._proxy('DELETE') if self.path.startswith('/api/') else self.send_error(404) http.server.ThreadingHTTPServer(('127.0.0.1', args.port), Proxy).serve_forever() if __name__ == '__main__': main()