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
| import contextlib import os import socket import sys import argparse import traceback from functools import partial from http.server import BaseHTTPRequestHandler, CGIHTTPRequestHandler, SimpleHTTPRequestHandler, ThreadingHTTPServer
def _get_best_family(*address): infos = socket.getaddrinfo( *address, type=socket.SOCK_STREAM, flags=socket.AI_PASSIVE, ) family, type, proto, canonname, sockaddr = next(iter(infos)) return family, sockaddr
def test(HandlerClass=BaseHTTPRequestHandler, ServerClass=ThreadingHTTPServer, protocol="HTTP/1.0", port=8000, bind=None): """Test the HTTP request handler class.
This runs an HTTP server on port 8000 (or the port argument).
""" ServerClass.address_family, addr = _get_best_family(bind, port)
HandlerClass.protocol_version = protocol with ServerClass(addr, HandlerClass) as httpd: host, port = httpd.socket.getsockname()[:2] url_host = f'[{host}]' if ':' in host else host print( f"Serving HTTP on {host} port {port} " f"(http://{url_host}:{port}/) ..." ) try: httpd.serve_forever() except KeyboardInterrupt: print("\nKeyboard interrupt received, exiting.") sys.exit(0)
def runserver(port=8000): parser = argparse.ArgumentParser() parser.add_argument('--cgi', action='store_true', help='Run as CGI Server') parser.add_argument('--bind', '-b', metavar='ADDRESS', help='Specify alternate bind address ' '[default: all interfaces]') parser.add_argument('--directory', '-d', default=os.getcwd(), help='Specify alternative directory ' '[default:current directory]') parser.add_argument('port', action='store', default=port, type=int, nargs='?', help='Specify alternate port [default: 8000]') args = parser.parse_args() if args.cgi: handler_class = CGIHTTPRequestHandler else: handler_class = partial(SimpleHTTPRequestHandler, directory=args.directory)
class DualStackServer(ThreadingHTTPServer): def server_bind(self): with contextlib.suppress(Exception): self.socket.setsockopt( socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) return super().server_bind()
test( HandlerClass=handler_class, ServerClass=DualStackServer, port=args.port, bind=args.bind, )
def get_host_ip(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: s.connect(('8.8.8.8', 80)) ip = s.getsockname()[0] finally: s.close() return ip
if __name__ == '__main__': print(""" 使用说明: 1.请确保该路径以及子路径没有 --敏感文件-- 2.仅限局域网访问(比如大家都连接同一个路由器) 3.共享路径是运行该程序的文件夹,局域网内所有人都能访问和下载文件 """) print("共享路径: {}".format(os.getcwd())) port = 80 try: ip = get_host_ip() print("启动程序成功") print("请在浏览器访问URL:{}".format(ip)) runserver(port) except Exception as e: print("启动程序失败:{}".format(traceback.format_exc()))
|