test: map URL to other directories

This allows to 'mount' the SDL source directory on http://localhost:8080/SDL.
This is useful for debugging emscripten applications in the browser.

Build SDL with "-gsource-map -ffile-prefix-map=/path/to/SDL:/SDL" to
configure the URL where the source code must be available.
This commit is contained in:
Anonymous Maarten 2024-05-30 20:30:36 +02:00 committed by Anonymous Maarten
parent d29276e625
commit 3fccb77da6

View file

@ -6,8 +6,8 @@ from argparse import ArgumentParser
import contextlib import contextlib
from http.server import SimpleHTTPRequestHandler from http.server import SimpleHTTPRequestHandler
from http.server import ThreadingHTTPServer from http.server import ThreadingHTTPServer
import os
import socket import socket
from socketserver import TCPServer
class MyHTTPRequestHandler(SimpleHTTPRequestHandler): class MyHTTPRequestHandler(SimpleHTTPRequestHandler):
@ -23,6 +23,10 @@ class MyHTTPRequestHandler(SimpleHTTPRequestHandler):
"": "application/octet-stream", "": "application/octet-stream",
} }
def __init__(self, *args, maps=None, **kwargs):
self.maps = maps or []
SimpleHTTPRequestHandler.__init__(self, *args, **kwargs)
def end_headers(self): def end_headers(self):
self.send_my_headers() self.send_my_headers()
SimpleHTTPRequestHandler.end_headers(self) SimpleHTTPRequestHandler.end_headers(self)
@ -32,12 +36,20 @@ class MyHTTPRequestHandler(SimpleHTTPRequestHandler):
self.send_header("Pragma", "no-cache") self.send_header("Pragma", "no-cache")
self.send_header("Expires", "0") self.send_header("Expires", "0")
def translate_path(self, path):
for map_path, map_prefix in self.maps:
if path.startswith(map_prefix):
res = os.path.join(map_path, path.removeprefix(map_prefix).lstrip("/"))
break
else:
res = super().translate_path(path)
return res
def serve_forever(port: int, ServerClass): def serve_forever(port: int, ServerClass):
handler = MyHTTPRequestHandler handler = MyHTTPRequestHandler
addr = ("0.0.0.0", port) addr = ("0.0.0.0", port)
HandlerClass = SimpleHTTPRequestHandler
with ServerClass(addr, handler) as httpd: with ServerClass(addr, handler) as httpd:
host, port = httpd.socket.getsockname()[:2] host, port = httpd.socket.getsockname()[:2]
url_host = f"[{host}]" if ":" in host else host url_host = f"[{host}]" if ":" in host else host
@ -53,8 +65,17 @@ def main():
parser = ArgumentParser(allow_abbrev=False) parser = ArgumentParser(allow_abbrev=False)
parser.add_argument("port", nargs="?", type=int, default=8080) parser.add_argument("port", nargs="?", type=int, default=8080)
parser.add_argument("-d", dest="directory", type=str, default=None) parser.add_argument("-d", dest="directory", type=str, default=None)
parser.add_argument("--map", dest="maps", nargs="+", type=str, help="Mappings, used as e.g. \"$HOME/projects/SDL:/sdl\"")
args = parser.parse_args() args = parser.parse_args()
maps = []
for m in args.maps:
try:
path, uri = m.split(":", 1)
except ValueError:
parser.error(f"Invalid mapping: \"{m}\"")
maps.append((path, uri))
class DualStackServer(ThreadingHTTPServer): class DualStackServer(ThreadingHTTPServer):
def server_bind(self): def server_bind(self):
# suppress exception when protocol is IPv4 # suppress exception when protocol is IPv4
@ -63,7 +84,13 @@ def main():
return super().server_bind() return super().server_bind()
def finish_request(self, request, client_address): def finish_request(self, request, client_address):
self.RequestHandlerClass(request, client_address, self, directory=args.directory) self.RequestHandlerClass(
request,
client_address,
self,
directory=args.directory,
maps=maps,
)
return serve_forever( return serve_forever(
port=args.port, port=args.port,