Browse Source

Merge branch 'cutoff_with_many_errors' into develop

master
Neil Booth 8 years ago
parent
commit
139efa57ae
  1. 37
      lib/jsonrpc.py

37
lib/jsonrpc.py

@ -117,7 +117,6 @@ class JSONRPC(asyncio.Protocol, LoggedClass):
message = message.decode() message = message.decode()
except UnicodeDecodeError as e: except UnicodeDecodeError as e:
msg = 'cannot decode binary bytes: {}'.format(e) msg = 'cannot decode binary bytes: {}'.format(e)
self.logger.warning(msg)
self.send_json_error(msg, self.PARSE_ERROR) self.send_json_error(msg, self.PARSE_ERROR)
return return
@ -125,7 +124,6 @@ class JSONRPC(asyncio.Protocol, LoggedClass):
message = json.loads(message) message = json.loads(message)
except json.JSONDecodeError as e: except json.JSONDecodeError as e:
msg = 'cannot decode JSON: {}'.format(e) msg = 'cannot decode JSON: {}'.format(e)
self.logger.warning(msg)
self.send_json_error(msg, self.PARSE_ERROR) self.send_json_error(msg, self.PARSE_ERROR)
return return
@ -133,52 +131,49 @@ class JSONRPC(asyncio.Protocol, LoggedClass):
def send_json_notification(self, method, params): def send_json_notification(self, method, params):
'''Create a json notification.''' '''Create a json notification.'''
return self.send_json(json_notification_payload(method, params)) self.send_json(json_notification_payload(method, params))
def send_json_result(self, result, id_): def send_json_result(self, result, id_):
'''Send a JSON result.''' '''Send a JSON result.'''
return self.send_json(json_result_payload(result, id_)) self.send_json(json_result_payload(result, id_))
def send_json_error(self, message, code, id_=None): def send_json_error(self, message, code, id_=None):
'''Send a JSON error.''' '''Send a JSON error.'''
self.send_json(json_error_payload(message, code, id_))
self.error_count += 1 self.error_count += 1
return self.send_json(json_error_payload(message, code, id_)) # Close abusive clients
if self.error_count >= 10:
self.transport.close()
def send_json(self, payload): def send_json(self, payload):
'''Send a JSON payload.''' '''Send a JSON payload.'''
# Confirmed this happens, sometimes a lot
if self.transport.is_closing(): if self.transport.is_closing():
# Confirmed this happens, sometimes a lot return
return False
try: try:
data = (json.dumps(payload) + '\n').encode() data = (json.dumps(payload) + '\n').encode()
except TypeError: except TypeError:
msg = 'JSON encoding failure: {}'.format(payload) msg = 'JSON encoding failure: {}'.format(payload)
self.logger.error(msg) self.logger.error(msg)
return self.send_json_error(msg, self.INTERNAL_ERROR, self.send_json_error(msg, self.INTERNAL_ERROR, payload.get('id'))
payload.get('id')) else:
self.send_count += 1
self.send_count += 1 self.send_size += len(data)
self.send_size += len(data) self.transport.write(data)
self.transport.write(data)
return True
async def handle_json_request(self, request): async def handle_json_request(self, request):
'''Asynchronously handle a JSON request. '''Asynchronously handle a JSON request.
Handles batch requests. Returns True if the request response Handles batch requests.
was sent (or if nothing was sent because the request was a
notification). Returns False if the send was aborted because
the connection is closing.
''' '''
if isinstance(request, list): if isinstance(request, list):
payload = await self.batch_request_payload(request) payload = await self.batch_request_payload(request)
else: else:
payload = await self.single_request_payload(request) payload = await self.single_request_payload(request)
if not payload: if payload:
return True self.send_json(payload)
return self.send_json(payload)
async def batch_request_payload(self, batch): async def batch_request_payload(self, batch):
'''Return the JSON payload corresponding to a batch JSON request.''' '''Return the JSON payload corresponding to a batch JSON request.'''

Loading…
Cancel
Save