1
0
mirror of https://github.com/golang/go synced 2024-11-17 13:14:56 -07:00

net/rpc: remove warnings on incompatible methods at registration

When registering an RPC server, the type being registered may
have additional methods that are not meant to be exposed as
RPC endpoints. Remove the warnings net/rpc produces in
this case. The functionality to report warnings is kept in the code
with a compile-time constant that can be enabled for debugging.

The documentation of net/rpc states that only methods
satisfying a set of criteria will be made available, while other
methods will be ignored.

Fixes #19957

Change-Id: I5f8a148b4be1fdfffb2cd2029871193eaf24b751
Reviewed-on: https://go-review.googlesource.com/c/go/+/350009
Reviewed-by: Daniel Lublin <daniel@lublin.se>
Reviewed-by: Damien Neil <dneil@google.com>
Trust: Carlos Amedee <carlos@golang.org>
This commit is contained in:
Eli Bendersky 2021-09-14 15:02:55 -07:00 committed by Rob Pike
parent 4b654c0eec
commit c894b442d1

View File

@ -231,6 +231,10 @@ func (server *Server) RegisterName(name string, rcvr interface{}) error {
return server.register(rcvr, name, true) return server.register(rcvr, name, true)
} }
// logRegisterError specifies whether to log problems during method registration.
// To debug registration, recompile the package with this set to true.
const logRegisterError = false
func (server *Server) register(rcvr interface{}, name string, useName bool) error { func (server *Server) register(rcvr interface{}, name string, useName bool) error {
s := new(service) s := new(service)
s.typ = reflect.TypeOf(rcvr) s.typ = reflect.TypeOf(rcvr)
@ -252,7 +256,7 @@ func (server *Server) register(rcvr interface{}, name string, useName bool) erro
s.name = sname s.name = sname
// Install the methods // Install the methods
s.method = suitableMethods(s.typ, true) s.method = suitableMethods(s.typ, logRegisterError)
if len(s.method) == 0 { if len(s.method) == 0 {
str := "" str := ""
@ -274,9 +278,9 @@ func (server *Server) register(rcvr interface{}, name string, useName bool) erro
return nil return nil
} }
// suitableMethods returns suitable Rpc methods of typ, it will report // suitableMethods returns suitable Rpc methods of typ. It will log
// error using log if reportErr is true. // errors if logErr is true.
func suitableMethods(typ reflect.Type, reportErr bool) map[string]*methodType { func suitableMethods(typ reflect.Type, logErr bool) map[string]*methodType {
methods := make(map[string]*methodType) methods := make(map[string]*methodType)
for m := 0; m < typ.NumMethod(); m++ { for m := 0; m < typ.NumMethod(); m++ {
method := typ.Method(m) method := typ.Method(m)
@ -288,7 +292,7 @@ func suitableMethods(typ reflect.Type, reportErr bool) map[string]*methodType {
} }
// Method needs three ins: receiver, *args, *reply. // Method needs three ins: receiver, *args, *reply.
if mtype.NumIn() != 3 { if mtype.NumIn() != 3 {
if reportErr { if logErr {
log.Printf("rpc.Register: method %q has %d input parameters; needs exactly three\n", mname, mtype.NumIn()) log.Printf("rpc.Register: method %q has %d input parameters; needs exactly three\n", mname, mtype.NumIn())
} }
continue continue
@ -296,7 +300,7 @@ func suitableMethods(typ reflect.Type, reportErr bool) map[string]*methodType {
// First arg need not be a pointer. // First arg need not be a pointer.
argType := mtype.In(1) argType := mtype.In(1)
if !isExportedOrBuiltinType(argType) { if !isExportedOrBuiltinType(argType) {
if reportErr { if logErr {
log.Printf("rpc.Register: argument type of method %q is not exported: %q\n", mname, argType) log.Printf("rpc.Register: argument type of method %q is not exported: %q\n", mname, argType)
} }
continue continue
@ -304,28 +308,28 @@ func suitableMethods(typ reflect.Type, reportErr bool) map[string]*methodType {
// Second arg must be a pointer. // Second arg must be a pointer.
replyType := mtype.In(2) replyType := mtype.In(2)
if replyType.Kind() != reflect.Ptr { if replyType.Kind() != reflect.Ptr {
if reportErr { if logErr {
log.Printf("rpc.Register: reply type of method %q is not a pointer: %q\n", mname, replyType) log.Printf("rpc.Register: reply type of method %q is not a pointer: %q\n", mname, replyType)
} }
continue continue
} }
// Reply type must be exported. // Reply type must be exported.
if !isExportedOrBuiltinType(replyType) { if !isExportedOrBuiltinType(replyType) {
if reportErr { if logErr {
log.Printf("rpc.Register: reply type of method %q is not exported: %q\n", mname, replyType) log.Printf("rpc.Register: reply type of method %q is not exported: %q\n", mname, replyType)
} }
continue continue
} }
// Method needs one out. // Method needs one out.
if mtype.NumOut() != 1 { if mtype.NumOut() != 1 {
if reportErr { if logErr {
log.Printf("rpc.Register: method %q has %d output parameters; needs exactly one\n", mname, mtype.NumOut()) log.Printf("rpc.Register: method %q has %d output parameters; needs exactly one\n", mname, mtype.NumOut())
} }
continue continue
} }
// The return type of the method must be error. // The return type of the method must be error.
if returnType := mtype.Out(0); returnType != typeOfError { if returnType := mtype.Out(0); returnType != typeOfError {
if reportErr { if logErr {
log.Printf("rpc.Register: return type of method %q is %q, must be error\n", mname, returnType) log.Printf("rpc.Register: return type of method %q is %q, must be error\n", mname, returnType)
} }
continue continue