single_ursim_control/single_ursim_control/tiny_http_server.py

72 lines
2.3 KiB
Python

from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
import json
import logging
from threading import Thread
#
# This section might be a little fragile, but thankfully crashing this won't take the whole process down
# Since it's running in it's own thread
# Although the process might become unresponsive
#
class TinyRequestHandler(BaseHTTPRequestHandler):
def log_message(self, format, *args):
self.server._logger.debug(format % args)
def _handle_request(self, method: str, data: bytes = None):
_, name, *path = str(self.path).split("/")
method_name = f"{method}_{name}"
if hasattr(self.server._methods_instance, method_name):
status, result = getattr(self.server._methods_instance, method_name)(path, data)
self.send_response(status)
try:
stringified_result = json.dumps(result)
content_type = 'application/json'
except TypeError:
stringified_result = str(result)
content_type = 'text/plain; charset=UTF-8'
self.send_header('Content-type', content_type)
self.end_headers()
self.wfile.write(stringified_result.encode('utf-8'))
else:
self.send_response(404)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(b"NOT FOUND")
def do_GET(self):
self._handle_request('GET', None)
def do_POST(self):
if self.headers['Content-Length']:
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
else:
post_data = None
self._handle_request('POST', post_data)
class TinyHTTPServer(Thread):
def __init__(self, methods_instance, port: int = 8000):
super().__init__()
self._logger = logging.getLogger("http")
self._http_server = ThreadingHTTPServer(('', port), TinyRequestHandler)
self._http_server._methods_instance = methods_instance
self._http_server._logger = self._logger
def run(self):
self._logger.info(f"Starting HTTP Server (bind: {self._http_server.server_address})...")
self._http_server.serve_forever()
self._logger.info("Stopped HTTP Server...")
def shutdown(self):
self._http_server.shutdown()