| Index: third_party/cherrypy/wsgiserver/ssl_builtin.py
|
| ===================================================================
|
| --- third_party/cherrypy/wsgiserver/ssl_builtin.py (revision 0)
|
| +++ third_party/cherrypy/wsgiserver/ssl_builtin.py (revision 0)
|
| @@ -0,0 +1,91 @@
|
| +"""A library for integrating Python's builtin ``ssl`` library with CherryPy.
|
| +
|
| +The ssl module must be importable for SSL functionality.
|
| +
|
| +To use this module, set ``CherryPyWSGIServer.ssl_adapter`` to an instance of
|
| +``BuiltinSSLAdapter``.
|
| +"""
|
| +
|
| +try:
|
| + import ssl
|
| +except ImportError:
|
| + ssl = None
|
| +
|
| +try:
|
| + from _pyio import DEFAULT_BUFFER_SIZE
|
| +except ImportError:
|
| + try:
|
| + from io import DEFAULT_BUFFER_SIZE
|
| + except ImportError:
|
| + DEFAULT_BUFFER_SIZE = -1
|
| +
|
| +import sys
|
| +
|
| +from cherrypy import wsgiserver
|
| +
|
| +
|
| +class BuiltinSSLAdapter(wsgiserver.SSLAdapter):
|
| + """A wrapper for integrating Python's builtin ssl module with CherryPy."""
|
| +
|
| + certificate = None
|
| + """The filename of the server SSL certificate."""
|
| +
|
| + private_key = None
|
| + """The filename of the server's private key file."""
|
| +
|
| + def __init__(self, certificate, private_key, certificate_chain=None):
|
| + if ssl is None:
|
| + raise ImportError("You must install the ssl module to use HTTPS.")
|
| + self.certificate = certificate
|
| + self.private_key = private_key
|
| + self.certificate_chain = certificate_chain
|
| +
|
| + def bind(self, sock):
|
| + """Wrap and return the given socket."""
|
| + return sock
|
| +
|
| + def wrap(self, sock):
|
| + """Wrap and return the given socket, plus WSGI environ entries."""
|
| + try:
|
| + s = ssl.wrap_socket(sock, do_handshake_on_connect=True,
|
| + server_side=True, certfile=self.certificate,
|
| + keyfile=self.private_key, ssl_version=ssl.PROTOCOL_SSLv23)
|
| + except ssl.SSLError:
|
| + e = sys.exc_info()[1]
|
| + if e.errno == ssl.SSL_ERROR_EOF:
|
| + # This is almost certainly due to the cherrypy engine
|
| + # 'pinging' the socket to assert it's connectable;
|
| + # the 'ping' isn't SSL.
|
| + return None, {}
|
| + elif e.errno == ssl.SSL_ERROR_SSL:
|
| + if e.args[1].endswith('http request'):
|
| + # The client is speaking HTTP to an HTTPS server.
|
| + raise wsgiserver.NoSSLError
|
| + elif e.args[1].endswith('unknown protocol'):
|
| + # The client is speaking some non-HTTP protocol.
|
| + # Drop the conn.
|
| + return None, {}
|
| + raise
|
| + return s, self.get_environ(s)
|
| +
|
| + # TODO: fill this out more with mod ssl env
|
| + def get_environ(self, sock):
|
| + """Create WSGI environ entries to be merged into each request."""
|
| + cipher = sock.cipher()
|
| + ssl_environ = {
|
| + "wsgi.url_scheme": "https",
|
| + "HTTPS": "on",
|
| + 'SSL_PROTOCOL': cipher[1],
|
| + 'SSL_CIPHER': cipher[0]
|
| +## SSL_VERSION_INTERFACE string The mod_ssl program version
|
| +## SSL_VERSION_LIBRARY string The OpenSSL program version
|
| + }
|
| + return ssl_environ
|
| +
|
| + if sys.version_info >= (3, 0):
|
| + def makefile(self, sock, mode='r', bufsize=DEFAULT_BUFFER_SIZE):
|
| + return wsgiserver.CP_makefile(sock, mode, bufsize)
|
| + else:
|
| + def makefile(self, sock, mode='r', bufsize=DEFAULT_BUFFER_SIZE):
|
| + return wsgiserver.CP_fileobject(sock, mode, bufsize)
|
| +
|
|
|
| Property changes on: third_party/cherrypy/wsgiserver/ssl_builtin.py
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|