11# -*- coding: utf-8 -*
22###
3- # (C) Copyright (2012-2017 ) Hewlett Packard Enterprise Development LP
3+ # (C) Copyright (2012-2018 ) Hewlett Packard Enterprise Development LP
44#
55# Permission is hereby granted, free of charge, to any person obtaining a copy
66# of this software and associated documentation files (the "Software"), to deal
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,28 @@ 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+ self ._conn = None
232+
211233 def get_connection (self ):
212234 context = ssl .SSLContext (ssl .PROTOCOL_TLSv1_2 )
213235 if self ._sslTrustAll is False :
@@ -290,7 +312,7 @@ def post_multipart(self, uri, fields, files, baseName, verbose=False):
290312 mappedfile = mmap .mmap (inputfile .fileno (), 0 , access = mmap .ACCESS_READ )
291313 if verbose is True :
292314 print (('Uploading ' + files + '...' ))
293- conn = self .get_connection ()
315+ conn = self .get_reusable_connection ()
294316 # conn.set_debuglevel(1)
295317 conn .connect ()
296318 conn .putrequest ('POST' , uri )
@@ -300,6 +322,8 @@ def post_multipart(self, uri, fields, files, baseName, verbose=False):
300322 totalSize = os .path .getsize (files + '.b64' )
301323 conn .putheader ('Content-Length' , totalSize )
302324 conn .putheader ('X-API-Version' , self ._apiVersion )
325+ if self ._reuse_connection :
326+ conn .putheader ('Connection' , 'keep-alive' )
303327 conn .endheaders ()
304328
305329 while mappedfile .tell () < mappedfile .size ():
@@ -313,6 +337,7 @@ def post_multipart(self, uri, fields, files, baseName, verbose=False):
313337 mappedfile .close ()
314338 inputfile .close ()
315339 os .remove (files + '.b64' )
340+
316341 response = conn .getresponse ()
317342 body = response .read ().decode ('utf-8' )
318343
@@ -322,9 +347,11 @@ def post_multipart(self, uri, fields, files, baseName, verbose=False):
322347 except ValueError :
323348 body = response .read ().decode ('utf-8' )
324349
325- conn .close ()
350+ if not self ._reuse_connection :
351+ self .close_reusable_connection (conn )
326352
327353 if response .status >= 400 :
354+ self .close_reusable_connection (conn )
328355 raise HPOneViewException (body )
329356
330357 return response , body
0 commit comments