示例#1
0
    def process_request(self):

        encoding = self.request.encoding or 'utf-8'
        payload = self.loads(self.request.body.decode(encoding))

        if isinstance(payload, dict):

            # Store current request id, or None if request is a notification
            self.request_id = payload.get('id')
            return self.process_single_request(payload)

        elif isinstance(payload, (list, tuple)):

            batch_result = JSONRPCBatchResult()

            for single_payload in payload:
                try:
                    try:
                        request_id = single_payload.get('id')

                    except AttributeError:
                        request_id = None
                        raise RPCInvalidRequest(
                            'Single RPC call payload must be a struct')

                    result = self.process_single_request(single_payload)

                    # As stated in documentation:
                    # "A Response object SHOULD exist for each Request object, except that there SHOULD NOT be any
                    # Response objects for notifications."
                    if request_id:
                        batch_result.results.append(
                            self.json_success_response(result,
                                                       override_id=request_id))
                except AuthenticationFailed as e:
                    raise e

                except RPCException as e:
                    logger.warning(
                        'RPC Exception raised in a JSON-RPC batch handling: {}'
                        .format(e),
                        exc_info=settings.MODERNRPC_LOG_EXCEPTIONS)
                    batch_result.results.append(
                        self.json_error_response(e, override_id=request_id))

                except Exception as e:
                    logger.warning(
                        'Exception raised in a JSON-RPC batch handling: {}'.
                        format(e),
                        exc_info=settings.MODERNRPC_LOG_EXCEPTIONS)
                    rpc_exception = RPCInternalError(str(e))
                    batch_result.results.append(
                        self.json_error_response(rpc_exception,
                                                 override_id=request_id))

            return batch_result

        else:
            raise RPCInvalidRequest('Bad JSON-RPC payload: {}'.format(
                str(payload)))
示例#2
0
    def process_request(self):

        encoding = self.request.encoding or 'utf-8'
        payload = self.loads(self.request.body.decode(encoding))

        if isinstance(payload, dict):

            # Store current request id, or None if request is a notification
            self.request_id = payload.get('id')
            return self.process_single_request(payload)

        elif isinstance(payload, (list, tuple)):

            batch_result = JSONRPCBatchResult()

            for single_payload in payload:
                try:
                    try:
                        request_id = single_payload.get('id')

                    except AttributeError:
                        request_id = None
                        raise RPCInvalidRequest()

                    result = self.process_single_request(single_payload)

                    if request_id:
                        # As stated in documentation:
                        # "A Response object SHOULD exist for each Request object, except that there SHOULD NOT be any
                        # Response objects for notifications."
                        batch_result.results.append(
                            self.json_success_response(result,
                                                       override_id=request_id))

                except RPCException as e:
                    batch_result.results.append(
                        self.json_error_response(e, override_id=request_id))

                except Exception as e:
                    rpc_exception = RPCInternalError(str(e))
                    batch_result.results.append(
                        self.json_error_response(rpc_exception,
                                                 override_id=request_id))

            return batch_result

        else:
            raise RPCInvalidRequest()
示例#3
0
    def process_single_request(self, payload):

        if 'jsonrpc' not in payload:
            raise RPCInvalidRequest('Missing parameter "jsonrpc"')

        elif 'method' not in payload:
            raise RPCInvalidRequest('Missing parameter "method"')

        if payload['jsonrpc'] != '2.0':
            raise RPCInvalidRequest(
                'The attribute "jsonrpc" must contain "2.0"')

        method_name = payload['method']

        params = payload.get('params')
        args = params if isinstance(params, (list, tuple)) else []
        kwargs = params if isinstance(params, dict) else {}

        return self.execute_procedure(method_name, args=args, kwargs=kwargs)
示例#4
0
    def process_request(self):

        encoding = self.request.encoding or 'utf-8'
        data = self.request.body.decode(encoding)

        params, method_name = self.loads(data)

        if method_name is None:
            raise RPCInvalidRequest('Missing methodName')

        return self.execute_procedure(method_name, args=params)
示例#5
0
    def loads(self, str_data):
        try:
            try:
                # Python 3
                return xmlrpc_client.loads(str_data,
                                           use_builtin_types=settings.
                                           MODERNRPC_XMLRPC_USE_BUILTIN_TYPES)
            except TypeError:
                # Python 2
                return xmlrpc_client.loads(
                    str_data,
                    use_datetime=settings.MODERNRPC_XMLRPC_USE_BUILTIN_TYPES)

        except xml.parsers.expat.ExpatError as e:
            raise RPCParseError(e)

        except xmlrpc_client.ResponseError:
            raise RPCInvalidRequest('Bad XML-RPC payload')

        except Exception as e:  # pragma: no cover
            raise RPCInvalidRequest(e)
示例#6
0
    def can_handle(self):
        # Get the content-type header from incoming request. Method differs depending on current Django version
        try:
            # Django >= 1.10
            content_type = self.request.content_type
        except AttributeError:
            # Django up to 1.9
            content_type = self.request.META['CONTENT_TYPE']

        if not content_type:
            # We don't accept a request with missing Content-Type request
            raise RPCInvalidRequest('Missing header: Content-Type')

        return content_type.lower() in self.valid_content_types()
示例#7
0
    def process_single_request(self, payload):

        if 'jsonrpc' not in payload:
            raise RPCInvalidRequest('Missing parameter "jsonrpc"')

        elif 'method' not in payload:
            raise RPCInvalidRequest('Missing parameter "method"')

        if payload['jsonrpc'] != '2.0':
            raise RPCInvalidRequest(
                'The attribute "jsonrpc" must contains "2.0"')

        params = payload.get('params')

        if isinstance(params, (list, tuple)):
            rpc_request = RPCRequest(payload['method'], args=params)

        elif isinstance(params, dict):
            rpc_request = RPCRequest(payload['method'], kwargs=params)

        else:
            rpc_request = RPCRequest(payload['method'])

        return rpc_request.execute(self)