Files
Mark-VIII/scripts/dev_proxy.py
2026-08-11 20:24:24 -07:00

85 lines
3.6 KiB
Python

#!/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()