예제 #1
0
파일: api.py 프로젝트: MatWaller/lighthouse
    def render(self, request):
        t_in = time.time()
        request.content.seek(0, 0)
        # Unmarshal the JSON-RPC data.
        content = request.content.read()
        try:
            parsed = jsonrpclib.loads(content)
        except ValueError:
            return server.failure
        functionPath = parsed.get("method")
        args = parsed.get('params')
        id = parsed.get('id')
        version = parsed.get('jsonrpc')
        peer = request.transport.getPeer()

        if version:
            version = int(float(version))
        elif id and not version:
            version = jsonrpclib.VERSION_1
        else:
            version = jsonrpclib.VERSION_PRE1
        # XXX this all needs to be re-worked to support logic for multiple
        # versions...
        try:
            function = self._getFunction(functionPath)
        except jsonrpclib.Fault, f:
            self._cbRender(f, request, id, version)
예제 #2
0
 def render(self, request):
     request.content.seek(0, 0)
     # Unmarshal the JSON-RPC data.
     content = request.content.read()
     if not content and request.method=='GET' and request.args.has_key('request'):
         content=request.args['request'][0]
     self.callback = request.args['callback'][0] if request.args.has_key('callback') else None
     self.is_jsonp = True if self.callback else False
     parsed = jsonrpclib.loads(content)
     functionPath = parsed.get("method")
     args = parsed.get('params', [])
     id = parsed.get('id')
     version = parsed.get('jsonrpc')
     if version:
         version = int(float(version))
     elif id and not version:
         version = jsonrpclib.VERSION_1
     else:
         version = jsonrpclib.VERSION_PRE1
     # XXX this all needs to be re-worked to support logic for multiple
     # versions...
     try:
         function = self._getFunction(functionPath)
     except jsonrpclib.Fault, f:
         self._cbRender(f, request, id, version)
예제 #3
0
 def render(self, request):
     request.content.seek(0, 0)
     # Unmarshal the JSON-RPC data.
     content = request.content.read()
     if not content and request.method=='GET' and 'request' in request.args:
         content=request.args['request'][0]
     self.callback = request.args['callback'][0] if 'callback' in request.args else None
     self.is_jsonp = True if self.callback else False
     parsed = jsonrpclib.loads(content)
     functionPath = parsed.get("method")
     args = parsed.get('params', [])
     id = parsed.get('id')
     version = parsed.get('jsonrpc')
     if version:
         version = int(float(version))
     elif id and not version:
         version = jsonrpclib.VERSION_1
     else:
         version = jsonrpclib.VERSION_PRE1
     # XXX this all needs to be re-worked to support logic for multiple
     # versions...
     try:
         function = self._getFunction(functionPath)
     except jsonrpclib.Fault as f:
         self._cbRender(f, request, id, version)
     else:
         if not self.is_jsonp:
             request.setHeader("content-type", "text/json")
         else:
             request.setHeader("content-type", "text/javascript")
         d = defer.maybeDeferred(function, *args)
         d.addErrback(self._ebRender, id)
         d.addCallback(self._cbRender, request, id, version)
     return server.NOT_DONE_YET
예제 #4
0
    def render(self, request):
        request.content.seek(0, 0)
        # Unmarshal the JSON-RPC data.
        content = request.content.read()
        log.msg("Client({}): {}".format(request.client, content))
        if not content and request.method == 'GET' and request.args.has_key(
                'request'):
            content = request.args['request'][0]
        self.callback = request.args['callback'][0] if request.args.has_key(
            'callback') else None
        self.is_jsonp = True if self.callback else False
        parsed = jsonrpclib.loads(content)
        functionPath = parsed.get("method")
        params = parsed.get('params', {})
        args, kwargs = [], {}
        if params.__class__ == list:
            args = params
        else:
            kwargs = params
        id = parsed.get('id')
        token = None
        if request.requestHeaders.hasHeader(self.auth_token):
            token = request.requestHeaders.getRawHeaders(self.auth_token)[0]
        version = parsed.get('jsonrpc')
        if version:
            version = int(float(version))
        elif id and not version:
            version = jsonrpclib.VERSION_1
        else:
            version = jsonrpclib.VERSION_PRE1
        # XXX this all needs to be re-worked to support logic for multiple
        # versions...
        try:
            function = self._getFunction(functionPath)
            d = None
            if hasattr(function, 'requires_auth'):
                d = defer.maybeDeferred(self.auth, token, functionPath)
        except jsonrpclib.Fault as f:
            self._cbRender(f, request, id, version)
        else:
            if not self.is_jsonp:
                request.setHeader("content-type", "application/json")
            else:
                request.setHeader("content-type", "text/javascript")

            if hasattr(function, 'with_request'):
                args = [request] + args
            elif d:
                d.addCallback(context.call, function, *args, **kwargs)
            else:
                d = defer.maybeDeferred(function, *args, **kwargs)
            d.addErrback(self._ebRender, id)
            d.addCallback(self._cbRender, request, id, version)

            def _responseFailed(err, call):
                call.cancel()

            request.notifyFinish().addErrback(_responseFailed, d)
        return server.NOT_DONE_YET
예제 #5
0
    def render(self, request):
        request.content.seek(0, 0)
        # Unmarshal the JSON-RPC data.
        content = request.content.read()
        if isinstance(content, six.binary_type):
            content = content.decode('utf-8')
        log.msg("Client({}): {}".format(request.client, content))
        if not content and request.method == 'GET' and 'request' in request.args:
            content = request.args['request'][0]
        self.callback = request.args['callback'][0] if 'callback' in request.args else None
        self.is_jsonp = True if self.callback else False
        parsed = jsonrpclib.loads(content)
        functionPath = parsed.get("method")
        params = parsed.get('params', {})
        args, kwargs = [], {}
        if params.__class__ == list:
            args = params
        else:
            kwargs = params
        id = parsed.get('id')
        token = None
        if request.requestHeaders.hasHeader(self.auth_token):
            token = request.requestHeaders.getRawHeaders(self.auth_token)[0]
        version = parsed.get('jsonrpc')
        if version:
            version = int(float(version))
        elif id and not version:
            version = jsonrpclib.VERSION_1
        else:
            version = jsonrpclib.VERSION_PRE1
        # XXX this all needs to be re-worked to support logic for multiple
        # versions...
        try:
            function = self._getFunction(functionPath)
            d = None
            if hasattr(function, 'requires_auth'):
                d = defer.maybeDeferred(self.auth, token, functionPath)
        except jsonrpclib.Fault as f:
            self._cbRender(f, request, id, version)
        else:
            if not self.is_jsonp:
                request.setHeader("content-type", "application/json")
            else:
                request.setHeader("content-type", "text/javascript")

            if hasattr(function, 'with_request'):
                args = [request] + args
            elif d:
                d.addCallback(context.call, function, *args, **kwargs)
            else:
                d = defer.maybeDeferred(function, *args, **kwargs)
            d.addErrback(self._ebRender, id)
            d.addCallback(self._cbRender, request, id, version)

            def _responseFailed(err, call):
                call.cancel()
            request.notifyFinish().addErrback(_responseFailed, d)
        return server.NOT_DONE_YET
