SDL

Форк
0
/
server.py 
102 строки · 3.1 Кб
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())
103

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.