rpc: Fix json rpc to handle array and object request params.

rpc/v2/json2 code has a bug where it treats all jsonrpc 2.0
request params like an 'object'. In accordance with the spec
it could be both 'object' or an 'array'.

Handle both cases.
master
Harshavardhana 9 years ago
parent 40e8893fb9
commit e59ceba51b
  1. 18
      vendor/github.com/gorilla/rpc/v2/json2/json_test.go
  2. 17
      vendor/github.com/gorilla/rpc/v2/json2/server.go
  3. 4
      vendor/vendor.json

@ -71,7 +71,7 @@ type Service1Request struct {
B int B int
} }
type Service1BadRequest struct { type Service1NoParamsRequest struct {
V string `json:"jsonrpc"` V string `json:"jsonrpc"`
M string `json:"method"` M string `json:"method"`
ID uint64 `json:"id"` ID uint64 `json:"id"`
@ -84,8 +84,15 @@ type Service1Response struct {
type Service1 struct { type Service1 struct {
} }
const Service1DefaultResponse = 9999
func (t *Service1) Multiply(r *http.Request, req *Service1Request, res *Service1Response) error { func (t *Service1) Multiply(r *http.Request, req *Service1Request, res *Service1Response) error {
if req.A == 0 && req.B == 0 {
// Sentinel value for test with no params.
res.Result = Service1DefaultResponse
} else {
res.Result = req.A * req.B res.Result = req.A * req.B
}
return nil return nil
} }
@ -139,8 +146,13 @@ func TestService(t *testing.T) {
t.Errorf("Expected to get %q, but got %q", ErrResponseError, err) t.Errorf("Expected to get %q, but got %q", ErrResponseError, err)
} }
if err := executeRaw(t, s, &Service1BadRequest{"2.0", "Service1.Multiply", 1}, &res); err == nil { // No parameters.
t.Errorf("Expected error but error in nil") res = Service1Response{}
if err := executeRaw(t, s, &Service1NoParamsRequest{"2.0", "Service1.Multiply", 1}, &res); err != nil {
t.Error(err)
}
if res.Result != Service1DefaultResponse {
t.Errorf("Wrong response: got %v, want %v", res.Result, Service1DefaultResponse)
} }
} }

@ -125,22 +125,21 @@ func (c *CodecRequest) Method() (string, error) {
// ReadRe<quest fills the request object for the RPC method. // ReadRe<quest fills the request object for the RPC method.
func (c *CodecRequest) ReadRequest(args interface{}) error { func (c *CodecRequest) ReadRequest(args interface{}) error {
if c.err == nil { if c.err == nil && c.request.Params != nil {
if c.request.Params != nil { // Note: if c.request.Params is nil it's not an error, it's an optional member.
// JSON params structured object. Unmarshal to the args object. // JSON params structured object. Unmarshal to the args object.
err := json.Unmarshal(*c.request.Params, args) if err := json.Unmarshal(*c.request.Params, args); err != nil {
if err != nil { // Structed unmarshalling failed, attempt JSON params as
// array value. Unmarshal into array containing the
// request struct.
params := [1]interface{}{args}
if err = json.Unmarshal(*c.request.Params, &params); err != nil {
c.err = &Error{ c.err = &Error{
Code: E_INVALID_REQ, Code: E_INVALID_REQ,
Message: err.Error(), Message: err.Error(),
Data: c.request.Params, Data: c.request.Params,
} }
} }
} else {
c.err = &Error{
Code: E_INVALID_REQ,
Message: "rpc: method request ill-formed: missing params field",
}
} }
} }
return c.err return c.err

@ -44,8 +44,8 @@
}, },
{ {
"path": "github.com/gorilla/rpc/v2/json2", "path": "github.com/gorilla/rpc/v2/json2",
"revision": "839c4c31c6bb12c15f41802cf89325aa89439ac3", "revision": "64e20900b8aa38bb0771dec71ba3bcc2b07fc8ec",
"revisionTime": "2015-07-14T15:53:15-07:00" "revisionTime": "2015-11-05T07:45:51+08:00"
}, },
{ {
"path": "github.com/mattn/go-isatty", "path": "github.com/mattn/go-isatty",

Loading…
Cancel
Save