1 """A library for integrating Python's builtin ``ssl`` library with CherryPy.
3 The ssl module must be importable for SSL functionality.
5 To use this module, set ``CherryPyWSGIServer.ssl_adapter`` to an instance of
14 from cherrypy
import wsgiserver
17 class BuiltinSSLAdapter(wsgiserver
.SSLAdapter
):
18 """A wrapper for integrating Python's builtin ssl module with CherryPy."""
21 """The filename of the server SSL certificate."""
24 """The filename of the server's private key file."""
26 def __init__(self
, certificate
, private_key
, certificate_chain
=None):
28 raise ImportError("You must install the ssl module to use HTTPS.")
29 self
.certificate
= certificate
30 self
.private_key
= private_key
31 self
.certificate_chain
= certificate_chain
34 """Wrap and return the given socket."""
38 """Wrap and return the given socket, plus WSGI environ entries."""
40 s
= ssl
.wrap_socket(sock
, do_handshake_on_connect
=True,
41 server_side
=True, certfile
=self
.certificate
,
42 keyfile
=self
.private_key
, ssl_version
=ssl
.PROTOCOL_SSLv23
)
43 except ssl
.SSLError
, e
:
44 if e
.errno
== ssl
.SSL_ERROR_EOF
:
45 # This is almost certainly due to the cherrypy engine
46 # 'pinging' the socket to assert it's connectable;
47 # the 'ping' isn't SSL.
49 elif e
.errno
== ssl
.SSL_ERROR_SSL
:
50 if e
.args
[1].endswith('http request'):
51 # The client is speaking HTTP to an HTTPS server.
52 raise wsgiserver
.NoSSLError
54 return s
, self
.get_environ(s
)
56 # TODO: fill this out more with mod ssl env
57 def get_environ(self
, sock
):
58 """Create WSGI environ entries to be merged into each request."""
59 cipher
= sock
.cipher()
61 "wsgi.url_scheme": "https",
63 'SSL_PROTOCOL': cipher
[1],
64 'SSL_CIPHER': cipher
[0]
65 ## SSL_VERSION_INTERFACE string The mod_ssl program version
66 ## SSL_VERSION_LIBRARY string The OpenSSL program version
70 def makefile(self
, sock
, mode
='r', bufsize
=-1):
71 return wsgiserver
.CP_fileobject(sock
, mode
, bufsize
)