From 86506cd4f83f67c307e5f32ad8ca39a337158fe8 Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Sat, 7 Jan 2017 14:21:10 -0800 Subject: [PATCH] Handle quoted and hex string type HTTP args for both 'string' and '[]byte' type function args --- client/http_client.go | 9 +----- server/handlers.go | 66 ++++++++++++++++++++++++++++--------------- 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/client/http_client.go b/client/http_client.go index 54fbd1c2..57da5d6e 100644 --- a/client/http_client.go +++ b/client/http_client.go @@ -121,7 +121,7 @@ func (c *ClientURI) call(method string, params map[string]interface{}, result in if err != nil { return nil, err } - log.Info(Fmt("URI request to %v (%v): %v", c.address, method, values)) + // log.Info(Fmt("URI request to %v (%v): %v", c.address, method, values)) resp, err := c.client.PostForm(c.address+"/"+method, values) if err != nil { return nil, err @@ -178,13 +178,6 @@ func argsToJson(args map[string]interface{}) error { var n int var err error for k, v := range args { - // Convert strings to "0x"-prefixed hex - str, isString := reflect.ValueOf(v).Interface().(string) - if isString { - args[k] = fmt.Sprintf("0x%X", str) - continue - } - // Convert byte slices to "0x"-prefixed hex byteSlice, isByteSlice := reflect.ValueOf(v).Interface().([]byte) if isByteSlice { diff --git a/server/handlers.go b/server/handlers.go index f5730213..7a4ec1a4 100644 --- a/server/handlers.go +++ b/server/handlers.go @@ -225,36 +225,18 @@ func httpParamsToArgs(rpcFunc *RPCFunc, r *http.Request) ([]reflect.Value, error argTypes := rpcFunc.args argNames := rpcFunc.argNames - var err error values := make([]reflect.Value, len(argNames)) for i, name := range argNames { ty := argTypes[i] arg := GetParam(r, name) // log.Notice("param to arg", "ty", ty, "name", name, "arg", arg) - // Handle quoted strings - if strings.HasPrefix(arg, "\"") && strings.HasSuffix(arg, "\"") { - data := arg[1 : len(arg)-1] - if ty.Kind() == reflect.String { - values[i] = reflect.ValueOf(string(data)) - } else { - values[i] = reflect.ValueOf(data) - } - continue + v, err, ok := nonJsonToArg(ty, arg) + if err != nil { + return nil, err } - - // Handle hex strings - if strings.HasPrefix(strings.ToLower(arg), "0x") { - var value []byte - value, err = hex.DecodeString(arg[2:]) - if err != nil { - return nil, err - } - if ty.Kind() == reflect.String { - values[i] = reflect.ValueOf(string(value)) - } else { - values[i] = reflect.ValueOf(value) - } + if ok { + values[i] = v continue } @@ -278,6 +260,44 @@ func _jsonStringToArg(ty reflect.Type, arg string) (reflect.Value, error) { return v, nil } +func nonJsonToArg(ty reflect.Type, arg string) (reflect.Value, error, bool) { + isQuotedString := strings.HasPrefix(arg, `"`) && strings.HasSuffix(arg, `"`) + isHexString := strings.HasPrefix(strings.ToLower(arg), "0x") + expectingString := ty.Kind() == reflect.String + expectingByteSlice := ty.Kind() == reflect.Slice && ty.Elem().Kind() == reflect.Uint8 + + if isHexString { + if !expectingString && !expectingByteSlice { + err := fmt.Errorf("Got a hex string arg, but expected '%s'", + ty.Kind().String()) + return reflect.ValueOf(nil), err, false + } + + var value []byte + value, err := hex.DecodeString(arg[2:]) + if err != nil { + return reflect.ValueOf(nil), err, false + } + if ty.Kind() == reflect.String { + return reflect.ValueOf(string(value)), nil, true + } + return reflect.ValueOf([]byte(value)), nil, true + } + + if isQuotedString && expectingByteSlice { + var err error + v := reflect.New(reflect.TypeOf("")) + wire.ReadJSONPtr(v.Interface(), []byte(arg), &err) + if err != nil { + return reflect.ValueOf(nil), err, false + } + v = v.Elem() + return reflect.ValueOf([]byte(v.String())), nil, true + } + + return reflect.ValueOf(nil), nil, false +} + // rpc.http //----------------------------------------------------------------------------- // rpc.websocket