from http import HTTPStatus from flask import Flask, Response, request, send_file from os import urandom from threading import Thread, Event from werkzeug.serving import make_server from typing import Optional from types import FrameType import signal import sys from base64 import b64encode as base64_encode SERVER_IP: str = "0.0.0.0" HTTP_HOST: str = "sniphbank.com" HTTP_PORT: int = 80 HTTPS_PORT: int = 443 DEBUG: bool = False app = Flask(__name__) app.secret_key = urandom(24) @app.route("/") def index(): return send_file("./website/index.html") @app.route("/login", methods=["POST"]) def login(): # There isn't really a reason to validate the user for the demo, # just decide on a username that might pertain to whomever's # personal information user = request.form["username"] password = request.form["password"].encode() if user != "ronniej": return Response("User not found", HTTPStatus.UNAUTHORIZED) if base64_encode(password).decode() != "Z29GQUxDT05TMTIz": return Response("Incorrect password", HTTPStatus.UNAUTHORIZED) return send_file("./website/account.html") @app.route("/css/style.css", methods=["GET"]) def stylesheet(): return send_file("./website/css/style.css") @app.route("/favicon.ico", methods=["GET"]) def favicon(): return send_file("./website/favicon.ico") class ServerThread(Thread): def __init__( self, app: Flask, host: str, port: int, ssl_context: Optional[tuple[str, str]] = None, name: str = "ServerThread", ) -> None: super().__init__(name=name, daemon=True) self.server = make_server( host, port, app, threaded=True, ssl_context=ssl_context, # tuple (cert, key) or SSLContext ) def run(self): self.server.serve_forever() def shutdown(self): self.server.shutdown() def _install_signal_handlers(stop_event: Event): def handler(signum: signal.Signals, frame: Optional[FrameType]): stop_event.set() signal.signal(signal.SIGINT, handler) try: signal.signal(signal.SIGTERM, handler) except AttributeError: pass if __name__ == "__main__": stop_event = Event() _install_signal_handlers(stop_event) http_server = ServerThread( app, SERVER_IP, HTTP_PORT, ssl_context=None, name="HTTP-Thread" ) https_server = ServerThread( app, SERVER_IP, HTTPS_PORT, ssl_context=("./certs/cert.pem", "./certs/key.pem"), name="HTTPS-Thread", ) try: http_server.start() https_server.start() print(f"HTTP server running at http://{SERVER_IP}:{HTTP_PORT}") print(f"HTTPS server running at https://{SERVER_IP}:{HTTPS_PORT}") print("Press Ctrl+C to stop.") stop_event.wait() except KeyboardInterrupt: pass finally: for srv in (http_server, https_server): try: srv.shutdown() except Exception: pass for srv in (http_server, https_server): srv.join(timeout=5) print("Servers stopped!") sys.exit(0)