# retoor from __future__ import annotations import logging from socketserver import ForkingMixIn from xmlrpc.server import SimpleXMLRPCDispatcher, SimpleXMLRPCRequestHandler, SimpleXMLRPCServer from defusedxml.xmlrpc import monkey_patch as _harden_xmlrpc from devplacepy.config import XMLRPC_BIND, XMLRPC_PORT _harden_xmlrpc() from . import bridge from .registry import Method, build_index, method_help, method_signature logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", ) logger = logging.getLogger("xmlrpc.server") RPC_PATHS = ("/", "/RPC2", "/xmlrpc") def _auth_from_headers(headers) -> dict[str, str]: auth: dict[str, str] = {} api_key = headers.get("X-API-KEY") or headers.get("x-api-key") authorization = headers.get("Authorization") or headers.get("authorization") or "" if not api_key and authorization.lower().startswith("bearer "): api_key = authorization[7:].strip() if authorization.lower().startswith("basic "): auth["authorization"] = authorization.strip() if api_key: auth["api_key"] = api_key.strip() real_ip = headers.get("X-Real-IP") or headers.get("x-real-ip") if real_ip: auth["real_ip"] = real_ip forwarded = headers.get("X-Forwarded-For") or headers.get("x-forwarded-for") if forwarded: auth["forwarded_for"] = forwarded return auth class _RequestHandler(SimpleXMLRPCRequestHandler): rpc_paths = RPC_PATHS def decode_request_content(self, data): if b" ForkingXMLRPCServer: index = build_index() server = ForkingXMLRPCServer((host, port), index) server.register_introspection_functions() server.register_multicall_functions() for name, method in index.items(): server.register_function(_make_handler(server, method), name) logger.info("XML-RPC bridge registered %d methods", len(index)) return server def main() -> None: server = build_server(XMLRPC_BIND, XMLRPC_PORT) logger.info("Forking XML-RPC server listening on %s:%d", XMLRPC_BIND, XMLRPC_PORT) try: server.serve_forever() except KeyboardInterrupt: logger.info("XML-RPC server interrupted") finally: server.server_close() if __name__ == "__main__": main()