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.
This commit is contained in:
Harshavardhana 2016-02-13 18:50:21 -08:00
parent 40e8893fb9
commit e59ceba51b
3 changed files with 27 additions and 16 deletions

View File

@ -71,7 +71,7 @@ type Service1Request struct {
B int
}
type Service1BadRequest struct {
type Service1NoParamsRequest struct {
V string `json:"jsonrpc"`
M string `json:"method"`
ID uint64 `json:"id"`
@ -84,8 +84,15 @@ type Service1Response struct {
type Service1 struct {
}
const Service1DefaultResponse = 9999
func (t *Service1) Multiply(r *http.Request, req *Service1Request, res *Service1Response) error {
res.Result = req.A * req.B
if req.A == 0 && req.B == 0 {
// Sentinel value for test with no params.
res.Result = Service1DefaultResponse
} else {
res.Result = req.A * req.B
}
return nil
}
@ -139,8 +146,13 @@ func TestService(t *testing.T) {
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 {
t.Errorf("Expected error but error in nil")
// No parameters.
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)
}
}

View File

@ -125,22 +125,21 @@ func (c *CodecRequest) Method() (string, error) {
// ReadRe<quest fills the request object for the RPC method.
func (c *CodecRequest) ReadRequest(args interface{}) error {
if c.err == nil {
if c.request.Params != nil {
// JSON params structured object. Unmarshal to the args object.
err := json.Unmarshal(*c.request.Params, args)
if err != nil {
if c.err == nil && 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.
if err := json.Unmarshal(*c.request.Params, args); 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{
Code: E_INVALID_REQ,
Message: err.Error(),
Data: c.request.Params,
}
}
} else {
c.err = &Error{
Code: E_INVALID_REQ,
Message: "rpc: method request ill-formed: missing params field",
}
}
}
return c.err

4
vendor/vendor.json vendored
View File

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