2026-01-13 09:59:39 -03:00
|
|
|
import json
|
|
|
|
|
import os
|
|
|
|
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
|
|
|
from urllib import request, error
|
|
|
|
|
|
|
|
|
|
UPSTREAM = os.environ.get("UPSTREAM_URL", "http://bstein-dev-home-backend/api/chat")
|
|
|
|
|
KEY_MATRIX = os.environ.get("CHAT_KEY_MATRIX", "")
|
|
|
|
|
KEY_HOMEPAGE = os.environ.get("CHAT_KEY_HOMEPAGE", "")
|
2026-01-26 14:08:11 -03:00
|
|
|
UPSTREAM_TIMEOUT_SEC = float(os.environ.get("UPSTREAM_TIMEOUT_SEC", "90"))
|
2026-01-13 09:59:39 -03:00
|
|
|
|
|
|
|
|
ALLOWED = {k for k in (KEY_MATRIX, KEY_HOMEPAGE) if k}
|
|
|
|
|
|
|
|
|
|
class Handler(BaseHTTPRequestHandler):
|
|
|
|
|
def _send_json(self, code: int, payload: dict):
|
|
|
|
|
body = json.dumps(payload).encode()
|
|
|
|
|
self.send_response(code)
|
|
|
|
|
self.send_header("Content-Type", "application/json")
|
|
|
|
|
self.send_header("Content-Length", str(len(body)))
|
|
|
|
|
self.end_headers()
|
|
|
|
|
self.wfile.write(body)
|
|
|
|
|
|
|
|
|
|
def do_GET(self): # noqa: N802
|
|
|
|
|
if self.path in ("/healthz", "/"):
|
|
|
|
|
return self._send_json(200, {"ok": True})
|
|
|
|
|
return self._send_json(404, {"error": "not_found"})
|
|
|
|
|
|
|
|
|
|
def do_POST(self): # noqa: N802
|
|
|
|
|
if self.path != "/":
|
|
|
|
|
return self._send_json(404, {"error": "not_found"})
|
|
|
|
|
|
|
|
|
|
key = self.headers.get("x-api-key", "")
|
|
|
|
|
if not key or key not in ALLOWED:
|
|
|
|
|
return self._send_json(401, {"error": "unauthorized"})
|
|
|
|
|
|
|
|
|
|
length = int(self.headers.get("content-length", "0") or "0")
|
|
|
|
|
raw = self.rfile.read(length) if length else b"{}"
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
upstream_req = request.Request(
|
|
|
|
|
UPSTREAM,
|
|
|
|
|
data=raw,
|
|
|
|
|
headers={"Content-Type": "application/json"},
|
|
|
|
|
method="POST",
|
|
|
|
|
)
|
2026-01-26 14:08:11 -03:00
|
|
|
with request.urlopen(upstream_req, timeout=UPSTREAM_TIMEOUT_SEC) as resp:
|
2026-01-13 09:59:39 -03:00
|
|
|
data = resp.read()
|
|
|
|
|
self.send_response(resp.status)
|
|
|
|
|
for k, v in resp.headers.items():
|
|
|
|
|
if k.lower() in ("content-length", "connection", "server", "date"):
|
|
|
|
|
continue
|
|
|
|
|
self.send_header(k, v)
|
|
|
|
|
self.send_header("Content-Length", str(len(data)))
|
|
|
|
|
self.end_headers()
|
|
|
|
|
self.wfile.write(data)
|
|
|
|
|
except error.HTTPError as e:
|
|
|
|
|
data = e.read() if hasattr(e, "read") else b""
|
|
|
|
|
self.send_response(e.code)
|
|
|
|
|
self.send_header("Content-Type", "application/json")
|
|
|
|
|
self.send_header("Content-Length", str(len(data)))
|
|
|
|
|
self.end_headers()
|
|
|
|
|
self.wfile.write(data)
|
|
|
|
|
except Exception:
|
|
|
|
|
return self._send_json(502, {"error": "bad_gateway"})
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
port = int(os.environ.get("PORT", "8080"))
|
|
|
|
|
httpd = HTTPServer(("0.0.0.0", port), Handler)
|
|
|
|
|
httpd.serve_forever()
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
main()
|