From 12db9ba0e1b06bc594094ab5790dded82ab93a5e Mon Sep 17 00:00:00 2001 From: Anthony Metzidis Date: Tue, 26 Dec 2017 16:36:45 -0800 Subject: [PATCH] support ssl in pelican.server with --ssl, --cert & --key --- .gitignore | 3 +++ docs/tips.rst | 22 ++++++++++++++++++++++ pelican/server.py | 42 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 1ae0e9f6..45946946 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,6 @@ tags htmlcov six-*.egg/ *.orig +venv +samples/output +*.pem diff --git a/docs/tips.rst b/docs/tips.rst index 50160380..4e89d148 100644 --- a/docs/tips.rst +++ b/docs/tips.rst @@ -147,3 +147,25 @@ embed videos in the markup. You can use `reST video directive `_ for reST or `mdx_video plugin `_ for Markdown. + +Develop Locally Using SSL +================================== + +Here's how you can set up your local pelican server to support SSL. + +First, create a self-signed certificate and key using ``openssl`` (this creates ``cert.pem`` and ``key.pem``):: + + $ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes + +And use this command to launch the server (the server starts within your ``output`` directory):: + + python -m pelican.server 8443 --key=../key.pem --cert=../cert.pem + +If you are using ``develop-server.sh``, add this to the top:: + + CERT="$BASEDIR/cert.pem" + KEY="$BASEDIR/key.pem" + +and modify the ``pelican.server`` line as follows:: + + $PY -m pelican.server $port --ssl --cert="$CERT" --key="$KEY" & \ No newline at end of file diff --git a/pelican/server.py b/pelican/server.py index ad68a3bc..7e74421b 100644 --- a/pelican/server.py +++ b/pelican/server.py @@ -1,8 +1,10 @@ # -*- coding: utf-8 -*- from __future__ import print_function, unicode_literals +import argparse import logging import os +import ssl import sys try: @@ -14,6 +16,26 @@ from six.moves import SimpleHTTPServer as srvmod from six.moves import socketserver +def parse_arguments(): + parser = argparse.ArgumentParser( + description='Pelican Development Server', + formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + parser.add_argument("port", default=8000, type=int, nargs="?", + help="Port to Listen On") + parser.add_argument("server", default="", nargs="?", + help="Interface to Listen On") + parser.add_argument('--ssl', action="store_true", + help='Activate SSL listener') + parser.add_argument('--cert', default="./cert.pem", nargs="?", + help='Path to certificate file. ' + + 'Relative to current directory') + parser.add_argument('--key', default="./key.pem", nargs="?", + help='Path to certificate key file. ' + + 'Relative to current directory') + return parser.parse_args() + + class ComplexHTTPRequestHandler(srvmod.SimpleHTTPRequestHandler): SUFFIXES = ['', '.html', '/index.html'] @@ -55,18 +77,26 @@ class ComplexHTTPRequestHandler(srvmod.SimpleHTTPRequestHandler): if __name__ == '__main__': - PORT = len(sys.argv) in (2, 3) and int(sys.argv[1]) or 8000 - SERVER = len(sys.argv) == 3 and sys.argv[2] or "" - + args = parse_arguments() socketserver.TCPServer.allow_reuse_address = True try: httpd = socketserver.TCPServer( - (SERVER, PORT), ComplexHTTPRequestHandler) + (args.server, args.port), + ComplexHTTPRequestHandler) + if args.ssl: + httpd.socket = ssl.wrap_socket( + httpd.socket, keyfile=args.key, + certfile=args.cert, server_side=True) + except ssl.SSLError as e: + logging.error("Couldn't open certificate file %s or key file %s", + args.cert, args.key) except OSError as e: - logging.error("Could not listen on port %s, server %s.", PORT, SERVER) + logging.error("Could not listen on port %s, server %s.", + args.port, args.server) sys.exit(getattr(e, 'exitcode', 1)) - logging.info("Serving at port %s, server %s.", PORT, SERVER) + logging.info("Serving at port %s, server %s.", + args.port, args.server) try: httpd.serve_forever() except KeyboardInterrupt as e: