Add support for HAProxy Protocol ("proxy protocol")
Is there a way to add a CustomHandler to ChannelPipeline using NettyServerBuilder ?
I initialize my GrpcNettyServer by below:
NettyServerBuilder serverBuilder =
NettyServerBuilder
.forPort(config.getPort())
.addService();
.intercept();
.executor();
.build();
All I want is to get the channel from the server and add a custom handler to the channel pipeline. Does NettyServerBuilder supports that option ?
All I want is to get the channel from the server
By channel you mean an Http2Connection that is created for each incoming connection from a client?
and add a custom handler to the channel pipeline.
What sort of custom handling you want to do on the channel/conection?
By channel you mean an Http2Connection that is created for each incoming connection from a client?
Yeah right
What sort of custom handling you want to do on the channel/conection?
I want to add a custom handler such as ProxyChannelHandler which would extract certain PPV2 information. When data is received from the SocketChannel it needs to be given to ProxyChannelHandler as the first ChannelInboundHandler in the ChannelPipeline. Is there a way to add this ProxyChannelHandler as the first channel in the channel pipeline using NettyServerBuilder ?
It looks like the PPV2 info you want is just the local and remote addresses on a connection. That is available already in gRPC on the ServerCall object as shown in https://github.com/grpc/grpc-java/blob/master/interop-testing/src/main/java/io/grpc/testing/integration/AbstractInteropTest.java#L2020 . So you can do this without adding any CustomHandler if my assumption about what PPV2 info you want is correct.
@madanrajhari let me know if the above has addressed your question. If not I would like to know what specifically you need that would require a CustomHandler.
gRPC doesn't support injecting custom handlers in the netty pipeline. That would be far too brittle to maintain API stability. However, for general-purpose use cases, you can do something similar to what is discussed in https://github.com/grpc/grpc-java/issues/9002#issuecomment-1074064745 .
I expect we'd be okay with a Proxy Protocol implementation contribution. Although dependencies may get a bit messy since it seems we may need to add a codec-haproxy netty dependency. Maybe it is small enough not to care.
If you are interested in contributing speak up and coordinate. I'll need to speak with other languages, for example, to make sure they are okay with this feature being added to Java (since it isn't a language-specific concern). But overall, this doesn't seem too bad of a feature, for someone semi-familiar with Netty.
@ejona86 Hi I am interested in implementing this.
A few questions here:
- Is the support here wanted to add a HAProxy Protocol specific ProtocolNegotiator that decodes the PPv2 header, similar to the serverTls() that adds support for TLS. And add it as part of the common ProtocolNegotiators?
- More like a usage wise question, if we want to use the ppv2 information extracted from the ProtocolNegotiators, what would be the best practice here to pass that along to the later workflow like interceptors? Would Context.Key be useful here?
Thanks for any insight.
More like a usage wise question, if we want to use the ppv2 information extracted from the ProtocolNegotiators, what would be the best practice here to pass that along to the later workflow like interceptors? Would Context.Key be useful here?
ProtocolNegotiators can set Attributes. Those attributes are available via serverCall.getAttributes(). We'd create a new attribute for this.
I have added support for the Proxy Protocol in the gRPC service of RocketMQ. If you have similar requirements, you can refer to the following class. https://github.com/apache/rocketmq/blob/develop/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/ProxyAndTlsProtocolNegotiator.java