Ejemplo n.º 1
0
def test_invalid_error():
    """
    This test tries to decode an error message with an invalid error code
    """

    from aiohttp_json_rpc import RpcInvalidRequestError
    from aiohttp_json_rpc.protocol import decode_msg

    raw_msg = '''
        {
            "jsonrpc": "2.0",
            "id": 1,
            "error": {
                "code": -32101,
                "message": "Invalid request",
                "data": null
            }
        }
    '''

    with pytest.raises(RpcInvalidRequestError):
        decode_msg(raw_msg)
Ejemplo n.º 2
0
def test_valid_notification():
    from aiohttp_json_rpc.protocol import JsonRpcMsgTyp, decode_msg

    # id is Null
    raw_msg = '''
    {
        "jsonrpc": "2.0",
        "id": null,
        "method": "foo",
        "params": "bar"
    }
    '''

    msg = decode_msg(raw_msg)

    assert msg.type == JsonRpcMsgTyp.NOTIFICATION

    assert msg.data['jsonrpc'] == '2.0'
    assert msg.data['id'] is None
    assert msg.data['method'] == 'foo'
    assert msg.data['params'] == 'bar'

    # without id
    raw_msg = '''
    {
        "jsonrpc": "2.0",
        "method": "foo",
        "params": "bar"
    }
    '''

    msg = decode_msg(raw_msg)

    assert msg.type == JsonRpcMsgTyp.NOTIFICATION

    assert msg.data['jsonrpc'] == '2.0'
    assert msg.data['id'] is None
    assert msg.data['method'] == 'foo'
    assert msg.data['params'] == 'bar'
Ejemplo n.º 3
0
def test_valid_error():
    from aiohttp_json_rpc.protocol import JsonRpcMsgTyp, decode_msg

    raw_msg = '''
        {
            "jsonrpc": "2.0",
            "id": 1,
            "error": {
                "code": -32600,
                "message": "Invalid request",
                "data": null
            }
        }
    '''

    msg = decode_msg(raw_msg)

    assert msg.type == JsonRpcMsgTyp.ERROR
    async def _handle_rpc_msg(self, http_request, raw_msg):
        # This is duplicated code from super but there is no way how to do it
        # to be able handle server->client requests
        host = http_request.host
        if host in self.waiting_requests:
            try:
                _raw_message = raw_msg.data
                msg = decode_msg(_raw_message)

            except RpcError as error:
                await self._ws_send_str(http_request, encode_error(error))
                return

            if msg.type in (JsonRpcMsgTyp.RESULT, JsonRpcMsgTyp.ERROR):
                msg_data = json.loads(_raw_message)
                if msg_data.get("id") in self.waiting_requests[host]:
                    self.responses[host].append(msg_data)
                    return

        return await super()._handle_rpc_msg(http_request, raw_msg)
Ejemplo n.º 5
0
def test_valid_message():
    from aiohttp_json_rpc.protocol import JsonRpcMsgTyp, decode_msg

    raw_msg = '''
    {
        "jsonrpc": "2.0",
        "id": 0,
        "method": "foo",
        "params": "bar"
    }
    '''

    msg = decode_msg(raw_msg)

    assert msg.type == JsonRpcMsgTyp.REQUEST

    assert msg.data['jsonrpc'] == '2.0'
    assert msg.data['id'] == 0
    assert msg.data['method'] == 'foo'
    assert msg.data['params'] == 'bar'
