Make RPC tests cope with server-side timeout between requests
Python's httplib does not graciously handle disconnections from the http server, resulting in BadStatusLine errors. See https://bugs.python.org/issue3566 "httplib persistent connections violate MUST in RFC2616 sec 8.1.4." This was fixed in Python 3.5. Work around it for now.
This commit is contained in:
parent
2190ea6c4e
commit
ddf98d1d84
1 changed files with 22 additions and 14 deletions
|
@ -106,6 +106,26 @@ class AuthServiceProxy(object):
|
||||||
name = "%s.%s" % (self.__service_name, name)
|
name = "%s.%s" % (self.__service_name, name)
|
||||||
return AuthServiceProxy(self.__service_url, name, connection=self.__conn)
|
return AuthServiceProxy(self.__service_url, name, connection=self.__conn)
|
||||||
|
|
||||||
|
def _request(self, method, path, postdata):
|
||||||
|
'''
|
||||||
|
Do a HTTP request, with retry if we get disconnected (e.g. due to a timeout).
|
||||||
|
This is a workaround for https://bugs.python.org/issue3566 which is fixed in Python 3.5.
|
||||||
|
'''
|
||||||
|
headers = {'Host': self.__url.hostname,
|
||||||
|
'User-Agent': USER_AGENT,
|
||||||
|
'Authorization': self.__auth_header,
|
||||||
|
'Content-type': 'application/json'}
|
||||||
|
try:
|
||||||
|
self.__conn.request(method, path, postdata, headers)
|
||||||
|
return self._get_response()
|
||||||
|
except httplib.BadStatusLine as e:
|
||||||
|
if e.line == "''": # if connection was closed, try again
|
||||||
|
self.__conn.close()
|
||||||
|
self.__conn.request(method, path, postdata, headers)
|
||||||
|
return self._get_response()
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
def __call__(self, *args):
|
def __call__(self, *args):
|
||||||
AuthServiceProxy.__id_count += 1
|
AuthServiceProxy.__id_count += 1
|
||||||
|
|
||||||
|
@ -115,13 +135,7 @@ class AuthServiceProxy(object):
|
||||||
'method': self.__service_name,
|
'method': self.__service_name,
|
||||||
'params': args,
|
'params': args,
|
||||||
'id': AuthServiceProxy.__id_count}, default=EncodeDecimal)
|
'id': AuthServiceProxy.__id_count}, default=EncodeDecimal)
|
||||||
self.__conn.request('POST', self.__url.path, postdata,
|
response = self._request('POST', self.__url.path, postdata)
|
||||||
{'Host': self.__url.hostname,
|
|
||||||
'User-Agent': USER_AGENT,
|
|
||||||
'Authorization': self.__auth_header,
|
|
||||||
'Content-type': 'application/json'})
|
|
||||||
|
|
||||||
response = self._get_response()
|
|
||||||
if response['error'] is not None:
|
if response['error'] is not None:
|
||||||
raise JSONRPCException(response['error'])
|
raise JSONRPCException(response['error'])
|
||||||
elif 'result' not in response:
|
elif 'result' not in response:
|
||||||
|
@ -133,13 +147,7 @@ class AuthServiceProxy(object):
|
||||||
def _batch(self, rpc_call_list):
|
def _batch(self, rpc_call_list):
|
||||||
postdata = json.dumps(list(rpc_call_list), default=EncodeDecimal)
|
postdata = json.dumps(list(rpc_call_list), default=EncodeDecimal)
|
||||||
log.debug("--> "+postdata)
|
log.debug("--> "+postdata)
|
||||||
self.__conn.request('POST', self.__url.path, postdata,
|
return self._request('POST', self.__url.path, postdata)
|
||||||
{'Host': self.__url.hostname,
|
|
||||||
'User-Agent': USER_AGENT,
|
|
||||||
'Authorization': self.__auth_header,
|
|
||||||
'Content-type': 'application/json'})
|
|
||||||
|
|
||||||
return self._get_response()
|
|
||||||
|
|
||||||
def _get_response(self):
|
def _get_response(self):
|
||||||
http_response = self.__conn.getresponse()
|
http_response = self.__conn.getresponse()
|
||||||
|
|
Loading…
Reference in a new issue