Description
Hi, I'm using ahc 2.0.31. Observed hanging AHC thread in two scenarios: 1. upload an empty file. 2. netty channel closed. At first, I thought these two cases were unrelated. But going through the code, found they seem caused by the same reason.
I used the default unpooled buffer allocator with UnpooledUnsafeDireByteBuf. In the code, on channel closed or file is empty, it will return -1, which makes sense.
public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
this.ensureAccessible();
ByteBuffer tmpBuf = this.internalNioBuffer();
tmpBuf.clear().position(index).limit(index + length);
try {
return in.read(tmpBuf);
} catch (ClosedChannelException var6) {
return -1;
}
}
But when file multipart part received -1, it decreased the position by -1. Then it compared the position with the length to see if the position reaches the end. With decrease by -1 every time, the position will never reach the end. And causing the thread looping forever...
protected long transferContentTo(ByteBuf target) throws IOException {
int transferred = target.writeBytes(this.channel, target.writableBytes());
this.position += (long)transferred;
if (this.position == this.length) {
this.state = MultipartState.POST_CONTENT;
this.channel.close();
}
return (long)transferred;
}
This is easy to reproduce. You can simply upload with empty file. Let me know if I mis-understand anything. Thx!