123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- #!/usr/bin/env python3
- import argparse
- import contextlib
- import os
- import socket
- import subprocess
- import sys
- from http.server import HTTPServer, SimpleHTTPRequestHandler, test # type: ignore
- from pathlib import Path
- # See cpython GH-17851 and GH-17864.
- class DualStackServer(HTTPServer):
- def server_bind(self):
- # Suppress exception when protocol is IPv4.
- with contextlib.suppress(Exception):
- self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
- return super().server_bind()
- class CORSRequestHandler(SimpleHTTPRequestHandler):
- def end_headers(self):
- self.send_header("Cross-Origin-Opener-Policy", "same-origin")
- self.send_header("Cross-Origin-Embedder-Policy", "require-corp")
- self.send_header("Access-Control-Allow-Origin", "*")
- super().end_headers()
- def shell_open(url):
- if sys.platform == "win32":
- os.startfile(url)
- else:
- opener = "open" if sys.platform == "darwin" else "xdg-open"
- subprocess.call([opener, url])
- def serve(root, port, run_browser):
- os.chdir(root)
- if run_browser:
- # Open the served page in the user's default browser.
- print("Opening the served URL in the default browser (use `--no-browser` or `-n` to disable this).")
- shell_open(f"http://127.0.0.1:{port}")
- test(CORSRequestHandler, DualStackServer, port=port)
- if __name__ == "__main__":
- parser = argparse.ArgumentParser()
- parser.add_argument("-p", "--port", help="port to listen on", default=8060, type=int)
- parser.add_argument(
- "-r", "--root", help="path to serve as root (relative to `platform/web/`)", default="../../bin", type=Path
- )
- browser_parser = parser.add_mutually_exclusive_group(required=False)
- browser_parser.add_argument(
- "-n", "--no-browser", help="don't open default web browser automatically", dest="browser", action="store_false"
- )
- parser.set_defaults(browser=True)
- args = parser.parse_args()
- # Change to the directory where the script is located,
- # so that the script can be run from any location.
- os.chdir(Path(__file__).resolve().parent)
- serve(args.root, args.port, args.browser)
|