예제 #6
0
    def stringReceived(self, string):
        try:
            received = jsonrpclib.loads(string)
        except jsonrpclib.ParseError:
            return self.unhandledError(failure.Failure())

        if "result" in received or "error" in received:
            return self._receivedResult(received)
        else:
            return self._receivedRequest(received)
예제 #7
0
파일: jsonrpc.py 프로젝트: ksze/txjsonrpc
    def render(self, request):
        request.content.seek(0, 0)
        # Unmarshal the JSON-RPC data.
        content = request.content.read()

        if not content and request.method=='GET' and request.args.has_key('request'):
            content=request.args['request'][0]

        self.callback = request.args['callback'][0] if request.args.has_key('callback') else None
        self.is_jsonp = True if self.callback else False
        parsed = jsonrpclib.loads(content)
        functionPath = parsed.get("method")
        params = parsed.get('params')
        args, kwargs = [], {}

        if isinstance(params, list):
          args = params
        elif isinstance(params, dict):
          kwargs = params

        id = parsed.get('id')
        version = parsed.get('jsonrpc')

        if version:
            version = int(float(version))
        elif id and not version:
            version = jsonrpclib.VERSION_1
        else:
            version = jsonrpclib.VERSION_PRE1

        # XXX this all needs to be re-worked to support logic for multiple
        # versions...
        try:
            function = self._getFunction(functionPath)
        except jsonrpclib.Fault as f:
            self._cbRender(f, request, id, version)
        else:
            if not self.is_jsonp:
                request.setHeader("content-type", "application/json")
            else:
                request.setHeader("content-type", "text/javascript")

            if hasattr(function, 'with_request'):
                args = [request] + args

            d = defer.maybeDeferred(function, *args, **kwargs)
            d.addErrback(self._ebRender, id)
            d.addCallback(self._cbRender, request, id, version)

            def _responseFailed(err, call):
                call.cancel()

            request.notifyFinish().addErrback(_responseFailed, d)

        return server.NOT_DONE_YET
예제 #8
0
 def parseResponse(self, contents):
     if not self.deferred:
         return
     try:
         # Convert the response from JSON-RPC to python.
         result = jsonrpclib.loads(contents)
         if self.version != jsonrpclib.VERSION_PRE1:
             result = result["result"]
         elif isinstance(result, list):
             result = result[0]
     except Exception, error:
         self.deferred.errback(error)
         self.deferred = None
예제 #9
0
 def parseResponse(self, contents):
     if not self.deferred:
         return
     try:
         # Convert the response from JSON-RPC to python.
         result = jsonrpclib.loads(contents)
         if self.version != jsonrpclib.VERSION_PRE1:
             result = result["result"]
         elif isinstance(result, list):
             result = result[0]
     except Exception, error:
         self.deferred.errback(error)
         self.deferred = None
예제 #10
0
 def _cbRender(self, result, request, id, version):
     if self.debug == 2:
         request.content.seek(0, 0)
         content = request.content.read()
         if not content and request.method == 'GET' and 'request' in request.args:
             content = request.args['request'][0]
         parsed = jsonrpclib.loads(content)
         functionPath = parsed.get("method")
         try:
             txt = jsonrpclib.dumps(result, id=id, version=2.0)
         except TypeError:
             txt = result
         self.safe_log("%s: %s" % (functionPath, lightLogVar(txt, 1000)), "DEBUG - ANSWER")
     return JSONRPC._cbRender(self, result, request, id, version)
예제 #11
0
 def parseResponse(self, contents):
     if not self.deferred:
         return
     try:
         # Convert the response from JSON-RPC to python.
         result = jsonrpclib.loads(contents)
         #response = jsonrpclib.loads(contents)
         #result = response['result']
         #error = response['error']
         #if error:
         #    self.deferred.errback(error)
         if isinstance(result, list):
             result = result[0]
     except Exception, error:
         self.deferred.errback(error)
         self.deferred = None
예제 #12
0
 def parseResponse(self, contents):
     if not self.deferred:
         return
     try:
         # Convert the response from JSON-RPC to python.
         result = jsonrpclib.loads(contents)
         #response = jsonrpclib.loads(contents)
         #result = response['result']
         #error = response['error']
         #if error:
         #    self.deferred.errback(error)
         if isinstance(result, list):
             result = result[0]
     except Exception, error:
         self.deferred.errback(error)
         self.deferred = None
예제 #13
0
 def parseResponse(self, contents):
     if not self.deferred:
         return
     try:
         # Convert the response from JSON-RPC to python.
         try:
             result = jsonrpclib.loads(contents)
         except ValueError:
             # In Python 3, the exception message is not very
             # user friendly.
             raise ValueError('No JSON object could be decoded')
         if self.version != jsonrpclib.VERSION_PRE1:
             result = result["result"]
         elif isinstance(result, list):
             result = result[0]
     except Exception as error:
         self.deferred.errback(error)
         self.deferred = None
     else:
         self.deferred.callback(result)
         self.deferred = None
