Skip to content

Instantly share code, notes, and snippets.

Created February 10, 2018 16:31
Show Gist options
  • Save anonymous/9c5e5c3c26402655dbadcfb742b72648 to your computer and use it in GitHub Desktop.
Save anonymous/9c5e5c3c26402655dbadcfb742b72648 to your computer and use it in GitHub Desktop.
Python script to serve an arbitrary directory over HTTPS
#!/usr/bin/env python
"""
This script can be used to serve an arbitrary directory over HTTPS.
It supports autogenerating a self-signed certificate via openssl.
Basic Usage: python serve_https.py <directory>
See full options via: python serve_https.py -h
"""
from __future__ import absolute_import, division, print_function
import argparse
try:
from http.server import HTTPServer, SimpleHTTPRequestHandler
except ImportError:
# py2 compat imports
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
import ssl
import sys
import subprocess
import os
def main():
parser = argparse.ArgumentParser()
parser.add_argument('directory', action='store', nargs='?',
help="Path to directory to serve")
parser.add_argument('--cert', '-c', action='store', default="./server.pem",
help="Path to server combine key+cert file [default: %(default)s]")
parser.add_argument('--auto-create-cert', '-a', action='store_true', default=False,
help="Auto-create self signed certificate if needed")
parser.add_argument('--bind', '-b', default='', metavar='ADDRESS',
help='Specify alternate bind address (default: <all interfaces>)')
parser.add_argument('--port', '-p', action='store', default=4443, type=int,
help='Specify alternate port(default: %(default)s)')
args = parser.parse_args()
cert = os.path.abspath(args.cert)
if not os.path.exists(cert):
print("Cert file not found:", cert)
if not args.auto_create_cert:
print("Either create cert file manually, or pass '-a' to auto create this file")
sys.exit(2)
print("Calling openssl to generate self-signed certificate")
cmd = ["openssl", "req", "-new", "-x509", "-keyout", cert, "-out", cert,
"-days", "365", "-nodes", "-batch", "-subj", "/CN=localhost"]
subprocess.check_call(cmd)
httpd = HTTPServer((args.bind, args.port), SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket, certfile=args.cert, server_side=True)
path = os.path.abspath(args.directory)
os.chdir(path)
print("Serving directory:", path)
sa = httpd.socket.getsockname()
if sa[0] in ["127.0.0.1", "0.0.0.0"]:
host = "localhost"
if sa[0] == "0.0.0.0":
print("Serving on all interfaces")
else:
host = sa[0]
print("Connect via https://%s:%s" % (host, sa[1]))
print("Ctrl-C to exit ...")
try:
httpd.serve_forever()
except KeyboardInterrupt:
print("\nKeyboard interrupt received, exiting.")
httpd.server_close()
sys.exit(0)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment