Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/platform/web/serve.py
10277 views
1
#!/usr/bin/env python3
2
3
import argparse
4
import contextlib
5
import os
6
import socket
7
import subprocess
8
import sys
9
from http.server import HTTPServer, SimpleHTTPRequestHandler
10
from pathlib import Path
11
12
13
# See cpython GH-17851 and GH-17864.
14
class DualStackServer(HTTPServer):
15
def server_bind(self):
16
# Suppress exception when protocol is IPv4.
17
with contextlib.suppress(Exception):
18
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
19
return super().server_bind()
20
21
22
class CORSRequestHandler(SimpleHTTPRequestHandler):
23
def end_headers(self):
24
self.send_header("Cross-Origin-Opener-Policy", "same-origin")
25
self.send_header("Cross-Origin-Embedder-Policy", "require-corp")
26
self.send_header("Access-Control-Allow-Origin", "*")
27
super().end_headers()
28
29
30
def shell_open(url):
31
if sys.platform == "win32":
32
os.startfile(url)
33
else:
34
opener = "open" if sys.platform == "darwin" else "xdg-open"
35
subprocess.call([opener, url])
36
37
38
def serve(root, port, run_browser):
39
os.chdir(root)
40
41
address = ("", port)
42
httpd = DualStackServer(address, CORSRequestHandler)
43
44
url = f"http://127.0.0.1:{port}"
45
if run_browser:
46
# Open the served page in the user's default browser.
47
print(f"Opening the served URL in the default browser (use `--no-browser` or `-n` to disable this): {url}")
48
shell_open(url)
49
else:
50
print(f"Serving at: {url}")
51
52
try:
53
httpd.serve_forever()
54
except KeyboardInterrupt:
55
print("\nKeyboard interrupt received, stopping server.")
56
finally:
57
# Clean-up server
58
httpd.server_close()
59
60
61
if __name__ == "__main__":
62
parser = argparse.ArgumentParser()
63
parser.add_argument("-p", "--port", help="port to listen on", default=8060, type=int)
64
parser.add_argument(
65
"-r", "--root", help="path to serve as root (relative to `platform/web/`)", default="../../bin", type=Path
66
)
67
browser_parser = parser.add_mutually_exclusive_group(required=False)
68
browser_parser.add_argument(
69
"-n", "--no-browser", help="don't open default web browser automatically", dest="browser", action="store_false"
70
)
71
parser.set_defaults(browser=True)
72
args = parser.parse_args()
73
74
# Change to the directory where the script is located,
75
# so that the script can be run from any location.
76
os.chdir(Path(__file__).resolve().parent)
77
78
serve(args.root, args.port, args.browser)
79
80