import argparse import os from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer from pathlib import Path DEFAULT_HOST = "127.0.0.1" DEFAULT_PORT = 8787 CALLBACK_PATH = "/vk/callback" HEALTH_PATH = "/health" def _read_callback_html(): html_path = Path(__file__).resolve().parent / "vk-callback" / "index.html" return html_path.read_bytes() class VkCallbackHandler(BaseHTTPRequestHandler): server_version = "AnabasisVkCallback/1.0" def do_GET(self): path = self.path.split("?", 1)[0] if path == HEALTH_PATH: self._send_text(200, "ok\n") return if path in ("/", CALLBACK_PATH): self._send_html(200, _read_callback_html()) return self._send_text(404, "not found\n") def log_message(self, fmt, *args): if getattr(self.server, "quiet", False): return super().log_message(fmt, *args) def _send_html(self, status, body): self.send_response(status) self.send_header("Content-Type", "text/html; charset=utf-8") self.send_header("Cache-Control", "no-store") self.send_header("Content-Length", str(len(body))) self.end_headers() self.wfile.write(body) def _send_text(self, status, text): body = text.encode("utf-8") self.send_response(status) self.send_header("Content-Type", "text/plain; charset=utf-8") self.send_header("Cache-Control", "no-store") self.send_header("Content-Length", str(len(body))) self.end_headers() self.wfile.write(body) def parse_args(): parser = argparse.ArgumentParser(description="Anabasis VK OAuth callback host") parser.add_argument("--host", default=os.getenv("ANABASIS_VK_CALLBACK_HOST", DEFAULT_HOST)) parser.add_argument("--port", type=int, default=int(os.getenv("ANABASIS_VK_CALLBACK_PORT", DEFAULT_PORT))) parser.add_argument("--quiet", action="store_true") return parser.parse_args() def main(): args = parse_args() server = ThreadingHTTPServer((args.host, args.port), VkCallbackHandler) server.quiet = args.quiet print(f"VK callback server listening on http://{args.host}:{args.port}{CALLBACK_PATH}") print(f"Health check: http://{args.host}:{args.port}{HEALTH_PATH}") try: server.serve_forever() except KeyboardInterrupt: pass finally: server.server_close() return 0 if __name__ == "__main__": raise SystemExit(main())