| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- """Simple static file server for the KVM frontend with API proxy"""
- import http.server
- import urllib.request
- import urllib.error
- import os
- import json
- PORT = 8006
- DIST_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "dist")
- API_BASE = "http://127.0.0.1:8004"
- class KVMHandler(http.server.SimpleHTTPRequestHandler):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, directory=DIST_DIR, **kwargs)
- def do_GET(self):
- if self.path.startswith("/api/"):
- self._proxy("GET")
- elif self.path == "/" or self.path == "":
- self.path = "/index.html"
- super().do_GET()
- else:
- # SPA fallback: if file doesn't exist, serve index.html
- file_path = os.path.join(DIST_DIR, self.path.lstrip("/"))
- if os.path.isfile(file_path):
- super().do_GET()
- else:
- self.path = "/index.html"
- super().do_GET()
- def do_POST(self):
- if self.path.startswith("/api/"):
- self._proxy("POST")
- else:
- self.send_error(404)
- def do_PUT(self):
- if self.path.startswith("/api/"):
- self._proxy("PUT")
- else:
- self.send_error(404)
- def do_DELETE(self):
- if self.path.startswith("/api/"):
- self._proxy("DELETE")
- else:
- self.send_error(404)
- def _proxy(self, method):
- """Proxy API requests to backend"""
- content_length = int(self.headers.get("Content-Length", 0))
- body = self.rfile.read(content_length) if content_length > 0 else None
- url = f"{API_BASE}{self.path}"
- req = urllib.request.Request(url, data=body, method=method)
-
- # Forward headers
- for key in ["Content-Type", "Authorization"]:
- if key in self.headers:
- req.add_header(key, self.headers[key])
- try:
- with urllib.request.urlopen(req, timeout=30) as resp:
- resp_body = resp.read()
- self.send_response(resp.status)
- self.send_header("Content-Type", "application/json")
- self.send_header("Access-Control-Allow-Origin", "*")
- self.end_headers()
- self.wfile.write(resp_body)
- except urllib.error.HTTPError as e:
- resp_body = e.read()
- self.send_response(e.code)
- self.send_header("Content-Type", "application/json")
- self.send_header("Access-Control-Allow-Origin", "*")
- self.end_headers()
- self.wfile.write(resp_body)
- except Exception as e:
- self.send_response(502)
- self.send_header("Content-Type", "application/json")
- self.end_headers()
- self.wfile.write(json.dumps({"error": str(e)}).encode())
- def log_message(self, format, *args):
- pass # Suppress logs
- if __name__ == "__main__":
- server = http.server.HTTPServer(("0.0.0.0", PORT), KVMHandler)
- print(f"KVM Frontend serving on http://0.0.0.0:{PORT}")
- server.serve_forever()
|