예제 #14
0
 def parseResponse(self, contents):
     if not self.deferred:
         return
     try:
         # Convert the response from JSON-RPC to python.
         try:
             result = jsonrpclib.loads(contents)
         except ValueError:
             # In Python 3, the exception message is not very
             # user friendly.
             raise ValueError('No JSON object could be decoded')
         if self.version != jsonrpclib.VERSION_PRE1:
             result = result["result"]
         elif isinstance(result, list):
             result = result[0]
     except Exception as error:
         self.deferred.errback(error)
         self.deferred = None
     else:
         self.deferred.callback(result)
         self.deferred = None
예제 #15
0
파일: jsonrpc.py 프로젝트: jof/txjsonrpc
 def render(self, request):
     request.content.seek(0, 0)
     # Unmarshal the JSON-RPC data.
     content = request.content.read()
     parsed = jsonrpclib.loads(content)
     functionPath = parsed.get("method")
     args = parsed.get('params', [])
     id = parsed.get('id')
     version = parsed.get('jsonrpc')
     if version:
         version = int(float(version))
     elif id and not version:
         version = jsonrpclib.VERSION_1
     else:
         version = jsonrpclib.VERSION_PRE1
     # XXX this all needs to be re-worked to support logic for multiple
     # versions...
     try:
         function = self._getFunction(functionPath)
     except jsonrpclib.Fault, f:
         self._cbRender(f, request, id, version)
예제 #16
0
 def render(self, request):
     request.content.seek(0, 0)
     # Unmarshal the JSON-RPC data.
     content = request.content.read()
     parsed = jsonrpclib.loads(content)
     functionPath = parsed.get("method")
     args = parsed.get('params', [])
     id = parsed.get('id')
     version = parsed.get('jsonrpc')
     if version:
         version = int(float(version))
     elif id and not version:
         version = jsonrpclib.VERSION_1
     else:
         version = jsonrpclib.VERSION_PRE1
     # XXX this all needs to be re-worked to support logic for multiple
     # versions...
     try:
         function = self._getFunction(functionPath)
     except jsonrpclib.Fault, f:
         self._cbRender(f, request, id, version)
예제 #17
0
    def render(self, request):
        request.content.seek(0, 0)
        # Unmarshal the JSON-RPC data.
        content = request.content.read()
        parsed = jsonrpclib.loads(content)
        functionPath = parsed.get("method")
        if functionPath not in ["search", "announce_sd", "check_available"]:
            return server.failure
        args = parsed.get('params')
        if len(args) != 1:
            return server.failure
        arg = args[0]
        id = parsed.get('id')
        version = parsed.get('jsonrpc')
        try:
            log.info("%s@%s: %s" % (functionPath, request.getClientIP(), arg))
        except Exception as err:
            log.error(err.message)

        if self.unique_clients.get(request.getClientIP(), None) is None:
            self.unique_clients[request.getClientIP()] = [[
                functionPath, arg, time.time()
            ]]
        else:
            self.unique_clients[request.getClientIP()].append(
                [functionPath, arg, time.time()])
        if version:
            version = int(float(version))
        elif id and not version:
            version = jsonrpclib.VERSION_1
        else:
            version = jsonrpclib.VERSION_PRE1
        # XXX this all needs to be re-worked to support logic for multiple
        # versions...
        try:
            function = self._getFunction(functionPath)
        except jsonrpclib.Fault, f:
            self._cbRender(f, request, id, version)
예제 #18
0
 def render(self, request):
     request.content.seek(0, 0)
     # Unmarshal the JSON-RPC data.
     content = request.content.read()
     log.msg("Client({}): {}".format(request.client, content))
     if not content and request.method=='GET' and request.args.has_key('request'):
         content=request.args['request'][0]
     self.callback = request.args['callback'][0] if request.args.has_key('callback') else None
     self.is_jsonp = True if self.callback else False
     parsed = jsonrpclib.loads(content)
     functionPath = parsed.get("method")
     params = parsed.get('params', {})
     args, kwargs = [], {}
     if params.__class__ == list:
         args = params
     else:
         kwargs = params
     id = parsed.get('id')
     token = None
     if request.requestHeaders.hasHeader(self.auth_token):
         token = request.requestHeaders.getRawHeaders(self.auth_token)[0]
     version = parsed.get('jsonrpc')
     if version:
         version = int(float(version))
     elif id and not version:
         version = jsonrpclib.VERSION_1
     else:
         version = jsonrpclib.VERSION_PRE1
     # XXX this all needs to be re-worked to support logic for multiple
     # versions...
     try:
         function = self._getFunction(functionPath)
         d = None
         if hasattr(function, 'requires_auth'):
             d = defer.maybeDeferred(self.auth, token, functionPath)
     except jsonrpclib.Fault, f:
         self._cbRender(f, request, id, version)
예제 #19
0
    def render(self, request):
        time_in = utils.now()
        assert self._check_headers(request), InvalidHeaderError
        session = request.getSession()
        session_id = session.uid
        finished_deferred = request.notifyFinish()

        if self._use_authentication:
            # if this is a new session, send a new secret and set the expiration
            # otherwise, session.touch()
            if self._initialize_session(session_id):

                def expire_session():
                    self._unregister_user_session(session_id)

                session.startCheckingExpiration()
                session.notifyOnExpire(expire_session)
                message = "OK"
                request.setResponseCode(self.OK)
                self._set_headers(request, message, True)
                self._render_message(request, message)
                return server.NOT_DONE_YET
            else:
                session.touch()

        request.content.seek(0, 0)
        content = request.content.read()
        try:
            parsed = jsonrpclib.loads(content)
        except ValueError:
            log.warning("Unable to decode request json")
            self._render_error_string('Invalid JSON', request, None)
            return server.NOT_DONE_YET

        function_name = parsed.get('method')
        args = parsed.get('params', {})
        id_ = parsed.get('id')
        token = parsed.pop('hmac', None)
        version = self._get_jsonrpc_version(parsed.get('jsonrpc'), id_)

        reply_with_next_secret = False
        if self._use_authentication:
            if function_name in self.authorized_functions:
                try:
                    self._verify_token(session_id, parsed, token)
                except InvalidAuthenticationToken as err:
                    log.warning("API validation failed")
                    self._render_error(
                        err,
                        request,
                        id_,
                        version=version,
                        response_code=AuthJSONRPCServer.UNAUTHORIZED)
                    return server.NOT_DONE_YET
                self._update_session_secret(session_id)
                reply_with_next_secret = True

        try:
            function = self._get_jsonrpc_method(function_name)
        except (UnknownAPIMethodError, NotAllowedDuringStartupError) as err:
            log.warning('Failed to get function %s: %s', function_name, err)
            self._render_error(err, request, version)
            return server.NOT_DONE_YET

        if args == EMPTY_PARAMS or args == []:
            d = defer.maybeDeferred(function)
        elif isinstance(args, dict):
            d = defer.maybeDeferred(function, **args)
        elif len(args) == 1 and isinstance(args[0], dict):
            # TODO: this is for backwards compatibility. Remove this once API and UI are updated
            # TODO: also delete EMPTY_PARAMS then
            d = defer.maybeDeferred(function, **args[0])
        else:
            # d = defer.maybeDeferred(function, *args)  # if we want to support positional args too
            raise ValueError('Args must be a dict')

        # finished_deferred will callback when the request is finished
        # and errback if something went wrong. If the errback is
        # called, cancel the deferred stack. This is to prevent
        # request.finish() from being called on a closed request.
        finished_deferred.addErrback(self._handle_dropped_request, d,
                                     function_name)

        d.addCallback(self._callback_render, request, id_, version,
                      reply_with_next_secret)
        # TODO: don't trap RuntimeError, which is presently caught to
        # handle deferredLists that won't peacefully cancel, namely
        # get_lbry_files
        d.addErrback(trap, ConnectionDone, ConnectionLost,
                     defer.CancelledError, RuntimeError)
        d.addErrback(
            log.fail(self._render_error, request, id_, version=version),
            'Failed to process %s', function_name)
        d.addBoth(lambda _: log.debug("%s took %f", function_name,
                                      (utils.now() - time_in).total_seconds()))
        return server.NOT_DONE_YET
