72 lines
2.3 KiB
Python
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()
|