diff --git a/util/grpcutil/grpc_util.go b/util/grpcutil/grpc_util.go index 91d87f3e3e51..06c8e17715ee 100644 --- a/util/grpcutil/grpc_util.go +++ b/util/grpcutil/grpc_util.go @@ -61,9 +61,7 @@ func ListenAndServeGRPC(stopper *stop.Stopper, server *grpc.Server, addr net.Add // connections or otherHandler otherwise. func GRPCHandlerFunc(grpcServer *grpc.Server, otherHandler http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // TODO(tamird): point to merged gRPC code rather than a PR. - // This is a partial recreation of gRPC's internal checks https://github.com/grpc/grpc-go/pull/514/files#diff-95e9a25b738459a2d3030e1e6fa2a718R61 - if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") { + if IsGRPCRequest(r) { grpcServer.ServeHTTP(w, r) } else { otherHandler.ServeHTTP(w, r) @@ -71,6 +69,14 @@ func GRPCHandlerFunc(grpcServer *grpc.Server, otherHandler http.Handler) http.Ha }) } +// IsGRPCRequest returns true if r came from a grpc client. +// +// Its logic is a partial recreation of gRPC's internal checks, see +// https://github.com/grpc/grpc-go/blob/01de3de/transport/handler_server.go#L61:L69 +func IsGRPCRequest(r *http.Request) bool { + return r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") +} + // IsClosedConnection returns true if err is an error produced by gRPC on closed connections. func IsClosedConnection(err error) bool { if err == context.Canceled || err == transport.ErrConnClosing || grpc.Code(err) == codes.Canceled {