github.com/number571/tendermint@v0.34.11-gost/rpc/jsonrpc/server/rpc_func.go (about) 1 package server 2 3 import ( 4 "net/http" 5 "reflect" 6 "strings" 7 8 "github.com/number571/tendermint/libs/log" 9 ) 10 11 // RegisterRPCFuncs adds a route for each function in the funcMap, as well as 12 // general jsonrpc and websocket handlers for all functions. "result" is the 13 // interface on which the result objects are registered, and is popualted with 14 // every RPCResponse 15 func RegisterRPCFuncs(mux *http.ServeMux, funcMap map[string]*RPCFunc, logger log.Logger) { 16 // HTTP endpoints 17 for funcName, rpcFunc := range funcMap { 18 mux.HandleFunc("/"+funcName, makeHTTPHandler(rpcFunc, logger)) 19 } 20 21 // JSONRPC endpoints 22 mux.HandleFunc("/", handleInvalidJSONRPCPaths(makeJSONRPCHandler(funcMap, logger))) 23 } 24 25 // Function introspection 26 27 // RPCFunc contains the introspected type information for a function 28 type RPCFunc struct { 29 f reflect.Value // underlying rpc function 30 args []reflect.Type // type of each function arg 31 returns []reflect.Type // type of each return arg 32 argNames []string // name of each argument 33 ws bool // websocket only 34 cache bool // allow the RPC response can be cached by the proxy cache server 35 } 36 37 // NewRPCFunc wraps a function for introspection. 38 // f is the function, args are comma separated argument names 39 // cache is a bool value to allow the client proxy server to cache the RPC results 40 func NewRPCFunc(f interface{}, args string, cache bool) *RPCFunc { 41 return newRPCFunc(f, args, false, cache) 42 } 43 44 // NewWSRPCFunc wraps a function for introspection and use in the websockets. 45 func NewWSRPCFunc(f interface{}, args string) *RPCFunc { 46 return newRPCFunc(f, args, true, false) 47 } 48 49 func newRPCFunc(f interface{}, args string, ws bool, c bool) *RPCFunc { 50 var argNames []string 51 if args != "" { 52 argNames = strings.Split(args, ",") 53 } 54 return &RPCFunc{ 55 f: reflect.ValueOf(f), 56 args: funcArgTypes(f), 57 returns: funcReturnTypes(f), 58 argNames: argNames, 59 ws: ws, 60 cache: c, 61 } 62 } 63 64 // return a function's argument types 65 func funcArgTypes(f interface{}) []reflect.Type { 66 t := reflect.TypeOf(f) 67 n := t.NumIn() 68 typez := make([]reflect.Type, n) 69 for i := 0; i < n; i++ { 70 typez[i] = t.In(i) 71 } 72 return typez 73 } 74 75 // return a function's return types 76 func funcReturnTypes(f interface{}) []reflect.Type { 77 t := reflect.TypeOf(f) 78 n := t.NumOut() 79 typez := make([]reflect.Type, n) 80 for i := 0; i < n; i++ { 81 typez[i] = t.Out(i) 82 } 83 return typez 84 } 85 86 //------------------------------------------------------------- 87 88 // NOTE: assume returns is result struct and error. If error is not nil, return it 89 func unreflectResult(returns []reflect.Value) (interface{}, error) { 90 errV := returns[1] 91 if err, ok := errV.Interface().(error); ok && err != nil { 92 return nil, err 93 } 94 rv := returns[0] 95 // the result is a registered interface, 96 // we need a pointer to it so we can marshal with type byte 97 rvp := reflect.New(rv.Type()) 98 rvp.Elem().Set(rv) 99 return rvp.Interface(), nil 100 }