5454
5555
5656class connection (object ):
57- def __init__ (self , applianceIp , api_version = 300 , sslBundle = False , timeout = None ):
57+ def __init__ (self , applianceIp , api_version = 300 , sslBundle = False , timeout = None , reuse_connection = False ):
5858 self ._session = None
5959 self ._host = applianceIp
6060 self ._cred = None
@@ -75,6 +75,10 @@ def __init__(self, applianceIp, api_version=300, sslBundle=False, timeout=None):
7575 self ._numDisplayedRecords = 0
7676 self ._validateVersion = False
7777 self ._timeout = timeout
78+ self ._reuse_connection = reuse_connection
79+ if self ._reuse_connection :
80+ self ._headers ['Connection' ] = 'keep-alive'
81+ self ._conn = None
7882
7983 def validateVersion (self ):
8084 version = self .get (uri ['version' ])
@@ -120,11 +124,11 @@ def do_http(self, method, path, body, custom_headers=None):
120124 if custom_headers :
121125 http_headers .update (custom_headers )
122126
123- bConnected = False
124127 conn = None
128+ bConnected = False
125129 while bConnected is False :
126130 try :
127- conn = self .get_connection ()
131+ conn = self .get_reusable_connection ()
128132 conn .request (method , path , body , http_headers )
129133 resp = conn .getresponse ()
130134 tempbytes = ''
@@ -133,23 +137,25 @@ def do_http(self, method, path, body, custom_headers=None):
133137 tempbody = tempbytes .decode ('utf-8' )
134138 except UnicodeDecodeError : # Might be binary data
135139 tempbody = tempbytes
136- conn .close ()
140+ if not self ._reuse_connection :
141+ self .close_reusable_connection (conn )
137142 bConnected = True
138143 return resp , tempbody
139144 if tempbody :
140145 try :
141146 body = json .loads (tempbody )
142147 except ValueError :
143148 body = tempbody
144- conn .close ()
149+ if not self ._reuse_connection :
150+ self .close_reusable_connection (conn )
145151 bConnected = True
146152 except http .client .BadStatusLine :
147153 logger .warning ('Bad Status Line. Trying again...' )
148- if conn :
149- conn .close ()
154+ self .close_reusable_connection (conn )
150155 time .sleep (1 )
151156 continue
152157 except http .client .HTTPException :
158+ self .close_reusable_connection (conn )
153159 raise HPOneViewException ('Failure during login attempt.\n %s' % traceback .format_exc ())
154160
155161 return resp , body
@@ -165,7 +171,7 @@ def download_to_stream(self, stream_writer, url, body='', method='GET', custom_h
165171 successful_connected = False
166172 while not successful_connected :
167173 try :
168- conn = self .get_connection ()
174+ conn = self .get_reusable_connection ()
169175 conn .request (method , url , body , http_headers )
170176 resp = conn .getresponse ()
171177
@@ -178,15 +184,16 @@ def download_to_stream(self, stream_writer, url, body='', method='GET', custom_h
178184 if tempbytes : # filter out keep-alive new chunks
179185 stream_writer .write (tempbytes )
180186
181- conn .close ()
187+ if not self ._reuse_connection :
188+ self .close_reusable_connection (conn )
182189 successful_connected = True
183190 except http .client .BadStatusLine :
184191 logger .warning ('Bad Status Line. Trying again...' )
185- if conn :
186- conn .close ()
192+ self .close_reusable_connection (conn )
187193 time .sleep (1 )
188194 continue
189195 except http .client .HTTPException :
196+ self .close_reusable_connection (conn )
190197 raise HPOneViewException ('Failure during login attempt.\n %s' % traceback .format_exc ())
191198
192199 return successful_connected
@@ -201,13 +208,29 @@ def __handle_download_error(self, resp, conn):
201208 body = tempbody
202209 except UnicodeDecodeError : # Might be binary data
203210 body = tempbytes
204- conn . close ( )
211+ self . close_reusable_connection ( conn )
205212 if not body :
206213 body = "Error " + str (resp .status )
207214
208- conn . close ( )
215+ self . close_reusable_connection ( conn )
209216 raise HPOneViewException (body )
210217
218+ def get_reusable_connection (self ):
219+ if self ._reuse_connection :
220+ if not self ._conn :
221+ logger .debug ('Creating new connection' )
222+ self ._conn = self .get_connection ()
223+ conn = self ._conn
224+ else :
225+ conn = self .get_connection ()
226+ return conn
227+
228+ def close_reusable_connection (self , conn ):
229+ if conn :
230+ conn .close ()
231+ if self ._reuse_connection :
232+ self ._conn = None
233+
211234 def get_connection (self ):
212235 context = ssl .SSLContext (ssl .PROTOCOL_TLSv1_2 )
213236 if self ._sslTrustAll is False :
@@ -290,7 +313,7 @@ def post_multipart(self, uri, fields, files, baseName, verbose=False):
290313 mappedfile = mmap .mmap (inputfile .fileno (), 0 , access = mmap .ACCESS_READ )
291314 if verbose is True :
292315 print (('Uploading ' + files + '...' ))
293- conn = self .get_connection ()
316+ conn = self .get_reusable_connection ()
294317 # conn.set_debuglevel(1)
295318 conn .connect ()
296319 conn .putrequest ('POST' , uri )
@@ -300,6 +323,8 @@ def post_multipart(self, uri, fields, files, baseName, verbose=False):
300323 totalSize = os .path .getsize (files + '.b64' )
301324 conn .putheader ('Content-Length' , totalSize )
302325 conn .putheader ('X-API-Version' , self ._apiVersion )
326+ if self ._reuse_connection :
327+ conn .putheader ('Connection' , 'keep-alive' )
303328 conn .endheaders ()
304329
305330 while mappedfile .tell () < mappedfile .size ():
@@ -313,6 +338,7 @@ def post_multipart(self, uri, fields, files, baseName, verbose=False):
313338 mappedfile .close ()
314339 inputfile .close ()
315340 os .remove (files + '.b64' )
341+
316342 response = conn .getresponse ()
317343 body = response .read ().decode ('utf-8' )
318344
@@ -322,9 +348,11 @@ def post_multipart(self, uri, fields, files, baseName, verbose=False):
322348 except ValueError :
323349 body = response .read ().decode ('utf-8' )
324350
325- conn .close ()
351+ if not self ._reuse_connection :
352+ self .close_reusable_connection (conn )
326353
327354 if response .status >= 400 :
355+ self .close_reusable_connection (conn )
328356 raise HPOneViewException (body )
329357
330358 return response , body
0 commit comments