예제 #20
0
 def test_loads(self):
     jsonInput = ["1", '"a"', '{"apple": 2}', '[1, 2, "a", "b"]']
     expectedResults = [1, "a", {"apple": 2}, [1, 2, "a", "b"]]
     for input, expected in zip(jsonInput, expectedResults):
         unmarshalled = loads(input)
         self.assertEquals(unmarshalled, expected)
예제 #21
0
    def test_loads(self):
        with self.assertRaises(j.ParseError):
            j.loads("bigboom")

        r = {"foo" : [1, 2, 3]}
        self.assertEqual(r, j.loads(json.dumps(r)))
예제 #22
0
파일: server.py 프로젝트: zhilinwww/lbry
    def _render(self, request):
        time_in = utils.now()
        # assert self._check_headers(request), InvalidHeaderError
        session = request.getSession()
        session_id = session.uid
        finished_deferred = request.notifyFinish()

        if self._use_authentication:
            # if this is a new session, send a new secret and set the expiration
            # otherwise, session.touch()
            if self._initialize_session(session_id):
                def expire_session():
                    self._unregister_user_session(session_id)

                session.startCheckingExpiration()
                session.notifyOnExpire(expire_session)
                message = "OK"
                request.setResponseCode(200)
                self._set_headers(request, message, True)
                self._render_message(request, message)
                return server.NOT_DONE_YET
            else:
                session.touch()

        request.content.seek(0, 0)
        content = request.content.read()
        try:
            parsed = jsonrpclib.loads(content)
        except ValueError:
            log.warning("Unable to decode request json")
            self._render_error(JSONRPCError(None, JSONRPCError.CODE_PARSE_ERROR), request, None)
            return server.NOT_DONE_YET

        id_ = None
        try:
            function_name = parsed.get('method')
            args = parsed.get('params', {})
            id_ = parsed.get('id', None)
            token = parsed.pop('hmac', None)
        except AttributeError as err:
            log.warning(err)
            self._render_error(
                JSONRPCError(None, code=JSONRPCError.CODE_INVALID_REQUEST), request, id_
            )
            return server.NOT_DONE_YET

        reply_with_next_secret = False
        if self._use_authentication:
            if function_name in self.authorized_functions:
                try:
                    self._verify_token(session_id, parsed, token)
                except InvalidAuthenticationToken as err:
                    log.warning("API validation failed")
                    self._render_error(
                        JSONRPCError.create_from_exception(
                            err.message, code=JSONRPCError.CODE_AUTHENTICATION_ERROR,
                            traceback=format_exc()
                        ),
                        request, id_
                    )
                    return server.NOT_DONE_YET
                self._update_session_secret(session_id)
                reply_with_next_secret = True

        try:
            fn = self._get_jsonrpc_method(function_name)
        except UnknownAPIMethodError as err:
            log.warning('Failed to get function %s: %s', function_name, err)
            self._render_error(
                JSONRPCError(None, JSONRPCError.CODE_METHOD_NOT_FOUND),
                request, id_
            )
            return server.NOT_DONE_YET
        except NotAllowedDuringStartupError:
            log.warning('Function not allowed during startup: %s', function_name)
            self._render_error(
                JSONRPCError("This method is unavailable until the daemon is fully started",
                             code=JSONRPCError.CODE_INVALID_REQUEST),
                request, id_
            )
            return server.NOT_DONE_YET

        if args == EMPTY_PARAMS or args == []:
            args_dict = {}
            _args, _kwargs = (), {}
        elif isinstance(args, dict):
            args_dict = args
        elif len(args) == 1 and isinstance(args[0], dict):
            # TODO: this is for backwards compatibility. Remove this once API and UI are updated
            # TODO: also delete EMPTY_PARAMS then
            args_dict = args[0]
            _args, _kwargs = (), args
        else:
            # d = defer.maybeDeferred(function, *args)  # if we want to support positional args too
            raise ValueError('Args must be a dict')

        params_error, erroneous_params = self._check_params(fn, args_dict)
        if params_error is not None:
            params_error_message = '{} for {} command: {}'.format(
                params_error, function_name, ', '.join(erroneous_params)
            )
            log.warning(params_error_message)
            self._render_error(
                JSONRPCError(params_error_message, code=JSONRPCError.CODE_INVALID_PARAMS),
                request, id_
            )
            return server.NOT_DONE_YET

        d = defer.maybeDeferred(fn, self, **args_dict)

        # finished_deferred will callback when the request is finished
        # and errback if something went wrong. If the errback is
        # called, cancel the deferred stack. This is to prevent
        # request.finish() from being called on a closed request.
        finished_deferred.addErrback(self._handle_dropped_request, d, function_name)

        d.addCallback(self._callback_render, request, id_, reply_with_next_secret)
        # TODO: don't trap RuntimeError, which is presently caught to
        # handle deferredLists that won't peacefully cancel, namely
        # get_lbry_files
        d.addErrback(trap, ConnectionDone, ConnectionLost, defer.CancelledError, RuntimeError)
        d.addErrback(self._render_error, request, id_)
        d.addBoth(lambda _: log.debug("%s took %f",
                                      function_name,
                                      (utils.now() - time_in).total_seconds()))
        return server.NOT_DONE_YET
