diff --git a/internal/jsonrpc2/messages.go b/internal/jsonrpc2/messages.go index 77c95313..b2dcfcf8 100644 --- a/internal/jsonrpc2/messages.go +++ b/internal/jsonrpc2/messages.go @@ -109,7 +109,7 @@ func (msg *Request) IsCall() bool { return msg.ID.IsValid() } func (msg *Request) marshal(to *wireCombined) { to.ID = msg.ID.value - to.Method = msg.Method + to.Method = &msg.Method to.Params = msg.Params } @@ -183,10 +183,10 @@ func DecodeMessage(data []byte) (Message, error) { if err != nil { return nil, err } - if msg.Method != "" { + if msg.Method != nil { // has a method, must be a call return &Request{ - Method: msg.Method, + Method: *msg.Method, ID: id, Params: msg.Params, }, nil diff --git a/internal/jsonrpc2/wire.go b/internal/jsonrpc2/wire.go index 4d123f2c..6cc17975 100644 --- a/internal/jsonrpc2/wire.go +++ b/internal/jsonrpc2/wire.go @@ -54,7 +54,7 @@ const wireVersion = "2.0" type wireCombined struct { VersionTag string `json:"jsonrpc"` ID any `json:"id,omitempty"` - Method string `json:"method,omitempty"` + Method *string `json:"method,omitempty"` Params json.RawMessage `json:"params,omitempty"` Result json.RawMessage `json:"result,omitempty"` Error *WireError `json:"error,omitempty"` diff --git a/internal/jsonrpc2/wire_test.go b/internal/jsonrpc2/wire_test.go index 6f576f08..b6fc505d 100644 --- a/internal/jsonrpc2/wire_test.go +++ b/internal/jsonrpc2/wire_test.go @@ -63,6 +63,24 @@ func TestWireMessage(t *testing.T) { } } +func TestDecodeEmptyMethodAsRequest(t *testing.T) { + msg, err := jsonrpc2.DecodeMessage([]byte(`{"jsonrpc":"2.0","id":5,"method":"","params":{}}`)) + if err != nil { + t.Fatal(err) + } + + req, ok := msg.(*jsonrpc2.Request) + if !ok { + t.Fatalf("decoded message is %T, want *jsonrpc2.Request", msg) + } + if req.ID.Raw() != int64(5) { + t.Fatalf("request id = %v, want 5", req.ID.Raw()) + } + if req.Method != "" { + t.Fatalf("request method = %q, want empty string", req.Method) + } +} + func newNotification(method string, params any) jsonrpc2.Message { msg, err := jsonrpc2.NewNotification(method, params) if err != nil {