rpc: fix bad method error for batch requests
If a batch request contained an invalid method, the server would reply with a non-batch error response. Fix this by tracking an error for each batch element.
This commit is contained in:
parent
c145589f25
commit
bb01bea4e2
16
rpc/json.go
16
rpc/json.go
@ -182,12 +182,12 @@ func parseRequest(incomingMsg json.RawMessage) ([]rpcRequest, bool, RPCError) {
|
|||||||
method: unsubscribeMethod, params: in.Payload}}, false, nil
|
method: unsubscribeMethod, params: in.Payload}}, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// regular RPC call
|
|
||||||
elems := strings.Split(in.Method, serviceMethodSeparator)
|
elems := strings.Split(in.Method, serviceMethodSeparator)
|
||||||
if len(elems) != 2 {
|
if len(elems) != 2 {
|
||||||
return nil, false, &methodNotFoundError{in.Method, ""}
|
return nil, false, &methodNotFoundError{in.Method, ""}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// regular RPC call
|
||||||
if len(in.Payload) == 0 {
|
if len(in.Payload) == 0 {
|
||||||
return []rpcRequest{rpcRequest{service: elems[0], method: elems[1], id: &in.Id}}, false, nil
|
return []rpcRequest{rpcRequest{service: elems[0], method: elems[1], id: &in.Id}}, false, nil
|
||||||
}
|
}
|
||||||
@ -236,15 +236,15 @@ func parseBatchRequest(incomingMsg json.RawMessage) ([]rpcRequest, bool, RPCErro
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
elems := strings.Split(r.Method, serviceMethodSeparator)
|
|
||||||
if len(elems) != 2 {
|
|
||||||
return nil, true, &methodNotFoundError{r.Method, ""}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(r.Payload) == 0 {
|
if len(r.Payload) == 0 {
|
||||||
requests[i] = rpcRequest{service: elems[0], method: elems[1], id: id, params: nil}
|
requests[i] = rpcRequest{id: id, params: nil}
|
||||||
} else {
|
} else {
|
||||||
requests[i] = rpcRequest{service: elems[0], method: elems[1], id: id, params: r.Payload}
|
requests[i] = rpcRequest{id: id, params: r.Payload}
|
||||||
|
}
|
||||||
|
if elem := strings.Split(r.Method, serviceMethodSeparator); len(elem) == 2 {
|
||||||
|
requests[i].service, requests[i].method = elem[0], elem[1]
|
||||||
|
} else {
|
||||||
|
requests[i].err = &methodNotFoundError{r.Method, ""}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ func (s *Server) serveRequest(codec ServerCodec, singleShot bool, options CodecO
|
|||||||
for atomic.LoadInt32(&s.run) == 1 {
|
for atomic.LoadInt32(&s.run) == 1 {
|
||||||
reqs, batch, err := s.readRequest(codec)
|
reqs, batch, err := s.readRequest(codec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.V(logger.Debug).Infof("%v\n", err)
|
glog.V(logger.Debug).Infof("read error %v\n", err)
|
||||||
codec.Write(codec.CreateErrorResponse(nil, err))
|
codec.Write(codec.CreateErrorResponse(nil, err))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -394,6 +394,11 @@ func (s *Server) readRequest(codec ServerCodec) ([]*serverRequest, bool, RPCErro
|
|||||||
var ok bool
|
var ok bool
|
||||||
var svc *service
|
var svc *service
|
||||||
|
|
||||||
|
if r.err != nil {
|
||||||
|
requests[i] = &serverRequest{id: r.id, err: r.err}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if r.isPubSub && r.method == unsubscribeMethod {
|
if r.isPubSub && r.method == unsubscribeMethod {
|
||||||
requests[i] = &serverRequest{id: r.id, isUnsubscribe: true}
|
requests[i] = &serverRequest{id: r.id, isUnsubscribe: true}
|
||||||
argTypes := []reflect.Type{reflect.TypeOf("")} // expect subscription id as first arg
|
argTypes := []reflect.Type{reflect.TypeOf("")} // expect subscription id as first arg
|
||||||
|
@ -88,6 +88,7 @@ type rpcRequest struct {
|
|||||||
id interface{}
|
id interface{}
|
||||||
isPubSub bool
|
isPubSub bool
|
||||||
params interface{}
|
params interface{}
|
||||||
|
err RPCError // invalid batch element
|
||||||
}
|
}
|
||||||
|
|
||||||
// RPCError implements RPC error, is add support for error codec over regular go errors
|
// RPCError implements RPC error, is add support for error codec over regular go errors
|
||||||
|
Loading…
Reference in New Issue
Block a user