1919TELEMETRY_URL = 'https://telemetry.split.io/api'
2020
2121_LOGGER = logging .getLogger (__name__ )
22-
22+ _EXC_MSG = '{source} library is throwing exceptions'
2323
2424HttpResponse = namedtuple ('HttpResponse' , ['status_code' , 'body' , 'headers' ])
2525
@@ -122,7 +122,7 @@ def _get_headers(self, extra_headers, sdk_key):
122122class HttpClient (HttpClientBase ):
123123 """HttpClient wrapper."""
124124
125- def __init__ (self , timeout = None , sdk_url = None , events_url = None , auth_url = None , telemetry_url = None , authentication_scheme = None , authentication_params = None ):
125+ def __init__ (self , timeout = None , sdk_url = None , events_url = None , auth_url = None , telemetry_url = None ):
126126 """
127127 Class constructor.
128128
@@ -140,8 +140,6 @@ def __init__(self, timeout=None, sdk_url=None, events_url=None, auth_url=None, t
140140 _LOGGER .debug ("Initializing httpclient" )
141141 self ._timeout = timeout / 1000 if timeout else None # Convert ms to seconds.
142142 self ._urls = _construct_urls (sdk_url , events_url , auth_url , telemetry_url )
143- self ._authentication_scheme = authentication_scheme
144- self ._authentication_params = authentication_params
145143 self ._lock = threading .RLock ()
146144
147145 def get (self , server , path , sdk_key , query = None , extra_headers = None ): # pylint: disable=too-many-arguments
@@ -162,22 +160,19 @@ def get(self, server, path, sdk_key, query=None, extra_headers=None): # pylint:
162160 :return: Tuple of status_code & response text
163161 :rtype: HttpResponse
164162 """
165- with self ._lock :
166- start = get_current_epoch_time_ms ()
167- with requests .Session () as session :
168- self ._set_authentication (session )
169- try :
170- response = session .get (
171- _build_url (server , path , self ._urls ),
172- params = query ,
173- headers = self ._get_headers (extra_headers , sdk_key ),
174- timeout = self ._timeout
175- )
176- self ._record_telemetry (response .status_code , get_current_epoch_time_ms () - start )
177- return HttpResponse (response .status_code , response .text , response .headers )
163+ start = get_current_epoch_time_ms ()
164+ try :
165+ response = requests .get (
166+ _build_url (server , path , self ._urls ),
167+ params = query ,
168+ headers = self ._get_headers (extra_headers , sdk_key ),
169+ timeout = self ._timeout
170+ )
171+ self ._record_telemetry (response .status_code , get_current_epoch_time_ms () - start )
172+ return HttpResponse (response .status_code , response .text , response .headers )
178173
179- except Exception as exc : # pylint: disable=broad-except
180- raise HttpClientException ('requests library is throwing exceptions' ) from exc
174+ except Exception as exc : # pylint: disable=broad-except
175+ raise HttpClientException (_EXC_MSG . format ( source = 'request' ) ) from exc
181176
182177 def post (self , server , path , sdk_key , body , query = None , extra_headers = None ): # pylint: disable=too-many-arguments
183178 """
@@ -199,37 +194,19 @@ def post(self, server, path, sdk_key, body, query=None, extra_headers=None): #
199194 :return: Tuple of status_code & response text
200195 :rtype: HttpResponse
201196 """
202- with self ._lock :
203- start = get_current_epoch_time_ms ()
204- with requests .Session () as session :
205- self ._set_authentication (session )
206- try :
207- response = session .post (
208- _build_url (server , path , self ._urls ),
209- json = body ,
210- params = query ,
211- headers = self ._get_headers (extra_headers , sdk_key ),
212- timeout = self ._timeout ,
213- )
214- self ._record_telemetry (response .status_code , get_current_epoch_time_ms () - start )
215- return HttpResponse (response .status_code , response .text , response .headers )
216- except Exception as exc : # pylint: disable=broad-except
217- raise HttpClientException ('requests library is throwing exceptions' ) from exc
218-
219- def _set_authentication (self , session ):
220- if self ._authentication_scheme == AuthenticateScheme .KERBEROS_SPNEGO :
221- _LOGGER .debug ("Using Kerberos Spnego Authentication" )
222- if self ._authentication_params != [None , None ]:
223- session .auth = HTTPKerberosAuth (principal = self ._authentication_params [0 ], password = self ._authentication_params [1 ], mutual_authentication = OPTIONAL )
224- else :
225- session .auth = HTTPKerberosAuth (mutual_authentication = OPTIONAL )
226- elif self ._authentication_scheme == AuthenticateScheme .KERBEROS_PROXY :
227- _LOGGER .debug ("Using Kerberos Proxy Authentication" )
228- if self ._authentication_params != [None , None ]:
229- session .mount ('https://' , HTTPAdapterWithProxyKerberosAuth (principal = self ._authentication_params [0 ], password = self ._authentication_params [1 ]))
230- else :
231- session .mount ('https://' , HTTPAdapterWithProxyKerberosAuth ())
232-
197+ start = get_current_epoch_time_ms ()
198+ try :
199+ response = requests .post (
200+ _build_url (server , path , self ._urls ),
201+ json = body ,
202+ params = query ,
203+ headers = self ._get_headers (extra_headers , sdk_key ),
204+ timeout = self ._timeout ,
205+ )
206+ self ._record_telemetry (response .status_code , get_current_epoch_time_ms () - start )
207+ return HttpResponse (response .status_code , response .text , response .headers )
208+ except Exception as exc : # pylint: disable=broad-except
209+ raise HttpClientException (_EXC_MSG .format (source = 'request' )) from exc
233210
234211 def _record_telemetry (self , status_code , elapsed ):
235212 """
@@ -306,7 +283,7 @@ async def get(self, server, path, apikey, query=None, extra_headers=None): # py
306283 return HttpResponse (response .status , body , response .headers )
307284
308285 except aiohttp .ClientError as exc : # pylint: disable=broad-except
309- raise HttpClientException ('aiohttp library is throwing exceptions' ) from exc
286+ raise HttpClientException (_EXC_MSG . format ( source = 'aiohttp' ) ) from exc
310287
311288 async def post (self , server , path , apikey , body , query = None , extra_headers = None ): # pylint: disable=too-many-arguments
312289 """
@@ -350,7 +327,7 @@ async def post(self, server, path, apikey, body, query=None, extra_headers=None)
350327 return HttpResponse (response .status , body , response .headers )
351328
352329 except aiohttp .ClientError as exc : # pylint: disable=broad-except
353- raise HttpClientException ('aiohttp library is throwing exceptions' ) from exc
330+ raise HttpClientException (_EXC_MSG . format ( source = 'aiohttp' ) ) from exc
354331
355332 async def _record_telemetry (self , status_code , elapsed ):
356333 """
@@ -372,3 +349,111 @@ async def _record_telemetry(self, status_code, elapsed):
372349 async def close_session (self ):
373350 if not self ._session .closed :
374351 await self ._session .close ()
352+
353+ class HttpClientKerberos (HttpClient ):
354+ """HttpClient wrapper."""
355+
356+ def __init__ (self , timeout = None , sdk_url = None , events_url = None , auth_url = None , telemetry_url = None , authentication_scheme = None , authentication_params = None ):
357+ """
358+ Class constructor.
359+
360+ :param timeout: How many milliseconds to wait until the server responds.
361+ :type timeout: int
362+ :param sdk_url: Optional alternative sdk URL.
363+ :type sdk_url: str
364+ :param events_url: Optional alternative events URL.
365+ :type events_url: str
366+ :param auth_url: Optional alternative auth URL.
367+ :type auth_url: str
368+ :param telemetry_url: Optional alternative telemetry URL.
369+ :type telemetry_url: str
370+ """
371+ _LOGGER .debug ("Initializing httpclient for Kerberos auth" )
372+ HttpClient .__init__ (self , timeout = timeout , sdk_url = sdk_url , events_url = events_url , auth_url = auth_url , telemetry_url = telemetry_url )
373+ self ._authentication_scheme = authentication_scheme
374+ self ._authentication_params = authentication_params
375+
376+ def get (self , server , path , sdk_key , query = None , extra_headers = None ): # pylint: disable=too-many-arguments
377+ """
378+ Issue a get request.
379+ :param server: Whether the request is for SDK server, Events server or Auth server.
380+ :typee server: str
381+ :param path: path to append to the host url.
382+ :type path: str
383+ :param sdk_key: sdk key.
384+ :type sdk_key: str
385+ :param query: Query string passed as dictionary.
386+ :type query: dict
387+ :param extra_headers: key/value pairs of possible extra headers.
388+ :type extra_headers: dict
389+
390+ :return: Tuple of status_code & response text
391+ :rtype: HttpResponse
392+ """
393+ with self ._lock :
394+ start = get_current_epoch_time_ms ()
395+ with requests .Session () as session :
396+ self ._set_authentication (session )
397+ try :
398+ response = session .get (
399+ _build_url (server , path , self ._urls ),
400+ headers = self ._get_headers (extra_headers , sdk_key ),
401+ params = query ,
402+ timeout = self ._timeout
403+ )
404+ self ._record_telemetry (response .status_code , get_current_epoch_time_ms () - start )
405+ return HttpResponse (response .status_code , response .text , response .headers )
406+
407+ except Exception as exc : # pylint: disable=broad-except
408+ raise HttpClientException (_EXC_MSG .format (source = 'request' )) from exc
409+
410+ def post (self , server , path , sdk_key , body , query = None , extra_headers = None ): # pylint: disable=too-many-arguments
411+ """
412+ Issue a POST request.
413+
414+ :param server: Whether the request is for SDK server or Events server.
415+ :typee server: str
416+ :param path: path to append to the host url.
417+ :type path: str
418+ :param sdk_key: sdk key.
419+ :type sdk_key: str
420+ :param body: body sent in the request.
421+ :type body: str
422+ :param query: Query string passed as dictionary.
423+ :type query: dict
424+ :param extra_headers: key/value pairs of possible extra headers.
425+ :type extra_headers: dict
426+
427+ :return: Tuple of status_code & response text
428+ :rtype: HttpResponse
429+ """
430+ with self ._lock :
431+ start = get_current_epoch_time_ms ()
432+ with requests .Session () as session :
433+ self ._set_authentication (session )
434+ try :
435+ response = session .post (
436+ _build_url (server , path , self ._urls ),
437+ params = query ,
438+ headers = self ._get_headers (extra_headers , sdk_key ),
439+ json = body ,
440+ timeout = self ._timeout ,
441+ )
442+ self ._record_telemetry (response .status_code , get_current_epoch_time_ms () - start )
443+ return HttpResponse (response .status_code , response .text , response .headers )
444+ except Exception as exc : # pylint: disable=broad-except
445+ raise HttpClientException (_EXC_MSG .format (source = 'request' )) from exc
446+
447+ def _set_authentication (self , session ):
448+ if self ._authentication_scheme == AuthenticateScheme .KERBEROS_SPNEGO :
449+ _LOGGER .debug ("Using Kerberos Spnego Authentication" )
450+ if self ._authentication_params != [None , None ]:
451+ session .auth = HTTPKerberosAuth (principal = self ._authentication_params [0 ], password = self ._authentication_params [1 ], mutual_authentication = OPTIONAL )
452+ else :
453+ session .auth = HTTPKerberosAuth (mutual_authentication = OPTIONAL )
454+ elif self ._authentication_scheme == AuthenticateScheme .KERBEROS_PROXY :
455+ _LOGGER .debug ("Using Kerberos Proxy Authentication" )
456+ if self ._authentication_params != [None , None ]:
457+ session .mount ('https://' , HTTPAdapterWithProxyKerberosAuth (principal = self ._authentication_params [0 ], password = self ._authentication_params [1 ]))
458+ else :
459+ session .mount ('https://' , HTTPAdapterWithProxyKerberosAuth ())
0 commit comments