-
Notifications
You must be signed in to change notification settings - Fork 5
/
server.py
executable file
·138 lines (106 loc) · 3.98 KB
/
server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/env python
import sys
import mimetypes
mimetypes.init()
if ".wasm" not in mimetypes.types_map:
print(
"WARNING: wasm mimetype unsupported on that system, trying to correct",
file=sys.stderr,
)
mimetypes.types_map[".wasm"] = "application/wasm"
import argparse
from http import server, HTTPStatus
import io
import os
import urllib
import urllib.request
from pathlib import Path
import hashlib
CWD = os.getcwd()
parser = argparse.ArgumentParser(
description="Start a local webserver with a Python terminal."
)
parser.add_argument(
"--port", type=int, default=8000, help="port for the http server to listen on"
)
args = parser.parse_args()
CACHE = Path("cache")
CACHE.mkdir(parents=True, exist_ok=True)
class MyHTTPRequestHandler(server.SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header("Access-Control-Allow-Origin", "*")
self.send_header("Cross-Origin-Opener-Policy", "unsafe-none")
self.send_header("Cross-Origin-Embedder-Policy", "unsafe-none")
self.send_header("Origin-Agent-Cluster", "?1")
super().end_headers()
def do_GET(self):
f = self.send_head()
if f:
try:
self.copyfile(f, self.wfile)
finally:
f.close()
def do_HEAD(self):
f = self.send_head()
if f:
f.close()
def send_head(self):
path = self.translate_path(self.path)
ctype = self.guess_type(path)
content = b''
def flush():
nonlocal ctype
nonlocal content
self.send_header("content-type", ctype)
self.send_header("content-length", str(len(content)))
self.end_headers()
return io.BytesIO(content)
if self.path.endswith('.map'):
self.send_response(404)
self.send_header("content-length", 0)
self.end_headers()
return io.BytesIO(b'')
if os.path.isdir(path):
parts = urllib.parse.urlsplit(self.path)
if not parts.path.endswith("/"):
# redirect browser - doing basically what apache does
self.send_response(HTTPStatus.MOVED_PERMANENTLY)
new_parts = (parts[0], parts[1], parts[2] + "/", parts[3], parts[4])
new_url = urllib.parse.urlunsplit(new_parts)
self.send_header("Location", new_url)
self.end_headers()
return None
for index in "index.html", "index.htm":
index = os.path.join(path, index)
if os.path.exists(index):
path = index
break
else:
return self.list_directory(path)
if not Path(path).is_file():
self.send_response(404)
return flush()
self.send_response(HTTPStatus.OK)
if self.path.startswith('/cors/'):
ctype = 'text/plain; charset=utf-8'
target = self.path[6:]
print("CORS:", target)
cache = CACHE / hashlib.md5(target.encode()).hexdigest()
if cache.is_file():
path = cache
else:
if target.startswith('https://paste.pythondiscord.com/'):
if not target.count('/raw/'):
target = target.replace('https://paste.pythondiscord.com/','https://paste.pythondiscord.com/raw/',1)
else:
content = f'print("Unsupported paste service")'.encode()
return flush()
path, headers = urllib.request.urlretrieve(target, cache)
with open(path, "rb") as file:
content = file.read()
if Path(path).suffix in [".html"]:
content = content.replace(
b"https://pygame-web.github.io/", b"http://localhost:8000/"
)
return flush()
server.test(HandlerClass=MyHTTPRequestHandler, protocol="HTTP/1.1", port=args.port)