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