Files
2025-09-13 12:46:22 -04:00

97 lines
2.8 KiB
Python

from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler
import urllib.parse as urlparse
import os
import json
import sys
import traceback
from pathlib import Path
from rokuHandler import RokuWrapper, ROKU_IP
from privatebinHandler import PrivateBinWrapper
HOST = os.environ.get("HOST", "0.0.0.0")
PORT = int(os.environ.get("PORT", "1331"))
ROOT = Path(__file__).parent.resolve()
print("root at", ROOT)
class HTTPHandler(BaseHTTPRequestHandler):
def setup(self):
print("setting up...")
super().setup()
self.rapp = RokuWrapper(self)
self.pbin = PrivateBinWrapper(self)
def _cors(self):
self.send_header("Access-Control-Allow-Origin", "*")
self.send_header("Access-Control-Allow-Headers", "*")
self.send_header("Access-Control-Allow-Methods", "GET, OPTIONS")
def _send(self, code=200, body=b''):
self.send_response(code)
self._cors()
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
if body:
self.wfile.write(body)
def _send_file(self, path: Path, content_type: str):
if not path.exists() or not path.is_file():
self._send(404, json.dumps({"error": "file not found"}).encode())
return
# send file content as JSON payload (openapi/spec are JSON)
data = path.read_bytes()
self._send(200, data)
def do_OPTIONS(self):
self.send_response(204)
self._cors()
self.end_headers()
def do_GET(self):
parsed = urlparse.urlparse(self.path)
path = parsed.path.rstrip("/").lower()
try:
# specs
if path.startswith("/roku"):
if path == "/roku/openapi.json":
return self._send_file(ROOT / "spec" / "roku.openapi.json", "application/json")
return self.rapp.run_command(path.replace("/roku/", ''))
if path.startswith("/privatebin"):
if path == "/privatebin/openapi.json":
return self._send_file(ROOT / "spec" / "privatebin.openapi.json", "application/json")
return self.pbin.run_command(path.replace("/privatebin/", ''))
# catch-all
self._send(404, json.dumps({"error": "unknown endpoint"}).encode())
except Exception as ex:
err = {"error": str(ex)}
self.log_error("Handler error: %s\n%s", ex, traceback.format_exc())
self._send(500, json.dumps(err).encode())
def log_message(self, format, *args):
# keep logs short and to stderr (default)
sys.stderr.write("%s - - [%s] %s\n" % (self.client_address[0],
self.log_date_time_string(), format % args))
def run(host=HOST, port=PORT):
server = ThreadingHTTPServer((host, port), HTTPHandler)
try:
print(f"Listening on {host}:{port} - Roku at {ROKU_IP}")
server.serve_forever()
print('finished running')
except KeyboardInterrupt:
print("Shutting down")
server.server_close()
if __name__ == "__main__":
run()
else:
print("Not running because this is not main")