예제 #23
0
 def test_loads(self):
     jsonInput = ["1", '"a"', '{"apple": 2}', '[1, 2, "a", "b"]']
     expectedResults = [1, "a", {"apple": 2}, [1, 2, "a", "b"]]
     for input, expected in zip(jsonInput, expectedResults):
         unmarshalled = loads(input)
         self.assertEquals(unmarshalled, expected)
예제 #24
0
파일: server.py 프로젝트: guzhenping/lbry
    def _render(self, request):
        time_in = utils.now()
        # if not self._check_headers(request):
        #     self._render_error(Failure(InvalidHeaderError()), request, None)
        #     return server.NOT_DONE_YET
        session = request.getSession()
        session_id = session.uid
        finished_deferred = request.notifyFinish()

        if self._use_authentication:
            # if this is a new session, send a new secret and set the expiration
            # otherwise, session.touch()
            if self._initialize_session(session_id):

                def expire_session():
                    self._unregister_user_session(session_id)

                session.notifyOnExpire(expire_session)
                message = "OK"
                request.setResponseCode(200)
                self._set_headers(request, message, True)
                self._render_message(request, message)
                return server.NOT_DONE_YET
            else:
                session.touch()

        request.content.seek(0, 0)
        content = request.content.read().decode()
        try:
            parsed = jsonrpclib.loads(content)
        except json.JSONDecodeError:
            log.warning("Unable to decode request json")
            self._render_error(
                JSONRPCError(None, code=JSONRPCError.CODE_PARSE_ERROR),
                request, None)
            return server.NOT_DONE_YET

        request_id = None
        try:
            function_name = parsed.get('method')
            args = parsed.get('params', {})
            request_id = parsed.get('id', None)
            token = parsed.pop('hmac', None)
        except AttributeError as err:
            log.warning(err)
            self._render_error(
                JSONRPCError(None, code=JSONRPCError.CODE_INVALID_REQUEST),
                request, request_id)
            return server.NOT_DONE_YET

        reply_with_next_secret = False
        if self._use_authentication:
            try:
                self._verify_token(session_id, parsed, token)
            except InvalidAuthenticationToken as err:
                log.warning("API validation failed")
                self._render_error(
                    JSONRPCError.create_from_exception(
                        str(err),
                        code=JSONRPCError.CODE_AUTHENTICATION_ERROR,
                        traceback=format_exc()), request, request_id)
                return server.NOT_DONE_YET
            request.addCookie("TWISTED_SESSION", session_id)
            self._update_session_secret(session_id)
            reply_with_next_secret = True

        try:
            fn = self._get_jsonrpc_method(function_name)
        except UnknownAPIMethodError as err:
            log.warning('Failed to get function %s: %s', function_name, err)
            self._render_error(
                JSONRPCError(None, code=JSONRPCError.CODE_METHOD_NOT_FOUND),
                request, request_id)
            return server.NOT_DONE_YET

        if args in (EMPTY_PARAMS, []):
            _args, _kwargs = (), {}
        elif isinstance(args, dict):
            _args, _kwargs = (), args
        elif len(args) == 1 and isinstance(args[0], dict):
            # TODO: this is for backwards compatibility. Remove this once API and UI are updated
            # TODO: also delete EMPTY_PARAMS then
            _args, _kwargs = (), args[0]
        elif len(args) == 2 and isinstance(args[0], list) and isinstance(
                args[1], dict):
            _args, _kwargs = args
        else:
            raise ValueError('invalid args format')

        params_error, erroneous_params = self._check_params(fn, _args, _kwargs)
        if params_error is not None:
            params_error_message = '{} for {} command: {}'.format(
                params_error, function_name, ', '.join(erroneous_params))
            log.warning(params_error_message)
            self._render_error(
                JSONRPCError(params_error_message,
                             code=JSONRPCError.CODE_INVALID_PARAMS), request,
                request_id)
            return server.NOT_DONE_YET

        try:
            result = fn(self, *_args, **_kwargs)
            if isinstance(result, Deferred):
                d = result
            elif isinstance(result, Failure):
                d = defer.fail(result)
            elif asyncio.iscoroutine(result):
                d = Deferred.fromFuture(asyncio.ensure_future(result))
            else:
                d = defer.succeed(result)
        except:
            d = defer.fail(Failure(captureVars=Deferred.debug))

        # finished_deferred will callback when the request is finished
        # and errback if something went wrong. If the errback is
        # called, cancel the deferred stack. This is to prevent
        # request.finish() from being called on a closed request.
        finished_deferred.addErrback(self._handle_dropped_request, d,
                                     function_name)

        d.addCallback(self._callback_render, request, request_id,
                      reply_with_next_secret)
        d.addErrback(trap, ConnectionDone, ConnectionLost,
                     defer.CancelledError)
        d.addErrback(self._render_error, request, request_id)
        d.addBoth(lambda _: log.debug("%s took %f", function_name,
                                      (utils.now() - time_in).total_seconds()))
        return server.NOT_DONE_YET
