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