Fix reference count issue when using Http2FrameCodec / Http2MultiplexCodec with HttpServerUpgradeHandler
Motivation: When using Http2FrameCodec / Http2MultiplexCodec with HttpServerUpgradeHandler reference count exception will be triggered. Modifications: - Correctly retain before calling InboundHttpToHttp2Adapter.handle - Add unit test Result: Fixes [#7172].
This commit is contained in:
parent
bca35b0449
commit
379ac890f4
@ -248,7 +248,7 @@ public class Http2FrameCodec extends Http2ConnectionHandler {
|
||||
upgrade.upgradeRequest().headers().setInt(
|
||||
HttpConversionUtil.ExtensionHeaderNames.STREAM_ID.text(), HTTP_UPGRADE_STREAM_ID);
|
||||
InboundHttpToHttp2Adapter.handle(
|
||||
ctx, connection(), decoder().frameListener(), upgrade.upgradeRequest());
|
||||
ctx, connection(), decoder().frameListener(), upgrade.upgradeRequest().retain());
|
||||
} finally {
|
||||
upgrade.release();
|
||||
}
|
||||
|
@ -24,9 +24,13 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.embedded.EmbeddedChannel;
|
||||
import io.netty.handler.codec.UnsupportedMessageTypeException;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpRequest;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpScheme;
|
||||
import io.netty.handler.codec.http.HttpServerUpgradeHandler;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import io.netty.handler.codec.http2.Http2Exception.StreamException;
|
||||
import io.netty.handler.codec.http2.Http2Stream.State;
|
||||
import io.netty.handler.logging.LogLevel;
|
||||
@ -40,6 +44,8 @@ import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.HashSet;
|
||||
@ -641,6 +647,31 @@ public class Http2FrameCodecTest {
|
||||
assertTrue(listenerExecuted.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void upgradeEventNoRefCntError() throws Http2Exception {
|
||||
frameListener.onHeadersRead(http2HandlerCtx, Http2CodecUtil.HTTP_UPGRADE_STREAM_ID, request, 31, false);
|
||||
|
||||
final FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/");
|
||||
final HttpServerUpgradeHandler.UpgradeEvent upgradeEvent = mock(HttpServerUpgradeHandler.UpgradeEvent.class);
|
||||
when(upgradeEvent.retain()).thenAnswer(new Answer<HttpServerUpgradeHandler.UpgradeEvent>() {
|
||||
@Override
|
||||
public HttpServerUpgradeHandler.UpgradeEvent answer(InvocationOnMock invocationOnMock) throws Throwable {
|
||||
request.retain();
|
||||
return upgradeEvent;
|
||||
}
|
||||
});
|
||||
when(upgradeEvent.release()).thenAnswer(new Answer<Boolean>() {
|
||||
@Override
|
||||
public Boolean answer(InvocationOnMock invocationOnMock) throws Throwable {
|
||||
return request.release();
|
||||
}
|
||||
});
|
||||
|
||||
when(upgradeEvent.upgradeRequest()).thenReturn(request);
|
||||
channel.pipeline().fireUserEventTriggered(upgradeEvent);
|
||||
assertEquals(1, request.refCnt());
|
||||
}
|
||||
|
||||
private static ChannelPromise anyChannelPromise() {
|
||||
return any(ChannelPromise.class);
|
||||
}
|
||||
|
@ -0,0 +1 @@
|
||||
mock-maker-inline
|
Loading…
x
Reference in New Issue
Block a user