Friday, January 3, 2014

Bottle with SSL

Bottle with SSL

I was looking into using the bottle python web framework with SSL, and came across a few links on Google. They all seemed to use other third party modules for adding SSL support, and when I came across this post explaining how to add SSL to the built-in SimpleHTTPServer, I wondered if the same could be done with bottle.

It can. We just need to create a custom bottle.ServerAdapter which wraps the socket with ssl. The following should create a very basic SSL server using bottle (you need to create a ssl certificate first, I'm assuming it's called 'server.pem' in the following):

# Trying SSL with bottle
# ie combo of http://www.piware.de/2011/01/creating-an-https-server-in-python/
# and http://dgtool.blogspot.com/2011/12/ssl-encryption-in-python-bottle.html
# without cherrypy?
# requires ssl

# to create a server certificate, run eg
# openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
# DON'T distribute this combined private/public key to clients!
# (see http://www.piware.de/2011/01/creating-an-https-server-in-python/#comment-11380)
from bottle import Bottle, get, run, ServerAdapter

# copied from bottle. Only changes are to import ssl and wrap the socket
class SSLWSGIRefServer(ServerAdapter):
    def run(self, handler):
        from wsgiref.simple_server import make_server, WSGIRequestHandler
        import ssl
        if self.quiet:
            class QuietHandler(WSGIRequestHandler):
                def log_request(*args, **kw): pass
            self.options['handler_class'] = QuietHandler
        srv = make_server(self.host, self.port, handler, **self.options)
        srv.socket = ssl.wrap_socket (
         srv.socket,
         certfile='server.pem',  # path to certificate
         server_side=True)
        srv.serve_forever()

@get("/x")
def get_x():
 return "Hi there"

#instead of:
#run(host="0.0.0.0", port=8090)
#we use:
srv = SSLWSGIRefServer(host="0.0.0.0", port=8090)
run(server=srv)

And that's it. You should now be able to go to https://localhost:8090/x and see 'Hi there'. The file's also available on github.

10 comments:

  1. thanks, Matt, I'll try this when the hardware's up and running.
    love
    Dad

    ReplyDelete
  2. very good !
    but redirections are made on http and not https...

    ReplyDelete
    Replies
    1. Check this out: https://pypi.python.org/pypi/Bottle-SSLify/0.0.1

      Delete
  3. I am just new to this, but can we add that adapter to bottle, then what would the script look like to call up the adapter.

    I had a go, but got lots of errors so probably way off.

    Thanks

    ReplyDelete
    Replies
    1. I submitted a pull request to add this to Bottle, but Bottle would prefer not to promise SSL support if it's not completely reliable. See here for details: https://github.com/bottlepy/bottle/pull/647#issuecomment-60152870

      Delete
  4. This comment has been removed by the author.

    ReplyDelete
  5. Very Good example , works very well, thank you very much !

    ReplyDelete
  6. I had a problem using this code where I could access my site via a web browser, but curl and python requests would give me certificate errors even though I had an officially signed certificate. I ended up using this instead: http://codegist.net/snippet/python/bottle-sslpy_tiagohillebrandt_python

    ReplyDelete
  7. Worked like a charm! thank you very much.

    ReplyDelete