Improve JSON-RPC handling for raw requests/responses, Fixes #364 (#458)

This commit is contained in:
monokh 2017-11-27 18:53:33 +00:00 committed by Adam Babik
parent 69276386d2
commit 0a82e67379
2 changed files with 37 additions and 29 deletions

View File

@ -28,20 +28,31 @@ func (c *Client) CallRaw(body string) string {
return c.callRawContext(ctx, json.RawMessage(body))
}
// jsonrpcMessage represents JSON-RPC request, notification, successful response or
// error response.
// jsonrpcMessage represents JSON-RPC message
type jsonrpcMessage struct {
Version string `json:"jsonrpc"`
ID json.RawMessage `json:"id,omitempty"`
Method string `json:"method,omitempty"`
Params json.RawMessage `json:"params,omitempty"`
Error *jsonError `json:"error,omitempty"`
Result json.RawMessage `json:"result,omitempty"`
ID json.RawMessage `json:"id"`
}
type jsonrpcRequest struct {
jsonrpcMessage
Method string `json:"method"`
Params json.RawMessage `json:"params,omitempty"`
}
type jsonrpcSuccessfulResponse struct {
jsonrpcMessage
Result json.RawMessage `json:"result"`
}
type jsonrpcErrorResponse struct {
jsonrpcMessage
Error jsonError `json:"error"`
}
// jsonError represents Error message for JSON-RPC responses.
type jsonError struct {
Code int `json:"code,omitempty"`
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
}
@ -146,8 +157,8 @@ func methodAndParamsFromBody(body json.RawMessage) (string, []interface{}, json.
}
// unmarshalMessage tries to unmarshal JSON-RPC message.
func unmarshalMessage(body json.RawMessage) (*jsonrpcMessage, error) {
var msg jsonrpcMessage
func unmarshalMessage(body json.RawMessage) (*jsonrpcRequest, error) {
var msg jsonrpcRequest
err := json.Unmarshal(body, &msg)
return &msg, err
}
@ -157,17 +168,12 @@ func newSuccessResponse(result json.RawMessage, id json.RawMessage) string {
id = defaultMsgID
}
// original response with `null` is lost due to geth RPC client
// conversion (unmarshalling). We'll have nil result object in this case,
// so handle it specially. `result` is required field in response.
if result == nil {
result = json.RawMessage("null")
}
msg := &jsonrpcMessage{
ID: id,
Version: jsonrpcVersion,
Result: result,
msg := &jsonrpcSuccessfulResponse{
jsonrpcMessage: jsonrpcMessage{
ID: id,
Version: jsonrpcVersion,
},
Result: result,
}
data, _ := json.Marshal(msg)
return string(data)
@ -178,10 +184,12 @@ func newErrorResponse(code int, err error, id json.RawMessage) string {
id = defaultMsgID
}
errMsg := &jsonrpcMessage{
Version: jsonrpcVersion,
ID: id,
Error: &jsonError{
errMsg := &jsonrpcErrorResponse{
jsonrpcMessage: jsonrpcMessage{
ID: id,
Version: jsonrpcVersion,
},
Error: jsonError{
Code: code,
Message: err.Error(),
},

View File

@ -42,10 +42,10 @@ func TestUnmarshalMessage(t *testing.T) {
got, err := unmarshalMessage(body)
require.NoError(t, err)
expected := &jsonrpcMessage{
Version: "2.0",
Method: "subtract",
Params: json.RawMessage(`{"subtrahend": 23, "minuend": 42}`),
expected := &jsonrpcRequest{
jsonrpcMessage: jsonrpcMessage{Version: "2.0"},
Method: "subtract",
Params: json.RawMessage(`{"subtrahend": 23, "minuend": 42}`),
}
require.Equal(t, expected, got)
}