Changeset View
Changeset View
Standalone View
Standalone View
test/functional/test_framework/authproxy.py
Show First 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | |||||
USER_AGENT = "AuthServiceProxy/0.1" | USER_AGENT = "AuthServiceProxy/0.1" | ||||
log = logging.getLogger("BitcoinRPC") | log = logging.getLogger("BitcoinRPC") | ||||
class JSONRPCException(Exception): | class JSONRPCException(Exception): | ||||
def __init__(self, rpc_error): | def __init__(self, rpc_error): | ||||
try: | try: | ||||
errmsg = '%(message)s (%(code)i)' % rpc_error | errmsg = '{} ({})'.format(rpc_error['message'], rpc_error['code']) | ||||
except (KeyError, TypeError): | except (KeyError, TypeError): | ||||
errmsg = '' | errmsg = '' | ||||
super().__init__(errmsg) | super().__init__(errmsg) | ||||
self.error = rpc_error | self.error = rpc_error | ||||
def EncodeDecimal(o): | def EncodeDecimal(o): | ||||
if isinstance(o, decimal.Decimal): | if isinstance(o, decimal.Decimal): | ||||
Show All 28 Lines | def __init__(self, service_url, service_name=None, timeout=HTTP_TIMEOUT, connection=None, ensure_ascii=True): | ||||
self.__conn = http.client.HTTPConnection( | self.__conn = http.client.HTTPConnection( | ||||
self.__url.hostname, port, timeout=timeout) | self.__url.hostname, port, timeout=timeout) | ||||
def __getattr__(self, name): | def __getattr__(self, name): | ||||
if name.startswith('__') and name.endswith('__'): | if name.startswith('__') and name.endswith('__'): | ||||
# Python internal stuff | # Python internal stuff | ||||
raise AttributeError | raise AttributeError | ||||
if self._service_name is not None: | if self._service_name is not None: | ||||
name = "%s.%s" % (self._service_name, name) | name = "{}.{}".format(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): | def _request(self, method, path, postdata): | ||||
''' | ''' | ||||
Do a HTTP request, with retry if we get disconnected (e.g. due to a timeout). | 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. | This is a workaround for https://bugs.python.org/issue3566 which is fixed in Python 3.5. | ||||
''' | ''' | ||||
headers = {'Host': self.__url.hostname, | headers = {'Host': self.__url.hostname, | ||||
Show All 15 Lines | def _request(self, method, path, postdata): | ||||
# ConnectionResetError happens on FreeBSD with Python 3.4 | # ConnectionResetError happens on FreeBSD with Python 3.4 | ||||
self.__conn.close() | self.__conn.close() | ||||
self.__conn.request(method, path, postdata, headers) | self.__conn.request(method, path, postdata, headers) | ||||
return self._get_response() | return self._get_response() | ||||
def get_request(self, *args, **argsn): | def get_request(self, *args, **argsn): | ||||
AuthServiceProxy.__id_count += 1 | AuthServiceProxy.__id_count += 1 | ||||
log.debug("-%s-> %s %s" % (AuthServiceProxy.__id_count, self._service_name, | log.debug("-{}-> {} {}".format( | ||||
json.dumps(args, default=EncodeDecimal, ensure_ascii=self.ensure_ascii))) | AuthServiceProxy.__id_count, self._service_name, json.dumps( | ||||
args, default=EncodeDecimal, ensure_ascii=self.ensure_ascii))) | |||||
if args and argsn: | if args and argsn: | ||||
raise ValueError( | raise ValueError( | ||||
'Cannot handle both named and positional arguments') | 'Cannot handle both named and positional arguments') | ||||
return {'version': '1.1', | return {'version': '1.1', | ||||
'method': self._service_name, | 'method': self._service_name, | ||||
'params': args or argsn, | 'params': args or argsn, | ||||
'id': AuthServiceProxy.__id_count} | 'id': AuthServiceProxy.__id_count} | ||||
Show All 18 Lines | class AuthServiceProxy(): | ||||
def _get_response(self): | def _get_response(self): | ||||
req_start_time = time.time() | req_start_time = time.time() | ||||
try: | try: | ||||
http_response = self.__conn.getresponse() | http_response = self.__conn.getresponse() | ||||
except socket.timeout as e: | except socket.timeout as e: | ||||
raise JSONRPCException({ | raise JSONRPCException({ | ||||
'code': -344, | 'code': -344, | ||||
'message': '%r RPC took longer than %f seconds. Consider ' | 'message': '{!r} RPC took longer than {} seconds. Consider ' | ||||
'using larger timeout for calls that take ' | 'using larger timeout for calls that take ' | ||||
'longer to return.' % (self._service_name, | 'longer to return.'.format((self._service_name, | ||||
self.__conn.timeout)}) | self.__conn.timeout))}) | ||||
if http_response is None: | if http_response is None: | ||||
raise JSONRPCException({ | raise JSONRPCException({ | ||||
'code': -342, 'message': 'missing HTTP response from server'}) | 'code': -342, 'message': 'missing HTTP response from server'}) | ||||
content_type = http_response.getheader('Content-Type') | content_type = http_response.getheader('Content-Type') | ||||
if content_type != 'application/json': | if content_type != 'application/json': | ||||
raise JSONRPCException({ | raise JSONRPCException({ | ||||
'code': -342, 'message': 'non-JSON HTTP response with \'%i %s\' from server' % (http_response.status, http_response.reason)}) | 'code': -342, 'message': 'non-JSON HTTP response with \'{} {}\' from server'.format( | ||||
http_response.status, http_response.reason)}) | |||||
responsedata = http_response.read().decode('utf8') | responsedata = http_response.read().decode('utf8') | ||||
response = json.loads(responsedata, parse_float=decimal.Decimal) | response = json.loads(responsedata, parse_float=decimal.Decimal) | ||||
elapsed = time.time() - req_start_time | elapsed = time.time() - req_start_time | ||||
if "error" in response and response["error"] is None: | if "error" in response and response["error"] is None: | ||||
log.debug("<-%s- [%.6f] %s" % (response["id"], elapsed, json.dumps( | log.debug("<-{}- [{:.6f}] {}".format(response["id"], elapsed, json.dumps( | ||||
response["result"], default=EncodeDecimal, ensure_ascii=self.ensure_ascii))) | response["result"], default=EncodeDecimal, ensure_ascii=self.ensure_ascii))) | ||||
else: | else: | ||||
log.debug("<-- [%.6f] %s" % (elapsed, responsedata)) | log.debug("<-- [{:.6f}] {}".format(elapsed, responsedata)) | ||||
return response | return response | ||||
def __truediv__(self, relative_uri): | def __truediv__(self, relative_uri): | ||||
return AuthServiceProxy("{}/{}".format(self.__service_url, relative_uri), self._service_name, connection=self.__conn) | return AuthServiceProxy("{}/{}".format(self.__service_url, relative_uri), self._service_name, connection=self.__conn) |