|
@@ -6,8 +6,8 @@ from argparse import ArgumentParser
|
|
|
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 @@ class MyHTTPRequestHandler(SimpleHTTPRequestHandler):
|
|
|
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 main():
|
|
|
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,
|