diff --git a/lib/jsonrpc.py b/lib/jsonrpc.py index 205beb3..eff942d 100644 --- a/lib/jsonrpc.py +++ b/lib/jsonrpc.py @@ -117,7 +117,6 @@ class JSONRPC(asyncio.Protocol, LoggedClass): message = message.decode() except UnicodeDecodeError as e: msg = 'cannot decode binary bytes: {}'.format(e) - self.logger.warning(msg) self.send_json_error(msg, self.PARSE_ERROR) return @@ -125,7 +124,6 @@ class JSONRPC(asyncio.Protocol, LoggedClass): message = json.loads(message) except json.JSONDecodeError as e: msg = 'cannot decode JSON: {}'.format(e) - self.logger.warning(msg) self.send_json_error(msg, self.PARSE_ERROR) return @@ -133,52 +131,49 @@ class JSONRPC(asyncio.Protocol, LoggedClass): def send_json_notification(self, method, params): '''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_): '''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): '''Send a JSON error.''' + self.send_json(json_error_payload(message, code, id_)) 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): '''Send a JSON payload.''' + # Confirmed this happens, sometimes a lot if self.transport.is_closing(): - # Confirmed this happens, sometimes a lot - return False + return try: data = (json.dumps(payload) + '\n').encode() except TypeError: msg = 'JSON encoding failure: {}'.format(payload) self.logger.error(msg) - return self.send_json_error(msg, self.INTERNAL_ERROR, - payload.get('id')) - - self.send_count += 1 - self.send_size += len(data) - self.transport.write(data) - return True + self.send_json_error(msg, self.INTERNAL_ERROR, payload.get('id')) + else: + self.send_count += 1 + self.send_size += len(data) + self.transport.write(data) async def handle_json_request(self, request): '''Asynchronously handle a JSON request. - Handles batch requests. Returns True if the request response - 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. + Handles batch requests. ''' if isinstance(request, list): payload = await self.batch_request_payload(request) else: payload = await self.single_request_payload(request) - if not payload: - return True - return self.send_json(payload) + if payload: + self.send_json(payload) async def batch_request_payload(self, batch): '''Return the JSON payload corresponding to a batch JSON request.'''