grpc / grpc-go

The Go language implementation of gRPC. HTTP/2 based RPC

Home Page:https://grpc.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

User agent becomes grpc-go/1.64. on server side of grpc gateway

CrossChEp opened this issue · comments

I'm trying to create an app using grpc-gateway and go but faced with the. I'm trying to write an interceptor that will authorize users before the requests using cookie and user agent. However the user-agent that I try to get is grpc-go/1.64, which is wrong as I send requests through postman.

I have a method that setups my grpc grpc server

func customHeaderMatcher(key string) (string, bool) {
	switch key {
	case "Cookie":
		logger.Info(key)
		return key, true
	case "User-Agent":
		logger.Info(key)
		return key, true
	default:
		return runtime.DefaultHeaderMatcher(key)
	}
}

func (s *Server) MapHandlers() {

    logger.Info("Trying to map handlers...")

    s.mux = runtime.NewServeMux(
        runtime.WithIncomingHeaderMatcher(customHeaderMatcher),
    )

    s.grpcServer = grpc.NewServer(
        grpc.ChainUnaryInterceptor(
            grpcConnector.LoggerInterceptor(),
            func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
                md, ok := metadata.FromIncomingContext(ctx)
                if !ok {
                   return nil, status.Errorf(codes.Unauthenticated, "MDWManager.AuthedMiddleware: missing metadata")
                }

               userAgent := md.Get("User-Agent")
               if len(userAgent) == 0 {
                   return nil, status.Errorf(codes.Unauthenticated, "MDWManager.AuthedMiddleware: cannot get User-agent")
               }
    
               logger.Infof("UserAgent=%s", userAgent)
            },
        ),
    )
   ...
}

I started digging into the go-grpc library sources and noticed that wrong context gets on server side of grpc connection because function that receives requests in grpc handleStream() has context with user agent

image

I decided to check what context I send to the server in grpc function newClientStreamWithParams() which is stored in client part of grpc library. And there's the context is right because the clientStream struct contains the context with right user-agent

image

So what can be wrong? Thank you in advance!

@CrossChEp Thanks for writing in. We are checking this on our side and will update soon.

@CrossChEp Actually the default header matcher in grpc-gateway appends a prefix grpcgateway- to the incoming http headers before adding them to the outgoing grpc context. And you aren't adding the prefix grpcgateway- to the user-agent header and sending it as is, and that's why its being overridden by the gRPC client of gateway. One way is to append the prefix to the header, but may I know is there any reason to using user-agent as it is without prefix?

This issue is labeled as requiring an update from the reporter, and no update has been received after 6 days. If no update is provided in the next 7 days, this issue will be automatically closed.