Title: netty client reuses serverside bootstrap results in the requests never finished
Tags: netty
Question: A Netty server requests to another server as a client for every request it receives. Almost like a proxy, except it does not forward the received message as it is. I tried to use the server ChannelHandlerContext to create a client, but the request never finishes.
In the last duplex handler, if test, the client receives response, otherwise the request haunts.
Server last handler:
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
log.info("receive: {}", msg);
if (!test) {
HttpClient.clientSend(ctx);
} else {
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1,
io.netty.handler.codec.http.HttpResponseStatus.OK,
Unpooled.wrappedBuffer(CONTENT));
response.headers().set(CONTENT_TYPE, "text/plain");
response.headers().setInt(CONTENT_LENGTH, response.content().readableBytes());
ctx.channel().writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
log.info("write: {}", msg);
ctx.write(msg, promise); // checked, it is success. but client never receives.
Client:
public static void clientSend(ChannelHandlerContext ctx) {
final Channel inboundChannel = ctx.channel();
try {
Bootstrap b = new Bootstrap();
b.group(inboundChannel.eventLoop())
.channel(inboundChannel.getClass())
.handler(new ClientChannelInitializer(inboundChannel));
// Make the connection attempt.
ChannelFuture f = b.connect(host,port);
Channel outboundChannel = f.channel();
f.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
// Prepare the HTTP request.
HttpRequest request =
new DefaultFullHttpRequest(
HttpVersion.HTTP_1_1, HttpMethod.POST, "targets", Unpooled.copiedBuffer(requestBody,
CharsetUtil.UTF_8));
// Send the HTTP request.
ChannelFuture wf = outboundChannel.writeAndFlush(request);
wf.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
log.info("write success");
} else {
log.info("write failed ", future.cause());
}
}
});
log.info("channel listener connected");
} else {
log.info("channel listener not connected");
}
}
}
);
}
When write is called, I can see that msg is correct, and ctx.write succeeds, however, the postman gives:

Here is the accepted answer: For me it looks like you missed to set the "Content-Length" header that matches the amount of bytes of your payload. Add it and it should be fine.


{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 0, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2018:00:06/14/18', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<netty>', 'Title': 'netty client reuses serverside bootstrap results in the requests never finished', 'ViewCount': 50, 'id': 50849530, 'user_AboutMe': '<p>Need help on idiomatic English! You are more than welcome to correct English I used in my posts!</p>\n', 'user_AccountId': 1424899.0, 'user_DisplayName': 'Tiina', 'user_Reputation': 3735.0, 'user_Views': 1669.0, 'user_id': 1348691.0}}