SDL: test: map URL to other directories

From 3fccb77da64b17781a90fdf24258d390a5dc2fee Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Thu, 30 May 2024 20:30:36 +0200
Subject: [PATCH] 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.
---
 test/emscripten/server.py | 33 ++++++++++++++++++++++++++++++---
 1 file changed, 30 insertions(+), 3 deletions(-)

diff --git a/test/emscripten/server.py b/test/emscripten/server.py
index 7787e3b9e4882..103d1645c0ac7 100755
--- a/test/emscripten/server.py
+++ b/test/emscripten/server.py
@@ -6,8 +6,8 @@
 import contextlib
 from http.server import SimpleHTTPRequestHandler
 from http.server import ThreadingHTTPServer
+import os
 import socket
-from socketserver import TCPServer
 
 
 class MyHTTPRequestHandler(SimpleHTTPRequestHandler):
@@ -23,6 +23,10 @@ class MyHTTPRequestHandler(SimpleHTTPRequestHandler):
         "": "application/octet-stream",
     }
 
+    def __init__(self, *args, maps=None, **kwargs):
+        self.maps = maps or []
+        SimpleHTTPRequestHandler.__init__(self, *args, **kwargs)
+
     def end_headers(self):
         self.send_my_headers()
         SimpleHTTPRequestHandler.end_headers(self)
@@ -32,12 +36,20 @@ def send_my_headers(self):
         self.send_header("Pragma", "no-cache")
         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):
     handler = MyHTTPRequestHandler
 
     addr = ("0.0.0.0", port)
-    HandlerClass = SimpleHTTPRequestHandler
     with ServerClass(addr, handler) as httpd:
         host, port = httpd.socket.getsockname()[:2]
         url_host = f"[{host}]" if ":" in host else host
@@ -53,8 +65,17 @@ def main():
     parser = ArgumentParser(allow_abbrev=False)
     parser.add_argument("port", nargs="?", type=int, default=8080)
     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()
 
+    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):
         def server_bind(self):
             # suppress exception when protocol is IPv4
@@ -63,7 +84,13 @@ def server_bind(self):
             return super().server_bind()
 
         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(
         port=args.port,