#!/usr/bin/env python3 import sys, os import http.server import ssl import subprocess import tempfile from http.server import SimpleHTTPRequestHandler def setup_options(): """Create command line options""" from argparse import ArgumentParser parser = ArgumentParser() parser.add_argument( "-s", dest="ssl", default=False, action="store_true", help="Enable self signed SSL (Default: %(default)s)", ) parser.add_argument( "-p", type=int, dest="port", default=8000, help="Server port (Default: %(default)s)", ) parser.add_argument( "-a", type=str, dest="address", default="", help="Server bind address. Use localhost for privacy. Defaults to all interfaces.", ) parser.add_argument( "rootpath", type=str, action="store", default=os.path.abspath("."), nargs="?", help="Root path of the server", ) options = parser.parse_args() if not os.path.exists(options.rootpath): parser.error("Path does not exist") options.rootpath = os.path.abspath(options.rootpath) return options def makekey(): tf = tempfile.NamedTemporaryFile(delete=False) tf.close p = subprocess.run( "openssl req -new -x509 -keyout {tf} -out {tf} -days 365 -subj /CN=localhost -nodes".format( tf=tf.name ), shell=True, ) return tf.name def serve(options): """Run the web server""" HandlerClass = SimpleHTTPRequestHandler ServerClass = http.server.HTTPServer Protocol = "HTTP/1.0" server_address = (options.address, options.port) os.chdir(options.rootpath) HandlerClass.protocol_version = Protocol httpd = ServerClass(server_address, HandlerClass) ssl_char = "" if options.ssl: keyfile = makekey() httpd.socket = ssl.wrap_socket(httpd.socket, server_side=True, certfile=keyfile) ssl_char = "s" sa = httpd.socket.getsockname() print("Serving http{}://{}:{}/".format(ssl_char, sa[0], str(sa[1]))) try: httpd.serve_forever() except KeyboardInterrupt: httpd.server_close() except OSError: httpd.server_close() if options.ssl: os.remove(keyfile) if __name__ == "__main__": options = setup_options() serve(options)