natasa365/whisper.cpp
0
1import http.server2import socketserver3import os4import sys5from pathlib import Path6import urllib.parse7 8SCRIPT_DIR = Path(__file__).parent.absolute()9DIRECTORY = os.path.join(SCRIPT_DIR, "../build-em/bin")10DIRECTORY = os.path.abspath(DIRECTORY)11 12# The context root we want for all applications13CONTEXT_ROOT = "/whisper.cpp"14 15class CustomHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):16 def __init__(self, *args, **kwargs):17 super().__init__(*args, directory=DIRECTORY, **kwargs)18 19 def do_GET(self):20 # Redirect root to the context root21 if self.path == '/':22 self.send_response(302)23 self.send_header('Location', CONTEXT_ROOT + '/')24 self.end_headers()25 return26 27 # Handle requests under the context root28 if self.path.startswith(CONTEXT_ROOT):29 # Remove the context root prefix to get the actual path30 actual_path = self.path[len(CONTEXT_ROOT):]31 32 if not actual_path:33 self.send_response(302)34 self.send_header('Location', CONTEXT_ROOT + '/')35 self.end_headers()36 return37 38 if '.worker.js' in actual_path:39 worker_file = os.path.basename(actual_path)40 worker_path = os.path.join(DIRECTORY, worker_file)41 42 if os.path.exists(worker_path):43 print(f"Found worker file: {worker_path}")44 self.path = '/' + worker_file45 else:46 print(f"Worker file not found: {worker_path}")47 48 elif actual_path == '/':49 self.path = '/whisper.wasm/index.html'50 elif actual_path.startswith('/bench.wasm/') or actual_path.startswith('/command.wasm/') or actual_path.startswith('/stream.wasm/'):51 # Keep the path as is, just remove the context root52 self.path = actual_path53 # For all other paths under the context root54 else:55 # Check if this is a request to a file in whisper.wasm56 potential_file = os.path.join(DIRECTORY, 'whisper.wasm', actual_path.lstrip('/'))57 if os.path.exists(potential_file) and not os.path.isdir(potential_file):58 self.path = '/whisper.wasm' + actual_path59 else:60 # Try to resolve the file from the base directory61 potential_file = os.path.join(DIRECTORY, actual_path.lstrip('/'))62 if os.path.exists(potential_file):63 self.path = actual_path64 65 # For direct requests to worker files (without context root as these66 # are in the build-em/bin directory67 elif '.worker.js' in self.path:68 worker_file = os.path.basename(self.path)69 worker_path = os.path.join(DIRECTORY, worker_file)70 71 if os.path.exists(worker_path):72 self.path = '/' + worker_file73 74 # Handle coi-serviceworker.js separately75 if 'coi-serviceworker.js' in self.path:76 worker_file = "coi-serviceworker.js"77 worker_path = os.path.join(SCRIPT_DIR, worker_file)78 if os.path.exists(worker_path):79 self.send_response(200)80 self.send_header('Content-type', 'application/javascript')81 self.end_headers()82 with open(worker_path, 'rb') as file:83 self.wfile.write(file.read())84 return85 else:86 print(f"Warning: Could not find {worker_path}")87 88 return super().do_GET()89 90 def end_headers(self):91 # Add required headers for SharedArrayBuffer92 self.send_header("Cross-Origin-Opener-Policy", "same-origin")93 self.send_header("Cross-Origin-Embedder-Policy", "require-corp")94 self.send_header("Access-Control-Allow-Origin", "*")95 super().end_headers()96 97PORT = 800098 99# Enable address reuse100class CustomServer(socketserver.TCPServer):101 allow_reuse_address = True102 103try:104 with CustomServer(("", PORT), CustomHTTPRequestHandler) as httpd:105 print(f"Serving directory '{DIRECTORY}' at http://localhost:{PORT}")106 print(f"Application context root: http://localhost:{PORT}{CONTEXT_ROOT}/")107 try:108 httpd.serve_forever()109 except KeyboardInterrupt:110 print("\nServer stopped.")111 # Force complete exit112 sys.exit(0)113except OSError as e:114 print(f"Error: {e}")115 sys.exit(1)116 