diff options
author | 3gg <3gg@shellblade.net> | 2025-08-30 16:53:58 -0700 |
---|---|---|
committer | 3gg <3gg@shellblade.net> | 2025-08-30 16:53:58 -0700 |
commit | 6aaedb813fa11ba0679c3051bc2eb28646b9506c (patch) | |
tree | 34acbfc9840e02cb4753e6306ea7ce978bf8b58e /src/contrib/SDL-3.2.20/test/emscripten/server.py | |
parent | 8f228ade99dd3d4c8da9b78ade1815c9adf85c8f (diff) |
Update to SDL3
Diffstat (limited to 'src/contrib/SDL-3.2.20/test/emscripten/server.py')
-rwxr-xr-x | src/contrib/SDL-3.2.20/test/emscripten/server.py | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/contrib/SDL-3.2.20/test/emscripten/server.py b/src/contrib/SDL-3.2.20/test/emscripten/server.py new file mode 100755 index 0000000..103d164 --- /dev/null +++ b/src/contrib/SDL-3.2.20/test/emscripten/server.py | |||
@@ -0,0 +1,102 @@ | |||
1 | #!/usr/bin/env python | ||
2 | |||
3 | # Based on http/server.py from Python | ||
4 | |||
5 | from argparse import ArgumentParser | ||
6 | import contextlib | ||
7 | from http.server import SimpleHTTPRequestHandler | ||
8 | from http.server import ThreadingHTTPServer | ||
9 | import os | ||
10 | import socket | ||
11 | |||
12 | |||
13 | class MyHTTPRequestHandler(SimpleHTTPRequestHandler): | ||
14 | extensions_map = { | ||
15 | ".manifest": "text/cache-manifest", | ||
16 | ".html": "text/html", | ||
17 | ".png": "image/png", | ||
18 | ".jpg": "image/jpg", | ||
19 | ".svg": "image/svg+xml", | ||
20 | ".css": "text/css", | ||
21 | ".js": "application/x-javascript", | ||
22 | ".wasm": "application/wasm", | ||
23 | "": "application/octet-stream", | ||
24 | } | ||
25 | |||
26 | def __init__(self, *args, maps=None, **kwargs): | ||
27 | self.maps = maps or [] | ||
28 | SimpleHTTPRequestHandler.__init__(self, *args, **kwargs) | ||
29 | |||
30 | def end_headers(self): | ||
31 | self.send_my_headers() | ||
32 | SimpleHTTPRequestHandler.end_headers(self) | ||
33 | |||
34 | def send_my_headers(self): | ||
35 | self.send_header("Cache-Control", "no-cache, no-store, must-revalidate") | ||
36 | self.send_header("Pragma", "no-cache") | ||
37 | self.send_header("Expires", "0") | ||
38 | |||
39 | def translate_path(self, path): | ||
40 | for map_path, map_prefix in self.maps: | ||
41 | if path.startswith(map_prefix): | ||
42 | res = os.path.join(map_path, path.removeprefix(map_prefix).lstrip("/")) | ||
43 | break | ||
44 | else: | ||
45 | res = super().translate_path(path) | ||
46 | return res | ||
47 | |||
48 | |||
49 | def serve_forever(port: int, ServerClass): | ||
50 | handler = MyHTTPRequestHandler | ||
51 | |||
52 | addr = ("0.0.0.0", port) | ||
53 | with ServerClass(addr, handler) as httpd: | ||
54 | host, port = httpd.socket.getsockname()[:2] | ||
55 | url_host = f"[{host}]" if ":" in host else host | ||
56 | print(f"Serving HTTP on {host} port {port} (http://{url_host}:{port}/) ...") | ||
57 | try: | ||
58 | httpd.serve_forever() | ||
59 | except KeyboardInterrupt: | ||
60 | print("\nKeyboard interrupt received, exiting.") | ||
61 | return 0 | ||
62 | |||
63 | |||
64 | def main(): | ||
65 | parser = ArgumentParser(allow_abbrev=False) | ||
66 | parser.add_argument("port", nargs="?", type=int, default=8080) | ||
67 | parser.add_argument("-d", dest="directory", type=str, default=None) | ||
68 | parser.add_argument("--map", dest="maps", nargs="+", type=str, help="Mappings, used as e.g. \"$HOME/projects/SDL:/sdl\"") | ||
69 | args = parser.parse_args() | ||
70 | |||
71 | maps = [] | ||
72 | for m in args.maps: | ||
73 | try: | ||
74 | path, uri = m.split(":", 1) | ||
75 | except ValueError: | ||
76 | parser.error(f"Invalid mapping: \"{m}\"") | ||
77 | maps.append((path, uri)) | ||
78 | |||
79 | class DualStackServer(ThreadingHTTPServer): | ||
80 | def server_bind(self): | ||
81 | # suppress exception when protocol is IPv4 | ||
82 | with contextlib.suppress(Exception): | ||
83 | self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) | ||
84 | return super().server_bind() | ||
85 | |||
86 | def finish_request(self, request, client_address): | ||
87 | self.RequestHandlerClass( | ||
88 | request, | ||
89 | client_address, | ||
90 | self, | ||
91 | directory=args.directory, | ||
92 | maps=maps, | ||
93 | ) | ||
94 | |||
95 | return serve_forever( | ||
96 | port=args.port, | ||
97 | ServerClass=DualStackServer, | ||
98 | ) | ||
99 | |||
100 | |||
101 | if __name__ == "__main__": | ||
102 | raise SystemExit(main()) | ||