From 5d90740f33d80db5559becc0cc619d965a4bb292 Mon Sep 17 00:00:00 2001 From: David Peraza Date: Thu, 20 Jun 2013 20:53:08 +0000 Subject: [PATCH] HTTPS response issues Fixes bug 1179392 glanceclient.common.http.HTTPClient.get_connection_kwargs method explicitly sets the timeout to be a float, while struc.pack is still using LL as the format string which means 2 Long Integers. Setting format string to fL which mean a float followed by Long Integer. Also, Bad file descriptor error is caused by socket being closed to soon. Added a close() implementation to VerifiedHTTPSConnection which will remove reference to socket before returning call to base HTTPConnection.close(). This will avoid socket to be closed before response body is read. Socket will close when response close is called. Change-Id: I3a973da3b962c7572ae0f61f6996bdd1f0048339 --- glanceclient/common/http.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/glanceclient/common/http.py b/glanceclient/common/http.py index c534d0fe..048c1371 100644 --- a/glanceclient/common/http.py +++ b/glanceclient/common/http.py @@ -288,6 +288,11 @@ class OpenSSLConnectionDelegator(object): return getattr(self.connection, name) def makefile(self, *args, **kwargs): + # Making sure socket is closed when this file is closed + # since we now avoid closing socket on connection close + # see new close method under VerifiedHTTPSConnection + kwargs['close'] = True + return socket._fileobject(self.connection, *args, **kwargs) @@ -411,10 +416,21 @@ class VerifiedHTTPSConnection(HTTPSConnection): if self.timeout is not None: # '0' microseconds sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, - struct.pack('LL', self.timeout, 0)) + struct.pack('fL', self.timeout, 0)) self.sock = OpenSSLConnectionDelegator(self.context, sock) self.sock.connect((self.host, self.port)) + def close(self): + if self.sock: + # Removing reference to socket but don't close it yet. + # Response close will close both socket and associated + # file. Closing socket too soon will cause response + # reads to fail with socket IO error 'Bad file descriptor'. + self.sock = None + + # Calling close on HTTPConnection to continue doing that cleanup. + HTTPSConnection.close(self) + class ResponseBodyIterator(object): """A class that acts as an iterator over an HTTP response."""