예제 #25
0
파일: server.py 프로젝트: lbryio/lbry
    def render(self, request):
        notify_finish = request.notifyFinish()
        assert self._check_headers(request), InvalidHeaderError
        session = request.getSession()
        session_id = session.uid

        if self._use_authentication:
            # if this is a new session, send a new secret and set the expiration
            # otherwise, session.touch()
            if self._initialize_session(session_id):
                def expire_session():
                    self._unregister_user_session(session_id)
                session.startCheckingExpiration()
                session.notifyOnExpire(expire_session)
                message = "OK"
                request.setResponseCode(self.OK)
                self._set_headers(request, message, True)
                self._render_message(request, message)
                return server.NOT_DONE_YET
            session.touch()

        request.content.seek(0, 0)
        content = request.content.read()
        try:
            parsed = jsonrpclib.loads(content)
        except ValueError as err:
            log.warning("Unable to decode request json")
            self._render_error(err, request)
            return server.NOT_DONE_YET

        function_name = parsed.get('method')
        args = parsed.get('params')
        id = parsed.get('id')
        token = parsed.pop('hmac', None)
        version = self._get_jsonrpc_version(parsed.get('jsonrpc'), id)

        try:
            self._run_subhandlers(request)
        except SubhandlerError as err:
            self._render_error(err, request, version)
            return server.NOT_DONE_YET

        reply_with_next_secret = False
        if self._use_authentication:
            if function_name in self.authorized_functions:
                try:
                    self._verify_token(session_id, parsed, token)
                except InvalidAuthenticationToken as err:
                    log.warning("API validation failed")
                    self._render_error(
                        err, request, version=version, response_code=AuthJSONRPCServer.UNAUTHORIZED)
                    return server.NOT_DONE_YET
                self._update_session_secret(session_id)
                reply_with_next_secret = True

        try:
            function = self._get_jsonrpc_method(function_name)
        except AttributeError as err:
            log.warning("Unknown method: %s", function_name)
            self._render_error(err, request, version)
            return server.NOT_DONE_YET

        if args == [{}]:
            d = defer.maybeDeferred(function)
        else:
            d = defer.maybeDeferred(function, *args)

        # cancel the response if the connection is broken
        notify_finish.addErrback(self._response_failed, d)
        d.addCallback(self._callback_render, request, version, reply_with_next_secret)
        d.addErrback(
            log.fail(self._render_error, request, version=version),
            'Failed to process %s', function_name
        )
        return server.NOT_DONE_YET
예제 #26
0
    def render(self, request):
        if self.open_cors:
            request.setHeader("Access-Control-Allow-Origin", "*")
        from_ip = ""
        if request.getHeader("x-forwarded-for"):
            from_ip = " from %s" % request.getHeader("x-forwarded-for")
        # Unmarshal the JSON-RPC data.
        request.content.seek(0, 0)
        content = request.content.read()
        if not content and request.method == 'GET' and 'request' in request.args:
            content = request.args['request'][0]
        self.callback = request.args['callback'][0] if 'callback' in request.args else None
        self.is_jsonp = True if self.callback else False
        try:
            parsed = jsonrpclib.loads(content)
        except ValueError:
            parsed = {"content": content, "method": None, "params": {}}
        functionPath = parsed.get("method")

        if self.debug:
            parsedcopy = deepcopy(parsed)
            if functionPath in ["start_corpus", "create_corpus"] and len(parsedcopy["params"]) > 1:
                parsedcopy["params"][1] = "********"
            self.safe_log(parsedcopy, "DEBUG - QUERY%s" % from_ip)

        params = parsed.get('params', {})
        args, kwargs = [], {}
        if params.__class__ == list:
            args = params
        else:
            kwargs = params
        id = parsed.get('id')
        token = None
        #if request.requestHeaders.hasHeader(self.auth_token):
        #    token = request.requestHeaders.getRawHeaders(self.auth_token)[0]
        version = parsed.get('jsonrpc')
        if version:
            version = int(float(version))
        elif id and not version:
            version = jsonrpclib.VERSION_1
        else:
            version = jsonrpclib.VERSION_PRE1
        try:
            function = self._getFunction(functionPath)
            d = None
            #if hasattr(function, 'requires_auth'):
            #    d = maybeDeferred(self.auth, token, functionPath)
        except (jsonrpclib.Fault, AttributeError) as f:
            self._cbRender(f, request, id, version)
        else:
            if not self.is_jsonp:
                request.setHeader("content-type", "application/json")
            else:
                request.setHeader("content-type", "text/javascript")

            if hasattr(function, 'with_request'):
                args = [request] + args
            elif d:
                d.addCallback(context.call, function, *args, **kwargs)
            else:
                d = maybeDeferred(function, *args, **kwargs)
            d.addErrback(self._ebRender, id)
            d.addCallback(self._cbRender, request, id, version)

            def _responseFailed(err, call):
                call.cancel()
            request.notifyFinish().addErrback(_responseFailed, d)
        return server.NOT_DONE_YET
예제 #27
0
파일: server.py 프로젝트: bitspill/lbry
    def render(self, request):
        notify_finish = request.notifyFinish()
        assert self._check_headers(request), InvalidHeaderError
        session = request.getSession()
        session_id = session.uid

        if self._use_authentication:
            # if this is a new session, send a new secret and set the expiration
            # otherwise, session.touch()
            if self._initialize_session(session_id):

                def expire_session():
                    self._unregister_user_session(session_id)

                session.startCheckingExpiration()
                session.notifyOnExpire(expire_session)
                message = "OK"
                request.setResponseCode(self.OK)
                self._set_headers(request, message, True)
                self._render_message(request, message)
                return server.NOT_DONE_YET
            session.touch()

        request.content.seek(0, 0)
        content = request.content.read()
        try:
            parsed = jsonrpclib.loads(content)
        except ValueError as err:
            log.warning("Unable to decode request json")
            self._render_error(err, request)
            return server.NOT_DONE_YET

        function_name = parsed.get('method')
        args = parsed.get('params')
        id = parsed.get('id')
        token = parsed.pop('hmac', None)
        version = self._get_jsonrpc_version(parsed.get('jsonrpc'), id)

        try:
            self._run_subhandlers(request)
        except SubhandlerError as err:
            self._render_error(err, request, version)
            return server.NOT_DONE_YET

        reply_with_next_secret = False
        if self._use_authentication:
            if function_name in self.authorized_functions:
                try:
                    self._verify_token(session_id, parsed, token)
                except InvalidAuthenticationToken as err:
                    log.warning("API validation failed")
                    self._render_error(
                        err,
                        request,
                        version=version,
                        response_code=AuthJSONRPCServer.UNAUTHORIZED)
                    return server.NOT_DONE_YET
                self._update_session_secret(session_id)
                reply_with_next_secret = True

        try:
            function = self._get_jsonrpc_method(function_name)
        except AttributeError as err:
            log.warning("Unknown method: %s", function_name)
            self._render_error(err, request, version)
            return server.NOT_DONE_YET

        if args == [{}]:
            d = defer.maybeDeferred(function)
        else:
            d = defer.maybeDeferred(function, *args)

        # cancel the response if the connection is broken
        notify_finish.addErrback(self._response_failed, d)
        d.addCallback(self._callback_render, request, version,
                      reply_with_next_secret)
        d.addErrback(self._log_and_render_error, request, version=version)
        return server.NOT_DONE_YET
