MockServer/server.py (97 lines of code) (raw):

import os import sys import signal import multiprocessing import socket import time import threading from hypercorn.config import Config from hypercorn.asyncio import serve from server_controller import app class TimeoutServer: def __init__(self, host='0.0.0.0', port=9081, accept_delay=2): self.host = host self.port = port self.accept_delay = accept_delay self.server_socket = None self.running = False self.thread = None def start(self): """Start the server in a separate thread""" self.running = True self.thread = threading.Thread(target=self._run_server) self.thread.daemon = True self.thread.start() print(f"Timeout test server started on {self.host}:{self.port} with {self.accept_delay}s delay") def stop(self): """Stop the server""" self.running = False if self.server_socket: self.server_socket.close() if self.thread: self.thread.join() print("Timeout test server stopped") def _run_server(self): """Main server loop""" self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.server_socket.bind((self.host, self.port)) self.server_socket.listen(1) self.server_socket.settimeout(1) # Allow checking running flag every second while self.running: try: # Wait for connection client_socket, address = self.server_socket.accept() print(f"Connection from {address}, delaying accept for {self.accept_delay}s") # Delay accepting the connection time.sleep(self.accept_delay) # Close the connection without sending any response client_socket.close() print("Connection closed after delay") except socket.timeout: continue # Just a timeout for checking running flag except Exception as e: if self.running: # Only log if we're still meant to be running print(f"Error: {e}") def server_process(config): """Run server in a separate process""" import asyncio async def run_server(): print(f"Starting server on {config.bind[0]}") print(f"Certificate file: {config.certfile}") print(f"Key file: {config.keyfile}") await serve(app, config) asyncio.run(run_server()) def main(): # Common SSL/TLS Configuration current_dir = os.path.dirname(os.path.abspath(__file__)) cert_file = os.path.join(current_dir, "certs/server/server.crt") key_file = os.path.join(current_dir, "certs/server/server.key") # HTTP/1.1 Server Config (plain HTTP) config_http11 = Config() config_http11.bind = ["0.0.0.0:9080"] config_http11.alpn_protocols = ["http/1.1"] # HTTP/2 Server Config (HTTPS) config_http2 = Config() config_http2.bind = ["0.0.0.0:9443"] config_http2.alpn_protocols = ["h2"] config_http2.certfile = cert_file config_http2.keyfile = key_file # Create HTTP servers processes processes = [] try: # Start HTTP/1.1 and HTTP/2 servers for config in [config_http11, config_http2]: p = multiprocessing.Process(target=server_process, args=(config,)) p.start() processes.append(p) print(f"Started process {p.pid} for {config.bind[0]}") # Start timeout test server timeout_server = TimeoutServer(port=9081, accept_delay=2) timeout_server.start() # Wait for processes for p in processes: p.join() except KeyboardInterrupt: print("\nReceived keyboard interrupt, shutting down...") finally: # Stop timeout server timeout_server.stop() # Kill all HTTP server processes for p in processes: if p.is_alive(): print(f"Terminating process {p.pid}") p.terminate() p.join(timeout=1) if p.is_alive(): print(f"Force killing process {p.pid}") p.kill() p.join() print("All servers stopped.") if __name__ == "__main__": # Handle Ctrl+C in the main process signal.signal(signal.SIGINT, lambda sig, frame: sys.exit(0)) main()