mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-21 17:01:35 +00:00
save commit
This commit is contained in:
@ -128,20 +128,26 @@ func makeJSONRPCHandler(funcMap map[string]*RPCFunc, cdc *amino.Codec, logger lo
|
||||
WriteRPCResponseHTTP(w, types.RPCInvalidRequestError(request.ID, errors.Errorf("Path %s is invalid", r.URL.Path)))
|
||||
return
|
||||
}
|
||||
|
||||
rpcFunc := funcMap[request.Method]
|
||||
if rpcFunc == nil || rpcFunc.ws {
|
||||
WriteRPCResponseHTTP(w, types.RPCMethodNotFoundError(request.ID))
|
||||
return
|
||||
}
|
||||
var args []reflect.Value
|
||||
|
||||
ctx := &types.Context{JSONReq: &request, HTTPReq: r}
|
||||
args := []reflect.Value{reflect.ValueOf(ctx)}
|
||||
if len(request.Params) > 0 {
|
||||
args, err = jsonParamsToArgsRPC(rpcFunc, cdc, request.Params)
|
||||
fnArgs, err := jsonParamsToArgs(rpcFunc, cdc, request.Params)
|
||||
if err != nil {
|
||||
WriteRPCResponseHTTP(w, types.RPCInvalidParamsError(request.ID, errors.Wrap(err, "Error converting json params to arguments")))
|
||||
return
|
||||
}
|
||||
args = append(args, fnArgs...)
|
||||
}
|
||||
|
||||
returns := rpcFunc.f.Call(args)
|
||||
|
||||
logger.Info("HTTPJSONRPC", "method", request.Method, "args", args, "returns", returns)
|
||||
result, err := unreflectResult(returns)
|
||||
if err != nil {
|
||||
@ -204,13 +210,14 @@ func arrayParamsToArgs(rpcFunc *RPCFunc, cdc *amino.Codec, params []json.RawMess
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// `raw` is unparsed json (from json.RawMessage) encoding either a map or an array.
|
||||
// `argsOffset` should be 0 for RPC calls, and 1 for WS requests, where len(rpcFunc.args) != len(rpcFunc.argNames).
|
||||
// raw is unparsed json (from json.RawMessage) encoding either a map or an
|
||||
// array.
|
||||
//
|
||||
// Example:
|
||||
// rpcFunc.args = [rpctypes.WSRPCContext string]
|
||||
// rpcFunc.args = [rpctypes.Context string]
|
||||
// rpcFunc.argNames = ["arg"]
|
||||
func jsonParamsToArgs(rpcFunc *RPCFunc, cdc *amino.Codec, raw []byte, argsOffset int) ([]reflect.Value, error) {
|
||||
func jsonParamsToArgs(rpcFunc *RPCFunc, cdc *amino.Codec, raw []byte) ([]reflect.Value, error) {
|
||||
const argsOffset = 1
|
||||
|
||||
// TODO: Make more efficient, perhaps by checking the first character for '{' or '['?
|
||||
// First, try to get the map.
|
||||
@ -231,20 +238,6 @@ func jsonParamsToArgs(rpcFunc *RPCFunc, cdc *amino.Codec, raw []byte, argsOffset
|
||||
return nil, errors.Errorf("Unknown type for JSON params: %v. Expected map or array", err)
|
||||
}
|
||||
|
||||
// Convert a []interface{} OR a map[string]interface{} to properly typed values
|
||||
func jsonParamsToArgsRPC(rpcFunc *RPCFunc, cdc *amino.Codec, params json.RawMessage) ([]reflect.Value, error) {
|
||||
return jsonParamsToArgs(rpcFunc, cdc, params, 0)
|
||||
}
|
||||
|
||||
// Same as above, but with the first param the websocket connection
|
||||
func jsonParamsToArgsWS(rpcFunc *RPCFunc, cdc *amino.Codec, params json.RawMessage, wsCtx types.WSRPCContext) ([]reflect.Value, error) {
|
||||
values, err := jsonParamsToArgs(rpcFunc, cdc, params, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return append([]reflect.Value{reflect.ValueOf(wsCtx)}, values...), nil
|
||||
}
|
||||
|
||||
// rpc.json
|
||||
//-----------------------------------------------------------------------------
|
||||
// rpc.http
|
||||
@ -257,15 +250,23 @@ func makeHTTPHandler(rpcFunc *RPCFunc, cdc *amino.Codec, logger log.Logger) func
|
||||
WriteRPCResponseHTTP(w, types.RPCMethodNotFoundError(types.JSONRPCStringID("")))
|
||||
}
|
||||
}
|
||||
|
||||
// All other endpoints
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
logger.Debug("HTTP HANDLER", "req", r)
|
||||
args, err := httpParamsToArgs(rpcFunc, cdc, r)
|
||||
|
||||
ctx := &types.Context{HTTPReq: r}
|
||||
args := []reflect.Value{reflect.ValueOf(ctx)}
|
||||
|
||||
fnArgs, err := httpParamsToArgs(rpcFunc, cdc, r)
|
||||
if err != nil {
|
||||
WriteRPCResponseHTTP(w, types.RPCInvalidParamsError(types.JSONRPCStringID(""), errors.Wrap(err, "Error converting http params to arguments")))
|
||||
return
|
||||
}
|
||||
args = append(args, fnArgs...)
|
||||
|
||||
returns := rpcFunc.f.Call(args)
|
||||
|
||||
logger.Info("HTTPRestRPC", "method", r.URL.Path, "args", args, "returns", returns)
|
||||
result, err := unreflectResult(returns)
|
||||
if err != nil {
|
||||
@ -621,27 +622,23 @@ func (wsc *wsConnection) readRoutine() {
|
||||
}
|
||||
|
||||
// Now, fetch the RPCFunc and execute it.
|
||||
|
||||
rpcFunc := wsc.funcMap[request.Method]
|
||||
if rpcFunc == nil {
|
||||
wsc.WriteRPCResponse(types.RPCMethodNotFoundError(request.ID))
|
||||
continue
|
||||
}
|
||||
var args []reflect.Value
|
||||
if rpcFunc.ws {
|
||||
wsCtx := types.WSRPCContext{Request: request, WSRPCConnection: wsc}
|
||||
if len(request.Params) > 0 {
|
||||
args, err = jsonParamsToArgsWS(rpcFunc, wsc.cdc, request.Params, wsCtx)
|
||||
}
|
||||
} else {
|
||||
if len(request.Params) > 0 {
|
||||
args, err = jsonParamsToArgsRPC(rpcFunc, wsc.cdc, request.Params)
|
||||
|
||||
ctx := &types.Context{JSONReq: &request, WSConn: wsc}
|
||||
args := []reflect.Value{reflect.ValueOf(ctx)}
|
||||
if len(request.Params) > 0 {
|
||||
fnArgs, err := jsonParamsToArgs(rpcFunc, wsc.cdc, request.Params)
|
||||
if err != nil {
|
||||
wsc.WriteRPCResponse(types.RPCInternalError(request.ID, errors.Wrap(err, "Error converting json params to arguments")))
|
||||
continue
|
||||
}
|
||||
args = append(args, fnArgs...)
|
||||
}
|
||||
if err != nil {
|
||||
wsc.WriteRPCResponse(types.RPCInternalError(request.ID, errors.Wrap(err, "Error converting json params to arguments")))
|
||||
continue
|
||||
}
|
||||
|
||||
returns := rpcFunc.f.Call(args)
|
||||
|
||||
// TODO: Need to encode args/returns to string if we want to log them
|
||||
|
Reference in New Issue
Block a user