Package cherrypy :: Package wsgiserver :: Module ssl_builtin
[hide private]
[frames] | no frames]

Source Code for Module cherrypy.wsgiserver.ssl_builtin

 1  """A library for integrating Python's builtin ``ssl`` library with CherryPy. 
 2   
 3  The ssl module must be importable for SSL functionality. 
 4   
 5  To use this module, set ``CherryPyWSGIServer.ssl_adapter`` to an instance of 
 6  ``BuiltinSSLAdapter``. 
 7  """ 
 8   
 9  try: 
10      import ssl 
11  except ImportError: 
12      ssl = None 
13   
14  try: 
15      from _pyio import DEFAULT_BUFFER_SIZE 
16  except ImportError: 
17      try: 
18          from io import DEFAULT_BUFFER_SIZE 
19      except ImportError: 
20          DEFAULT_BUFFER_SIZE = -1 
21   
22  import sys 
23   
24  from cherrypy import wsgiserver 
25   
26   
27 -class BuiltinSSLAdapter(wsgiserver.SSLAdapter):
28 """A wrapper for integrating Python's builtin ssl module with CherryPy.""" 29 30 certificate = None 31 """The filename of the server SSL certificate.""" 32 33 private_key = None 34 """The filename of the server's private key file.""" 35
36 - def __init__(self, certificate, private_key, certificate_chain=None):
37 if ssl is None: 38 raise ImportError("You must install the ssl module to use HTTPS.") 39 self.certificate = certificate 40 self.private_key = private_key 41 self.certificate_chain = certificate_chain
42
43 - def bind(self, sock):
44 """Wrap and return the given socket.""" 45 return sock
46
47 - def wrap(self, sock):
48 """Wrap and return the given socket, plus WSGI environ entries.""" 49 try: 50 s = ssl.wrap_socket(sock, do_handshake_on_connect=True, 51 server_side=True, certfile=self.certificate, 52 keyfile=self.private_key, ssl_version=ssl.PROTOCOL_SSLv23) 53 except ssl.SSLError: 54 e = sys.exc_info()[1] 55 if e.errno == ssl.SSL_ERROR_EOF: 56 # This is almost certainly due to the cherrypy engine 57 # 'pinging' the socket to assert it's connectable; 58 # the 'ping' isn't SSL. 59 return None, {} 60 elif e.errno == ssl.SSL_ERROR_SSL: 61 if e.args[1].endswith('http request'): 62 # The client is speaking HTTP to an HTTPS server. 63 raise wsgiserver.NoSSLError 64 elif e.args[1].endswith('unknown protocol'): 65 # The client is speaking some non-HTTP protocol. 66 # Drop the conn. 67 return None, {} 68 raise 69 return s, self.get_environ(s)
70 71 # TODO: fill this out more with mod ssl env
72 - def get_environ(self, sock):
73 """Create WSGI environ entries to be merged into each request.""" 74 cipher = sock.cipher() 75 ssl_environ = { 76 "wsgi.url_scheme": "https", 77 "HTTPS": "on", 78 'SSL_PROTOCOL': cipher[1], 79 'SSL_CIPHER': cipher[0] 80 ## SSL_VERSION_INTERFACE string The mod_ssl program version 81 ## SSL_VERSION_LIBRARY string The OpenSSL program version 82 } 83 return ssl_environ
84 85 if sys.version_info >= (3, 0):
86 - def makefile(self, sock, mode='r', bufsize=DEFAULT_BUFFER_SIZE):
87 return wsgiserver.CP_makefile(sock, mode, bufsize)
88 else:
89 - def makefile(self, sock, mode='r', bufsize=DEFAULT_BUFFER_SIZE):
90 return wsgiserver.CP_fileobject(sock, mode, bufsize)
91