diff --git a/examples/server.py b/examples/server.py index c2b189cf..14f67722 100644 --- a/examples/server.py +++ b/examples/server.py @@ -1,39 +1,115 @@ import http.server import socketserver import os +import sys from pathlib import Path +import urllib.parse SCRIPT_DIR = Path(__file__).parent.absolute() DIRECTORY = os.path.join(SCRIPT_DIR, "../build-em/bin") DIRECTORY = os.path.abspath(DIRECTORY) +# The context root we want for all applications +CONTEXT_ROOT = "/whisper.cpp" + class CustomHTTPRequestHandler(http.server.SimpleHTTPRequestHandler): def __init__(self, *args, **kwargs): super().__init__(*args, directory=DIRECTORY, **kwargs) def do_GET(self): - # If requesting a worker file from any subdirectory - if '.worker.js' in self.path: + # Redirect root to the context root + if self.path == '/': + self.send_response(302) + self.send_header('Location', CONTEXT_ROOT + '/') + self.end_headers() + return + + # Handle requests under the context root + if self.path.startswith(CONTEXT_ROOT): + # Remove the context root prefix to get the actual path + actual_path = self.path[len(CONTEXT_ROOT):] + + if not actual_path: + self.send_response(302) + self.send_header('Location', CONTEXT_ROOT + '/') + self.end_headers() + return + + if '.worker.js' in actual_path: + worker_file = os.path.basename(actual_path) + worker_path = os.path.join(DIRECTORY, worker_file) + + if os.path.exists(worker_path): + print(f"Found worker file: {worker_path}") + self.path = '/' + worker_file + else: + print(f"Worker file not found: {worker_path}") + + elif actual_path == '/': + self.path = '/whisper.wasm/index.html' + elif actual_path.startswith('/bench.wasm/') or actual_path.startswith('/command.wasm/') or actual_path.startswith('/stream.wasm/'): + # Keep the path as is, just remove the context root + self.path = actual_path + # For all other paths under the context root + else: + # Check if this is a request to a file in whisper.wasm + potential_file = os.path.join(DIRECTORY, 'whisper.wasm', actual_path.lstrip('/')) + if os.path.exists(potential_file) and not os.path.isdir(potential_file): + self.path = '/whisper.wasm' + actual_path + else: + # Try to resolve the file from the base directory + potential_file = os.path.join(DIRECTORY, actual_path.lstrip('/')) + if os.path.exists(potential_file): + self.path = actual_path + + # For direct requests to worker files (without context root as these + # are in the build-em/bin directory + elif '.worker.js' in self.path: worker_file = os.path.basename(self.path) worker_path = os.path.join(DIRECTORY, worker_file) if os.path.exists(worker_path): self.path = '/' + worker_file + # Handle coi-serviceworker.js separately + if 'coi-serviceworker.js' in self.path: + worker_file = "coi-serviceworker.js" + worker_path = os.path.join(SCRIPT_DIR, worker_file) + if os.path.exists(worker_path): + self.send_response(200) + self.send_header('Content-type', 'application/javascript') + self.end_headers() + with open(worker_path, 'rb') as file: + self.wfile.write(file.read()) + return + else: + print(f"Warning: Could not find {worker_path}") + return super().do_GET() def end_headers(self): # Add required headers for SharedArrayBuffer self.send_header("Cross-Origin-Opener-Policy", "same-origin") self.send_header("Cross-Origin-Embedder-Policy", "require-corp") - self.send_header("Access-Control-Allow-Origin", "*"); + self.send_header("Access-Control-Allow-Origin", "*") super().end_headers() PORT = 8000 -with socketserver.TCPServer(("", PORT), CustomHTTPRequestHandler) as httpd: - print(f"Serving directory '{DIRECTORY}' at http://localhost:{PORT}") - try: - httpd.serve_forever() - except KeyboardInterrupt: - print("\nServer stopped.") +# Enable address reuse +class CustomServer(socketserver.TCPServer): + allow_reuse_address = True + +try: + with CustomServer(("", PORT), CustomHTTPRequestHandler) as httpd: + print(f"Serving directory '{DIRECTORY}' at http://localhost:{PORT}") + print(f"Application context root: http://localhost:{PORT}{CONTEXT_ROOT}/") + try: + httpd.serve_forever() + except KeyboardInterrupt: + print("\nServer stopped.") + # Force complete exit + sys.exit(0) +except OSError as e: + print(f"Error: {e}") + sys.exit(1)