예제 #28
0
파일: server.py 프로젝트: wuhuaping/lbry
    def _render(self, request):
        time_in = utils.now()
        # assert self._check_headers(request), InvalidHeaderError
        session = request.getSession()
        session_id = session.uid
        finished_deferred = request.notifyFinish()

        if self._use_authentication:
            # if this is a new session, send a new secret and set the expiration
            # otherwise, session.touch()
            if self._initialize_session(session_id):

                def expire_session():
                    self._unregister_user_session(session_id)

                session.startCheckingExpiration()
                session.notifyOnExpire(expire_session)
                message = "OK"
                request.setResponseCode(200)
                self._set_headers(request, message, True)
                self._render_message(request, message)
                return server.NOT_DONE_YET
            else:
                session.touch()

        request.content.seek(0, 0)
        content = request.content.read()
        try:
            parsed = jsonrpclib.loads(content)
        except ValueError:
            log.warning("Unable to decode request json")
            self._render_error(
                JSONRPCError(None, JSONRPCError.CODE_PARSE_ERROR), request,
                None)
            return server.NOT_DONE_YET

        id_ = None
        try:
            function_name = parsed.get('method')
            is_queued = function_name in self.queued_methods
            args = parsed.get('params', {})
            id_ = parsed.get('id', None)
            token = parsed.pop('hmac', None)
        except AttributeError as err:
            log.warning(err)
            self._render_error(
                JSONRPCError(None, code=JSONRPCError.CODE_INVALID_REQUEST),
                request, id_)
            return server.NOT_DONE_YET

        reply_with_next_secret = False
        if self._use_authentication:
            if function_name in self.authorized_functions:
                try:
                    self._verify_token(session_id, parsed, token)
                except InvalidAuthenticationToken as err:
                    log.warning("API validation failed")
                    self._render_error(
                        JSONRPCError.create_from_exception(
                            err.message,
                            code=JSONRPCError.CODE_AUTHENTICATION_ERROR,
                            traceback=format_exc()), request, id_)
                    return server.NOT_DONE_YET
                self._update_session_secret(session_id)
                reply_with_next_secret = True

        try:
            function = self._get_jsonrpc_method(function_name)
        except UnknownAPIMethodError as err:
            log.warning('Failed to get function %s: %s', function_name, err)
            self._render_error(
                JSONRPCError(None, JSONRPCError.CODE_METHOD_NOT_FOUND),
                request, id_)
            return server.NOT_DONE_YET
        except NotAllowedDuringStartupError as err:
            log.warning('Function not allowed during startup %s: %s',
                        function_name, err)
            self._render_error(
                JSONRPCError(
                    "This method is unavailable until the daemon is fully started",
                    code=JSONRPCError.CODE_INVALID_REQUEST), request, id_)
            return server.NOT_DONE_YET
        except DeprecatedAPIMethodError:
            log.warning('API function is deprecated %s', function_name)
            self._render_error(
                JSONRPCError(None, JSONRPCError.CODE_METHOD_NOT_FOUND),
                request, id_)
            return server.NOT_DONE_YET

        if args == EMPTY_PARAMS or args == []:
            args_dict = {}
            _args, _kwargs = (), {}
        elif isinstance(args, dict):
            args_dict = args
        elif len(args) == 1 and isinstance(args[0], dict):
            # TODO: this is for backwards compatibility. Remove this once API and UI are updated
            # TODO: also delete EMPTY_PARAMS then
            args_dict = args[0]
            _args, _kwargs = (), args
        elif isinstance(args, list):
            _args, _kwargs = args, {}
        else:
            # d = defer.maybeDeferred(function, *args)  # if we want to support positional args too
            raise ValueError('Args must be a dict')

        params_error, erroneous_params = self._check_params(
            function, args_dict)
        if params_error is not None:
            params_error_message = '{} for {} command: {}'.format(
                params_error, function_name, ', '.join(erroneous_params))
            log.warning(params_error_message)
            self._render_error(
                JSONRPCError(params_error_message,
                             code=JSONRPCError.CODE_INVALID_PARAMS), request,
                id_)
            return server.NOT_DONE_YET

        if is_queued:
            d_lock = self._call_lock.get(function_name, False)
            if not d_lock:
                d = defer.maybeDeferred(function, self, **args_dict)
                self._call_lock[function_name] = finished_deferred

                def _del_lock(*args):
                    if function_name in self._call_lock:
                        del self._call_lock[function_name]
                    if args:
                        return args

                finished_deferred.addCallback(_del_lock)

            else:
                log.info("queued %s", function_name)
                d = d_lock
                d.addBoth(
                    lambda _: log.info("running %s from queue", function_name))
                d.addCallback(
                    lambda _: defer.maybeDeferred(function, self, **args_dict))
        else:
            d = defer.maybeDeferred(function, self, **args_dict)

        # finished_deferred will callback when the request is finished
        # and errback if something went wrong. If the errback is
        # called, cancel the deferred stack. This is to prevent
        # request.finish() from being called on a closed request.
        finished_deferred.addErrback(self._handle_dropped_request, d,
                                     function_name)

        d.addCallback(self._callback_render, request, id_,
                      reply_with_next_secret)
        # TODO: don't trap RuntimeError, which is presently caught to
        # handle deferredLists that won't peacefully cancel, namely
        # get_lbry_files
        d.addErrback(trap, ConnectionDone, ConnectionLost,
                     defer.CancelledError, RuntimeError)
        d.addErrback(log.fail(self._render_error, request, id_),
                     'Failed to process %s', function_name)
        d.addBoth(lambda _: log.debug("%s took %f", function_name,
                                      (utils.now() - time_in).total_seconds()))
        return server.NOT_DONE_YET
