Browse Source

Merge pull request #18 from tendermint/bugfix/fix-backward-compatibility-for-ws

fix backward compatibility for WS
pull/456/head
Ethan Buchman 8 years ago
committed by GitHub
parent
commit
559613689d
2 changed files with 37 additions and 4 deletions
  1. +28
    -0
      rpc_test.go
  2. +9
    -4
      server/handlers.go

+ 28
- 0
rpc_test.go View File

@ -261,6 +261,34 @@ func TestWSNewWSRPCFunc(t *testing.T) {
} }
} }
func TestWSHandlesArrayParams(t *testing.T) {
cl := client.NewWSClient(tcpAddr, websocketEndpoint)
_, err := cl.Start()
require.Nil(t, err)
defer cl.Stop()
val := "acbd"
params := []interface{}{val}
err = cl.WriteJSON(types.RPCRequest{
JSONRPC: "2.0",
ID: "",
Method: "echo_ws",
Params: params,
})
require.Nil(t, err)
select {
case msg := <-cl.ResultsCh:
result := new(Result)
wire.ReadJSONPtr(result, msg, &err)
require.Nil(t, err)
got := (*result).(*ResultEcho).Value
assert.Equal(t, got, val)
case err := <-cl.ErrorsCh:
t.Fatalf("%+v", err)
}
}
func randBytes(t *testing.T) []byte { func randBytes(t *testing.T) []byte {
n := rand.Intn(10) + 2 n := rand.Intn(10) + 2
buf := make([]byte, n) buf := make([]byte, n)


+ 9
- 4
server/handlers.go View File

@ -124,7 +124,7 @@ func makeJSONRPCHandler(funcMap map[string]*RPCFunc) http.HandlerFunc {
WriteRPCResponseHTTP(w, types.NewRPCResponse(request.ID, nil, "RPC method is only for websockets: "+request.Method)) WriteRPCResponseHTTP(w, types.NewRPCResponse(request.ID, nil, "RPC method is only for websockets: "+request.Method))
return return
} }
args, err := jsonParamsToArgs(rpcFunc, request.Params, 0)
args, err := jsonParamsToArgsRPC(rpcFunc, request.Params)
if err != nil { if err != nil {
WriteRPCResponseHTTP(w, types.NewRPCResponse(request.ID, nil, fmt.Sprintf("Error converting json params to arguments: %v", err.Error()))) WriteRPCResponseHTTP(w, types.NewRPCResponse(request.ID, nil, fmt.Sprintf("Error converting json params to arguments: %v", err.Error())))
return return
@ -142,7 +142,7 @@ func makeJSONRPCHandler(funcMap map[string]*RPCFunc) http.HandlerFunc {
// Convert a []interface{} OR a map[string]interface{} to properly typed values // Convert a []interface{} OR a map[string]interface{} to properly typed values
// //
// argsOffset is used in jsonParamsToArgsWS, where len(rpcFunc.args) != len(rpcFunc.argNames).
// argsOffset should be 0 for RPC calls, and 1 for WS requests, where len(rpcFunc.args) != len(rpcFunc.argNames).
// Example: // Example:
// rpcFunc.args = [rpctypes.WSRPCContext string] // rpcFunc.args = [rpctypes.WSRPCContext string]
// rpcFunc.argNames = ["arg"] // rpcFunc.argNames = ["arg"]
@ -173,7 +173,7 @@ func jsonParamsToArgs(rpcFunc *RPCFunc, paramsI interface{}, argsOffset int) ([]
} }
values := make([]reflect.Value, len(params)) values := make([]reflect.Value, len(params))
for i, p := range params { for i, p := range params {
ty := rpcFunc.args[i]
ty := rpcFunc.args[i+argsOffset]
v, err := _jsonObjectToArg(ty, p) v, err := _jsonObjectToArg(ty, p)
if err != nil { if err != nil {
return nil, err return nil, err
@ -187,6 +187,11 @@ func jsonParamsToArgs(rpcFunc *RPCFunc, paramsI interface{}, argsOffset int) ([]
return values, nil return values, nil
} }
// Convert a []interface{} OR a map[string]interface{} to properly typed values
func jsonParamsToArgsRPC(rpcFunc *RPCFunc, paramsI interface{}) ([]reflect.Value, error) {
return jsonParamsToArgs(rpcFunc, paramsI, 0)
}
// Same as above, but with the first param the websocket connection // Same as above, but with the first param the websocket connection
func jsonParamsToArgsWS(rpcFunc *RPCFunc, paramsI interface{}, wsCtx types.WSRPCContext) ([]reflect.Value, error) { func jsonParamsToArgsWS(rpcFunc *RPCFunc, paramsI interface{}, wsCtx types.WSRPCContext) ([]reflect.Value, error) {
values, err := jsonParamsToArgs(rpcFunc, paramsI, 1) values, err := jsonParamsToArgs(rpcFunc, paramsI, 1)
@ -494,7 +499,7 @@ func (wsc *wsConnection) readRoutine() {
wsCtx := types.WSRPCContext{Request: request, WSRPCConnection: wsc} wsCtx := types.WSRPCContext{Request: request, WSRPCConnection: wsc}
args, err = jsonParamsToArgsWS(rpcFunc, request.Params, wsCtx) args, err = jsonParamsToArgsWS(rpcFunc, request.Params, wsCtx)
} else { } else {
args, err = jsonParamsToArgs(rpcFunc, request.Params, 0)
args, err = jsonParamsToArgsRPC(rpcFunc, request.Params)
} }
if err != nil { if err != nil {
wsc.WriteRPCResponse(types.NewRPCResponse(request.ID, nil, err.Error())) wsc.WriteRPCResponse(types.NewRPCResponse(request.ID, nil, err.Error()))


Loading…
Cancel
Save