Created
October 12, 2016 17:04
-
-
Save mjumbewu/bd4fe0642464e22e2d047fb27cabdfc1 to your computer and use it in GitHub Desktop.
An extension to Python3's http.server module that allows creation of HTTPS servers. Inspired by @dergachev's even simpler https://gist.github.com/dergachev/7028596.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
An extension to Python3's http.server module that allows creation of HTTPS | |
servers. Inspired by @dergachev's https://gist.github.com/dergachev/7028596. | |
You can either use a separate certificate and key file: | |
python3 https_server.py -c server.crt -k server.key | |
Or generate a PEM file and use it as the certificate: | |
openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes | |
python https_server.py -c server.pem | |
""" | |
import argparse | |
from http.server import (HTTPServer, test, | |
CGIHTTPRequestHandler, SimpleHTTPRequestHandler) | |
from ssl import wrap_socket | |
def HTTPSServer_class_factory(certfile, keyfile=None): | |
""" | |
Create an HTTPSServer class that wraps an HTTPServer socket in an SSL | |
context. See https://docs.python.org/3/library/ssl.html#socket-creation | |
for more information. | |
""" | |
class CertifiedHTTPSServer (HTTPSServer): | |
def __init__(self, *args, **kwargs): | |
super().__init__(*args, **kwargs) | |
self.socket = wrap_socket(self.socket, certfile=certfile, keyfile=keyfile, server_side=True) | |
return CertifiedHTTPSServer | |
if __name__ == '__main__': | |
# NOTE: Most of the following parser arguments are copied from http.server. | |
# The exceptions are --certfile and --keyfile, which affect which server | |
# class is passed to the test server function | |
parser = argparse.ArgumentParser() | |
parser.add_argument('--cgi', action='store_true', | |
help='Run as CGI Server') | |
parser.add_argument('--bind', '-b', default='', metavar='ADDRESS', | |
help='Specify alternate bind address ' | |
'[default: all interfaces]') | |
parser.add_argument('port', action='store', | |
default=8000, type=int, | |
nargs='?', | |
help='Specify alternate port [default: 8000]') | |
parser.add_argument('--certfile', '-c', action='store', default=None, | |
nargs='?', help='Specify an SSL certificate to serve ' | |
'requests over HTTPS [default: None]') | |
parser.add_argument('--keyfile', '-k', action='store', default=None, | |
nargs='?', help='Specify an SSL certificate to serve ' | |
'requests over HTTPS [default: None]') | |
args = parser.parse_args() | |
if args.cgi: | |
handler_class = CGIHTTPRequestHandler | |
else: | |
handler_class = SimpleHTTPRequestHandler | |
if args.certfile: | |
server_class = HTTPSServer_class_factory(args.certfile, args.keyfile) | |
else: | |
server_class = HTTPServer | |
test(HandlerClass=handler_class, ServerClass=server_class, port=args.port, bind=args.bind) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment