rpc/protocol/json/server_request.go

145 lines
4.0 KiB
Go
Raw Permalink Normal View History

2017-11-26 10:15:51 +00:00
package json
import (
2018-03-23 03:22:16 +00:00
"encoding/json"
2017-11-26 10:15:51 +00:00
"git.loafle.net/commons_go/rpc/protocol"
2018-03-20 06:31:54 +00:00
crp "git.loafle.net/commons_go/rpc/protocol"
cuej "git.loafle.net/commons_go/util/encoding/json"
2017-11-26 10:15:51 +00:00
)
// ----------------------------------------------------------------------------
// Request
// ----------------------------------------------------------------------------
// serverRequest represents a JSON-RPC request received by the server.
type serverRequest struct {
// JSON-RPC protocol.
Version string `json:"jsonrpc"`
// A String containing the name of the method to be invoked.
Method string `json:"method"`
// A Structured value to pass as arguments to the method.
Params *json.RawMessage `json:"params,omitempty"`
// The request id. MUST be a string, number or null.
// Our implementation will not do type checking for id.
// It will be copied as it is.
ID *json.RawMessage `json:"id,omitempty"`
}
// ----------------------------------------------------------------------------
// ServerRequestCodec
// ----------------------------------------------------------------------------
// newRequestCodec returns a new ServerRequestCodec.
2018-03-23 17:26:41 +00:00
func newServerRequestCodec(buf []byte) (protocol.ServerRequestCodec, error) {
2018-03-23 13:45:48 +00:00
req := &serverRequest{}
err := json.Unmarshal(buf, req)
if err != nil {
2018-03-27 11:23:43 +00:00
err = &crp.Error{
2018-03-23 13:45:48 +00:00
Code: crp.E_PARSE,
Message: err.Error(),
Data: req,
}
}
if req.Version != Version {
2018-03-27 11:23:43 +00:00
err = &crp.Error{
2018-03-23 13:45:48 +00:00
Code: crp.E_INVALID_REQ,
Message: "jsonrpc must be " + Version,
Data: req,
}
}
return &ServerRequestCodec{req: req, err: err}, nil
}
2017-11-26 10:15:51 +00:00
// ServerRequestCodec decodes and encodes a single request.
type ServerRequestCodec struct {
2018-03-23 07:43:05 +00:00
req *serverRequest
err error
2017-11-26 10:15:51 +00:00
}
2018-03-22 15:41:28 +00:00
func (src *ServerRequestCodec) HasResponse() bool {
return src.req.ID != nil
}
2017-11-26 10:15:51 +00:00
// Method returns the RPC method for the current request.
//
// The method uses a dotted notation as in "Service.Method".
func (src *ServerRequestCodec) Method() string {
return src.req.Method
}
// ReadRequest fills the request object for the RPC method.
//
// ReadRequest parses request parameters in two supported forms in
// accordance with http://www.jsonrpc.org/specification#parameter_structures
//
// by-position: params MUST be an Array, containing the
// values in the Server expected order.
//
// by-name: params MUST be an Object, with member names
// that match the Server expected parameter names. The
// absence of expected names MAY result in an error being
// generated. The names MUST match exactly, including
// case, to the method's expected parameters.
func (src *ServerRequestCodec) ReadParams(args []interface{}) error {
if src.err == nil && src.req.Params != nil {
2018-03-20 06:31:54 +00:00
// Note: if scr.request.Params is nil it's not an error, it's an optional member.
2017-11-26 10:15:51 +00:00
// JSON params structured object. Unmarshal to the args object.
2018-03-20 06:31:54 +00:00
if err := cuej.SetValueWithJSONStringArray(*src.req.Params, args); nil != err {
2018-03-27 11:23:43 +00:00
src.err = &crp.Error{
2018-03-20 06:31:54 +00:00
Code: crp.E_INVALID_REQ,
2017-11-26 10:15:51 +00:00
Message: err.Error(),
Data: src.req.Params,
}
return src.err
}
2018-03-20 06:31:54 +00:00
return nil
2017-11-26 10:15:51 +00:00
}
return src.err
}
func (src *ServerRequestCodec) Params() ([]string, error) {
if src.err == nil && src.req.Params != nil {
2018-03-20 06:31:54 +00:00
var values []string
2017-11-26 10:15:51 +00:00
2018-03-23 03:48:20 +00:00
if err := json.Unmarshal(*src.req.Params, &values); err != nil {
2018-03-27 11:23:43 +00:00
src.err = &crp.Error{
2018-03-20 06:31:54 +00:00
Code: crp.E_INVALID_REQ,
2017-11-26 10:15:51 +00:00
Message: err.Error(),
Data: src.req.Params,
}
return nil, src.err
}
2018-03-20 06:31:54 +00:00
return values, nil
2017-11-26 10:15:51 +00:00
}
return nil, src.err
}
2018-03-23 17:26:41 +00:00
func (src *ServerRequestCodec) NewResponse(reply interface{}) ([]byte, error) {
2018-03-23 13:45:48 +00:00
res := &serverResponse{Version: Version, Result: reply, ID: src.req.ID}
2018-03-23 17:26:41 +00:00
return src.newServerResponse(res)
2018-03-23 13:45:48 +00:00
}
2018-03-23 17:26:41 +00:00
func (src *ServerRequestCodec) NewError(status int, err error) ([]byte, error) {
2018-03-27 11:23:43 +00:00
jsonErr, ok := err.(*crp.Error)
2018-03-23 13:45:48 +00:00
if !ok {
2018-03-27 11:23:43 +00:00
jsonErr = &crp.Error{
2018-03-23 13:45:48 +00:00
Code: crp.E_SERVER,
Message: err.Error(),
}
}
res := &serverResponse{Version: Version, Error: jsonErr, ID: src.req.ID}
2018-03-23 17:26:41 +00:00
return src.newServerResponse(res)
2018-03-23 13:45:48 +00:00
}
2018-03-23 17:26:41 +00:00
func (src *ServerRequestCodec) newServerResponse(res *serverResponse) ([]byte, error) {
2018-03-23 13:45:48 +00:00
return json.Marshal(res)
}