From 2e4214c77b787fc23347a08e0b8e31c20ab21b98 Mon Sep 17 00:00:00 2001 From: Nico Tonozzi Date: Fri, 28 Oct 2016 16:46:40 -0700 Subject: [PATCH] Send something over the wire for responses I accidentally made this change in the main repo, instead of here. This ensures that the server can tell the difference between a response and a request. The old method (resp == nil) didn't work because we use interfaces here, and the interfaces would often have types, but not values. --- handler_with_error.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/handler_with_error.go b/handler_with_error.go index ac35812..006018d 100644 --- a/handler_with_error.go +++ b/handler_with_error.go @@ -3,6 +3,7 @@ package jsonrpc2 import ( "context" "log" + "reflect" ) // HandlerWithError implements Handler by calling the func for each @@ -21,7 +22,7 @@ func (h HandlerWithError) Handle(ctx context.Context, conn *Conn, req *Request) resp := &Response{ID: req.ID} if err == nil { - if result == nil { + if isNilValue(result) { result = struct{}{} } err = resp.SetResult(result) @@ -40,3 +41,17 @@ func (h HandlerWithError) Handle(ctx context.Context, conn *Conn, req *Request) } } } + +// isNilValue tests if an interface is empty, because an empty interface does +// not encode any information, we can't encode it in JSON so that the proxy +// knows it's a response, not a request. +func isNilValue(resp interface{}) bool { + if resp == nil { + return true + } + kind := reflect.TypeOf(resp).Kind() + value := reflect.ValueOf(resp) + nilPtr := kind == reflect.Ptr && value.IsNil() + nilSlice := kind == reflect.Slice && value.IsNil() + return nilPtr || nilSlice +}