Fix an NPE in AbstractHttp2StreamChannel (#9379)
Motivation: If a read triggers a AbstractHttp2StreamChannel to close we can get an NPE in the read loop. Modifications: Make sure that the inboundBuffer isn't null before attempting to continue the loop. Result: No NPE. Fixes #9337
This commit is contained in:
parent
e8ab79f34d
commit
dd1785ba66
@ -783,7 +783,7 @@ abstract class AbstractHttp2StreamChannel extends DefaultAttributeMap implements
|
||||
do {
|
||||
flowControlledBytes += doRead0((Http2Frame) message, allocHandle);
|
||||
} while ((readEOS || (continueReading = allocHandle.continueReading())) &&
|
||||
(message = inboundBuffer.poll()) != null);
|
||||
inboundBuffer != null && (message = inboundBuffer.poll()) != null);
|
||||
|
||||
if (continueReading && isParentReadInProgress() && !readEOS) {
|
||||
// Currently the parent and child channel are on the same EventLoop thread. If the parent is
|
||||
|
@ -303,6 +303,42 @@ public abstract class Http2MultiplexTest<C extends Http2FrameCodec> {
|
||||
verifyFramesMultiplexedToCorrectChannel(childChannel, inboundHandler, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelReadShouldRespectAutoReadAndNotProduceNPE() throws Exception {
|
||||
LastInboundHandler inboundHandler = new LastInboundHandler();
|
||||
Http2StreamChannel childChannel = newInboundStream(3, false, inboundHandler);
|
||||
assertTrue(childChannel.config().isAutoRead());
|
||||
Http2HeadersFrame headersFrame = inboundHandler.readInbound();
|
||||
assertNotNull(headersFrame);
|
||||
|
||||
childChannel.config().setAutoRead(false);
|
||||
childChannel.pipeline().addFirst(new ChannelInboundHandlerAdapter() {
|
||||
private int count;
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
ctx.fireChannelRead(msg);
|
||||
// Close channel after 2 reads so there is still something in the inboundBuffer when the close happens.
|
||||
if (++count == 2) {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("hello world"), 0, false);
|
||||
Http2DataFrame dataFrame0 = inboundHandler.readInbound();
|
||||
assertNotNull(dataFrame0);
|
||||
release(dataFrame0);
|
||||
|
||||
frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("foo"), 0, false);
|
||||
frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("bar"), 0, false);
|
||||
frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("bar"), 0, false);
|
||||
|
||||
assertNull(inboundHandler.readInbound());
|
||||
|
||||
childChannel.config().setAutoRead(true);
|
||||
verifyFramesMultiplexedToCorrectChannel(childChannel, inboundHandler, 3);
|
||||
inboundHandler.checkException();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readInChannelReadWithoutAutoRead() {
|
||||
useReadWithoutAutoRead(false);
|
||||
|
Loading…
Reference in New Issue
Block a user