예제 #29
0
파일: server.py 프로젝트: Fillerix99/lbry
    def render(self, request):
        time_in = utils.now()
        assert self._check_headers(request), InvalidHeaderError
        session = request.getSession()
        session_id = session.uid
        finished_deferred = request.notifyFinish()

        if self._use_authentication:
            # if this is a new session, send a new secret and set the expiration
            # otherwise, session.touch()
            if self._initialize_session(session_id):
                def expire_session():
                    self._unregister_user_session(session_id)

                session.startCheckingExpiration()
                session.notifyOnExpire(expire_session)
                message = "OK"
                request.setResponseCode(self.OK)
                self._set_headers(request, message, True)
                self._render_message(request, message)
                return server.NOT_DONE_YET
            else:
                session.touch()

        request.content.seek(0, 0)
        content = request.content.read()
        try:
            parsed = jsonrpclib.loads(content)
        except ValueError:
            log.warning("Unable to decode request json")
            self._render_error_string('Invalid JSON', request, None)
            return server.NOT_DONE_YET

        function_name = parsed.get('method')
        args = parsed.get('params', {})
        id_ = parsed.get('id')
        token = parsed.pop('hmac', None)
        version = self._get_jsonrpc_version(parsed.get('jsonrpc'), id_)

        reply_with_next_secret = False
        if self._use_authentication:
            if function_name in self.authorized_functions:
                try:
                    self._verify_token(session_id, parsed, token)
                except InvalidAuthenticationToken as err:
                    log.warning("API validation failed")
                    self._render_error(
                        err, request, id_, version=version,
                        response_code=AuthJSONRPCServer.UNAUTHORIZED)
                    return server.NOT_DONE_YET
                self._update_session_secret(session_id)
                reply_with_next_secret = True

        try:
            function = self._get_jsonrpc_method(function_name)
        except (UnknownAPIMethodError, NotAllowedDuringStartupError) as err:
            log.warning('Failed to get function %s: %s', function_name, err)
            self._render_error(err, request, version)
            return server.NOT_DONE_YET

        if args == EMPTY_PARAMS or args == []:
            d = defer.maybeDeferred(function)
        elif isinstance(args, dict):
            d = defer.maybeDeferred(function, **args)
        elif len(args) == 1 and isinstance(args[0], dict):
            # TODO: this is for backwards compatibility. Remove this once API and UI are updated
            # TODO: also delete EMPTY_PARAMS then
            d = defer.maybeDeferred(function, **args[0])
        else:
            # d = defer.maybeDeferred(function, *args)  # if we want to support positional args too
            raise ValueError('Args must be a dict')

        # finished_deferred will callback when the request is finished
        # and errback if something went wrong. If the errback is
        # called, cancel the deferred stack. This is to prevent
        # request.finish() from being called on a closed request.
        finished_deferred.addErrback(self._handle_dropped_request, d, function_name)

        d.addCallback(self._callback_render, request, id_, version, reply_with_next_secret)
        # TODO: don't trap RuntimeError, which is presently caught to
        # handle deferredLists that won't peacefully cancel, namely
        # get_lbry_files
        d.addErrback(trap, ConnectionDone, ConnectionLost, defer.CancelledError, RuntimeError)
        d.addErrback(log.fail(self._render_error, request, id_, version=version),
                     'Failed to process %s', function_name)
        d.addBoth(lambda _: log.debug("%s took %f",
                                      function_name,
                                      (utils.now() - time_in).total_seconds()))
        return server.NOT_DONE_YET
예제 #30
0
    def render(self, request):
        if self.open_cors:
            request.setHeader("Access-Control-Allow-Origin", "*")
        from_ip = ""
        if request.getHeader("x-forwarded-for"):
            from_ip = " from %s" % request.getHeader("x-forwarded-for")
        # Unmarshal the JSON-RPC data.
        request.content.seek(0, 0)
        content = request.content.read()
        if not content and request.method == 'GET' and 'request' in request.args:
            content = request.args['request'][0]
        self.callback = request.args['callback'][
            0] if 'callback' in request.args else None
        self.is_jsonp = True if self.callback else False
        try:
            parsed = jsonrpclib.loads(content)
        except ValueError:
            parsed = {"content": content, "method": None, "params": {}}
        functionPath = parsed.get("method")

        if self.debug:
            parsedcopy = deepcopy(parsed)
            if functionPath in ["start_corpus", "create_corpus"
                                ] and len(parsedcopy["params"]) > 1:
                parsedcopy["params"][1] = "********"
            self.safe_log(parsedcopy, "DEBUG - QUERY%s" % from_ip)

        params = parsed.get('params', {})
        args, kwargs = [], {}
        if params.__class__ == list:
            args = params
        else:
            kwargs = params
        id = parsed.get('id')
        token = None
        #if request.requestHeaders.hasHeader(self.auth_token):
        #    token = request.requestHeaders.getRawHeaders(self.auth_token)[0]
        version = parsed.get('jsonrpc')
        if version:
            version = int(float(version))
        elif id and not version:
            version = jsonrpclib.VERSION_1
        else:
            version = jsonrpclib.VERSION_PRE1
        if not functionPath:
            self._cbRender({}, request, id, version)
            return server.NOT_DONE_YET
        try:
            function = self._getFunction(functionPath)
            d = None
            #if hasattr(function, 'requires_auth'):
            #    d = maybeDeferred(self.auth, token, functionPath)
        except (jsonrpclib.Fault, AttributeError) as f:
            self._cbRender(f, request, id, version)
        else:
            if not self.is_jsonp:
                request.setHeader("content-type", "application/json")
            else:
                request.setHeader("content-type", "text/javascript")

            if hasattr(function, 'with_request'):
                args = [request] + args
            elif d:
                d.addCallback(context.call, function, *args, **kwargs)
            else:
                d = maybeDeferred(function, *args, **kwargs)
            d.addErrback(self._ebRender, id)
            d.addCallback(self._cbRender, request, id, version)

            def _responseFailed(err, call):
                call.cancel()

            request.notifyFinish().addErrback(_responseFailed, d)
        return server.NOT_DONE_YET