From 13ef629ec4ae03d3f02c4ffaa71dbc16193e4d7d Mon Sep 17 00:00:00 2001 From: pjkersha Date: Fri, 17 Aug 2012 11:50:12 +0000 Subject: [PATCH] git-svn-id: http://proj.badc.rl.ac.uk/svn/ndg-security/trunk/ndg_httpsclient@8096 051b1e3e-aa0c-0410-b6c2-bfbade6052be --- ndg/httpsclient/https.py | 2 +- ndg/httpsclient/ssl_socket.py | 29 ++++++++++++++++++++++------- ndg/httpsclient/utils.py | 2 +- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/ndg/httpsclient/https.py b/ndg/httpsclient/https.py index 3f4aa65..f7a9bdf 100644 --- a/ndg/httpsclient/https.py +++ b/ndg/httpsclient/https.py @@ -83,7 +83,7 @@ def close(self): """Close socket and shut down SSL connection""" self.sock.close() - + class HTTPSContextHandler(AbstractHTTPHandler): '''HTTPS handler that allows a SSL context to be set for the SSL connections. diff --git a/ndg/httpsclient/ssl_socket.py b/ndg/httpsclient/ssl_socket.py index abb79f0..e735ed7 100644 --- a/ndg/httpsclient/ssl_socket.py +++ b/ndg/httpsclient/ssl_socket.py @@ -46,6 +46,7 @@ def __init__(self, ctx, sock=None): self.__ssl_conn = SSL.Connection(ctx, self.socket) self.buf_size = self.__class__.default_buf_size + self._makefile_refs = 0 def __del__(self): """Close underlying socket when this object goes out of scope @@ -68,13 +69,16 @@ def buf_size(self, value): def close(self): """Shutdown the SSL connection and call the close method of the underlying socket""" - try: +# try: +# self.__ssl_conn.shutdown() +# except SSL.Error: +# # Make errors on shutdown non-fatal +# pass + + if self._makefile_refs < 1: self.__ssl_conn.shutdown() - except SSL.Error: - # Make errors on shutdown non-fatal - pass - - self.__ssl_conn.close() + else: + self._makefile_refs -= 1 def set_shutdown(self, mode): """Set the shutdown state of the Connection. @@ -212,7 +216,7 @@ def state_string(self): """Return the SSL state of this connection.""" return self.__ssl_conn.state_string() - def makefile(self, *args): + def _DEPRECATE_makefile(self, *args): """Specific to Python socket API and required by httplib: convert response into a file-like object. This implementation reads using recv and copies the output into a StringIO buffer to simulate a file object @@ -256,6 +260,17 @@ def makefile(self, *args): return stream + def makefile(self, mode='r', bufsize=-1): + + """Make and return a file-like object that + works with the SSL connection. Just use the code + from the socket module.""" + + self._makefile_refs += 1 + # close=True so as to decrement the reference count when done with + # the file-like object. + return socket._fileobject(self.socket, mode, bufsize, close=True) + def getsockname(self): """ @return: the socket's own address diff --git a/ndg/httpsclient/utils.py b/ndg/httpsclient/utils.py index c25fd22..14c431f 100644 --- a/ndg/httpsclient/utils.py +++ b/ndg/httpsclient/utils.py @@ -160,7 +160,7 @@ def open_url(url, config, data=None): handlers.append(urllib2.ProxyHandler(config.proxies)) log.debug("Configuring proxies: %s" % config.proxies) - opener = build_opener(config.ssl_context, *handlers) + opener = build_opener(*handlers, ssl_context=config.ssl_context) # Open the URL and check the response. return_code = 0