121 lines
4.5 KiB
Python
121 lines
4.5 KiB
Python
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):
|
|
# 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 any(actual_path.startswith(prefix) for prefix in (
|
|
'/bench.wasm/',
|
|
'/command.wasm/',
|
|
'/stream.wasm/',
|
|
'/wchess.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", "*")
|
|
super().end_headers()
|
|
|
|
PORT = 8000
|
|
|
|
# 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)
|