I am new to netty and I am stuck at a point. I am using netty as a reverse proxy and here is my channel pipeline.
streamChannel.pipeline()
.addLast(new Http2StreamFrameToHttpObjectCodec(true))
.addLast(new BandwidthHandler(transactionStrategy))
.addLast(new ProxyRequestCodec(transactionStrategy, sslSession))
.addLast(new TransactionHandler(transactionStrategy, connectionCtx))
.addLast(new ObjectAggregator(aggregationStrategy, MAX_AGGREGATED_CONTENT_LENGTH,protocol))
.addLast(new AggregatedProxyRequestDecoder(connectionCtx))
.addLast(new AuthenticationHandler(authenticationStrategy))
.addLast(new RouteHandler(routingStrategy, fChannel))
.addLast(new RequestFilter(filteringStrategy, fChannel))
.addLast(new AppSpecificHandler(proxyConfig.appHandlers(), connectionCtx))
.addLast(new RequestModifier(modificationStrategy))
.addLast(new FlowControlHandler())
.addLast(new ConnectionHandler(connectionCtx, backendPort))
.addLast(new RequestForwarder(connectionCtx))
.addLast(new ExceptionHandler(connectionCtx));
These handlers are present inside the Http2MultiplexHandler because these handlers were used in http1 and updating the whole business logic to http2 frames was a major change. Now the issue I am facing is that the connection handler does not connect to backend host unless the it receives a FullHttpRequest that is if I remove ObjectAggregator from the pipeline, the future returned from bootstrap.connect(host, port) doesn't resolve until I get a connection timeout exception. Below is the connection handler code.
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof ProxyRequest proxyRequest) {
connectToBackend(ctx, proxyRequest);
return;
}
fireNextHandlerRead(ctx, msg);
}
private void connectToBackend(ChannelHandlerContext ctx, ProxyRequest proxyRequest) throws InterruptedException {
var host = proxyRequest.hostName();
var bChannel = connectionCtx.bChannelPool().acquire(host);
if (bChannel.isConnected()) {
connectionCtx.bChannel(bChannel);
fireNextHandlerRead(ctx, proxyRequest);
return;
}
var connectFuture = bChannel.connect(host, backendPort);
connectFuture
.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)
.addListener(future -> {
if (!future.isSuccess()) return;
connectionCtx.bChannel(bChannel);
fireNextHandlerRead(ctx, proxyRequest);
});
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof ProxyRequest proxyRequest) {
connectToBackend(ctx, proxyRequest);
return;
}
fireNextHandlerRead(ctx, msg);
}
private void connectToBackend(ChannelHandlerContext ctx, ProxyRequest proxyRequest) throws InterruptedException {
var host = proxyRequest.hostName();
var bChannel = connectionCtx.bChannelPool().acquire(host);
if (bChannel.isConnected()) {
connectionCtx.bChannel(bChannel);
fireNextHandlerRead(ctx, proxyRequest);
return;
}
var connectFuture = bChannel.connect(host, backendPort);
connectFuture
.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)
.addListener(future -> {
if (!future.isSuccess()) return;
connectionCtx.bChannel(bChannel);
fireNextHandlerRead(ctx, proxyRequest);
});
}
Below is the connect from BackendChannel
public ChannelFuture connect(String host, int port) {
var connectFuture = bootstrap.connect(host, port);
channelOpt = Optional.of(connectFuture.channel());
return connectFuture;
}
I am pretty sure it has nothing to do with the fullHttpRequest, because the same logic works in a standalone http1 pipeline. Any help would be greatly appriciated.