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)