server.py 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #!/usr/bin/env python
  2. # Based on http/server.py from Python
  3. from argparse import ArgumentParser
  4. from http.server import SimpleHTTPRequestHandler
  5. from socketserver import TCPServer
  6. def serve_forever(port: int, ServerClass):
  7. handler = SimpleHTTPRequestHandler
  8. handler.extensions_map = {
  9. ".manifest": "text/cache-manifest",
  10. ".html": "text/html",
  11. ".png": "image/png",
  12. ".jpg": "image/jpg",
  13. ".svg": "image/svg+xml",
  14. ".css": "text/css",
  15. ".js": "application/x-javascript",
  16. ".wasm": "application/wasm",
  17. "": "application/octet-stream",
  18. }
  19. addr = ("0.0.0.0", port)
  20. HandlerClass = SimpleHTTPRequestHandler
  21. with ServerClass(addr, handler) as httpd:
  22. host, port = httpd.socket.getsockname()[:2]
  23. url_host = f"[{host}]" if ":" in host else host
  24. print(
  25. f"Serving HTTP on {host} port {port} (http://{url_host}:{port}/) ..."
  26. )
  27. try:
  28. httpd.serve_forever()
  29. except KeyboardInterrupt:
  30. print("\nKeyboard interrupt received, exiting.")
  31. return 0
  32. def main():
  33. parser = ArgumentParser(allow_abbrev=False)
  34. parser.add_argument("port", nargs="?", type=int, default=8080)
  35. parser.add_argument("-d", dest="directory", type=str, default=None)
  36. args = parser.parse_args()
  37. import contextlib
  38. import http.server
  39. import socket
  40. class DualStackServer(http.server.ThreadingHTTPServer):
  41. def server_bind(self):
  42. # suppress exception when protocol is IPv4
  43. with contextlib.suppress(Exception):
  44. self.socket.setsockopt(
  45. socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
  46. return super().server_bind()
  47. def finish_request(self, request, client_address):
  48. self.RequestHandlerClass(request, client_address, self, directory=args.directory)
  49. return serve_forever(
  50. port=args.port,
  51. ServerClass=DualStackServer,
  52. )
  53. if __name__ == "__main__":
  54. raise SystemExit(main())