Reputation: 4246
I'm trying to code a high performance reverse proxy server using Netty 4.1. I based my code on an Java adaptation of Feng-Zihao/protox and the Netty Proxy Example.
I first had some trouble handling 100-CONTINUE but adding the HttpObjectAggregator
into my pipeline kinda solved that.
serverBootstrap
.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.DEBUG))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));
ch.pipeline().addLast(new HttpRequestDecoder());
ch.pipeline().addLast(new HttpResponseEncoder());
ch.pipeline().addLast(new HttpObjectAggregator(1048576));
ch.pipeline().addLast(new FrontendHandler());
}
})
// .option(ChannelOption.SO_REUSEADDR, true)
// .option(ChannelOption.SO_BACKLOG, 128)
// .childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.AUTO_READ, false)
.bind(port).sync();
On the client side, the request hangs indefinitely.
The thing is, AUTO_READ being at false
seems to prevent the HttpObjectAggregator
to do his work and my FrontendHandler
only ever receives the channelActive
event but never the channelRead
.
It seems though that I need that to make sure I don't get into some race condition between the reads and the remote peer connection.
FYI, my goal in the end is to choose to forward or not the request based on a filter (probably a new handler right before my FrontendHandler) that will need to read the full http content.
Am I missing something here ?
Upvotes: 3
Views: 1762
Reputation: 1281
Turn on auto read when your outbound channel becomes active, and have your FrontendHandler turn it off while processing each message. Then turn it on again when you are ready to handle another message.
This will let HttpObjectAggregator keep reading as many messages as it needs to in order to create a FullHttpMessage, and then stop sending it messages while your FrontendHandler is processing or waiting on some client write to invoke a listener.
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.channel().config().setAutoRead(false);
...
// This call should probably be in some event listener
ctx.channel().config().setAutoRead(true);
Upvotes: 3