From b7e7a7b15cdb6871219ad8ced082ef76e6667d3b Mon Sep 17 00:00:00 2001 From: Valentin Kuznetsov Date: Thu, 11 Nov 2021 09:21:44 -0500 Subject: [PATCH] Improve handling of HTTP response when it is not in JSON form --- src/python/dbs/apis/dbsClient.py | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/python/dbs/apis/dbsClient.py b/src/python/dbs/apis/dbsClient.py index 333d1e3..af7eb47 100644 --- a/src/python/dbs/apis/dbsClient.py +++ b/src/python/dbs/apis/dbsClient.py @@ -10,6 +10,19 @@ import sys import urllib.request, urllib.parse, urllib.error +def headerHas(headers, content, mime): + """ + Check mime content in HTTP headers which represented as multi line string. + The content is pattern a particular header should start with and mime + is a value of the content. For instance, a typical usage is to check if + given content type exists in HTTP Header, e.g. Content-Type: application/json + """ + for hdr in headers.split('\n'): + if content.lower() in hdr.lower(): + if mime.lower() in hdr.lower(): + return True + return False + def parseStream(results): """ Parse given stream of results @@ -363,6 +376,7 @@ def __init__(self, url="", proxy=None, key=None, cert=None, verifypeer=True, deb self.accept = accept self.aggregate = aggregate self.debug = debug + self.http_response = None self.rest_api = RestApi(auth=X509Auth(ssl_cert=cert, ssl_key=key, ssl_verifypeer=verifypeer, ca_info=ca_info), proxy=Socks5Proxy(proxy_url=self.proxy) if self.proxy else None) @@ -400,7 +414,17 @@ def __callServer(self, method="", params={}, data={}, callmethod='GET', content= print("HTTP={} URL={} method={} params={} data={} headers={}".format(callmethod, self.url, method, params, data, request_headers)) self.http_response = method_func(self.url, method, params, data, request_headers) except HTTPError as http_error: - self.__parseForException(http_error) + if headerHas(http_error.header, 'Content-Type', 'application/json'): + self.__parseForException(http_error) + else: + msg = "\nURL={}\nCode={}\nMessage={}\nHeader={}\nBody={}\n".format( + http_error.url, + http_error.code, + http_error.msg, + http_error.header, + http_error.body) + data = HTTPError(http_error.url, http_error.code, msg, http_error.header, http_error.body) + self.__parseForException(data) if self.accept == "application/ndjson": return parseStream(self.http_response.body) @@ -411,7 +435,7 @@ def __callServer(self, method="", params={}, data={}, callmethod='GET', content= json_ret=json.loads(self.http_response.body) except ValueError as ex: print("The server output is not a valid json, most probably you have a typo in the url.\n%s.\n" % self.url, file=sys.stderr) - raise dbsClientException("Invalid url", "Possible urls are %s" %self.http_response.body) + raise dbsClientException("Invalid url", "Possible urls are %s" % self.http_response.body) if self.aggregate and aggFunc: return aggFunc(json_ret)