Ejemplo n.º 6
0
    async def handle_http_request(self, http_request):
        raw_msg = await http_request.read()
        try:
            msg = decode_msg(raw_msg)
            self.logger.debug('message decoded: %s', msg)

        except RpcError as error:
            return self._http_send_str(http_request, encode_error(error))

        # handle requests
        if msg.type == JsonRpcMsgTyp.REQUEST:
            self.logger.debug('msg gets handled as request')

            # check if method is available
            if msg.data['method'] not in http_request.methods:
                self.logger.debug('method %s is unknown or restricted',
                                  msg.data['method'])
                if msg.data['method'] in self.rpc_methods:
                    err_msg = 'Method is disabled by the node administrator'
                else:
                    err_msg = 'Method not found'

                return self._http_send_str(
                    http_request,
                    encode_error(
                        RpcMethodNotFoundError(msg_id=msg.data.get('id', None),
                                               message=err_msg)))

            # call method
            raw_response = getattr(
                http_request.methods[msg.data['method']].method,
                'raw_response',
                False,
            )

            try:
                result = await http_request.methods[msg.data['method']](
                    http_request=http_request,
                    rpc=self,
                    msg=msg,
                )

                if not raw_response:
                    result = encode_result(msg.data['id'], result)

                return self._http_send_str(http_request, result)

            except (RpcGenericServerDefinedError, RpcInvalidRequestError,
                    RpcInvalidParamsError, RemmeRpcError) as error:

                return self._http_send_str(
                    http_request,
                    encode_error(error, id=msg.data.get('id', None)))

            except Exception as error:
                logging.error(error, exc_info=True)

                return self._http_send_str(
                    http_request,
                    encode_error(
                        RpcInternalError(msg_id=msg.data.get('id', None))))

        # handle result
        elif msg.type == JsonRpcMsgTyp.RESULT:
            self.logger.debug('msg gets handled as result')

            result = encode_result(msg.data['id'], msg.data['result'])
            return self._http_send_str(http_request, result)
        else:
            self.logger.debug('unsupported msg type (%s)', msg.type)

            return self._http_send_str(
                http_request,
                encode_error(
                    RpcInvalidRequestError(msg_id=msg.data.get('id', None))))
Ejemplo n.º 7
0
    async def _handle_rpc_msg(self, http_request, data=None):
        if not data:
            raw_msg = await http_request.read()
        else:
            raw_msg = data.data
        try:
            msg = decode_msg(raw_msg)
            self.logger.debug(f'message decoded: {msg}')

        except RpcError as error:
            return await self._send_str(http_request, encode_error(error))

        # handle requests
        if msg.type == JsonRpcMsgTyp.REQUEST:
            self.logger.debug('msg gets handled as request')
            method = msg.data['method']

            # check if method is available
            if method not in http_request.methods:
                self.logger.debug(f'method {method} is unknown or restricted')

                if method in self.rpc_methods:
                    err_msg = 'Method is disabled by the node administrator'
                else:
                    err_msg = 'Method not found'

                return await self._send_str(
                    http_request,
                    encode_error(
                        RpcMethodNotFoundError(msg_id=msg.data.get('id', None),
                                               message=err_msg)))

            measurement = METRICS_SENDER.get_time_measurement(
                f'rpc_api.{method}')

            # call method
            raw_response = getattr(
                http_request.methods[method].method,
                'raw_response',
                False,
            )

            try:
                result = await http_request.methods[method](
                    http_request=http_request,
                    rpc=self,
                    msg=msg,
                )

                if not raw_response:
                    result = encode_result(msg.data['id'], result)

            except (RpcGenericServerDefinedError, RpcInvalidRequestError,
                    RpcInvalidParamsError, RemmeRpcError) as error:

                result = encode_error(error, id=msg.data.get('id', None))

            except Exception as error:
                logging.error(error, exc_info=True)

                result = encode_error(
                    RpcInternalError(msg_id=msg.data.get('id', None)))

            measurement.done()
            return await self._send_str(http_request, result)

        # handle result
        elif msg.type == JsonRpcMsgTyp.RESULT:
            self.logger.debug('msg gets handled as result')

            result = encode_result(msg.data['id'], msg.data['result'])
            return await self._send_str(http_request, result)
        else:
            self.logger.debug(f'unsupported msg type ({msg.type})')

            return await self._send_str(
                http_request,
                encode_error(
                    RpcInvalidRequestError(msg_id=msg.data.get('id', None))))