use of io.netty.handler.codec.http2.Http2GoAwayFrame in project netty by netty.
the class Http2MultiplexCodecTest method outboundStreamShouldWriteGoAwayWithoutReset.
@Test
public void outboundStreamShouldWriteGoAwayWithoutReset() {
childChannelInitializer.handler = new ChannelInboundHandlerAdapter() {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(new DefaultHttp2GoAwayFrame(Http2Error.NO_ERROR));
ctx.fireChannelActive();
}
};
Http2StreamChannelBootstrap b = new Http2StreamChannelBootstrap();
b.parentChannel(parentChannel).handler(childChannelInitializer);
Channel childChannel = b.connect().channel();
assertTrue(childChannel.isActive());
Http2GoAwayFrame goAwayFrame = parentChannel.readOutbound();
assertNotNull(goAwayFrame);
goAwayFrame.release();
childChannel.close();
parentChannel.runPendingTasks();
Http2ResetFrame reset = parentChannel.readOutbound();
assertNull(reset);
}
use of io.netty.handler.codec.http2.Http2GoAwayFrame in project netty by netty.
the class Http2MultiplexCodec method channelRead.
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (!(msg instanceof Http2Frame)) {
ctx.fireChannelRead(msg);
return;
}
if (msg instanceof Http2StreamFrame) {
Http2StreamFrame frame = (Http2StreamFrame) msg;
int streamId = frame.streamId();
Http2StreamChannel childChannel = childChannels.get(streamId);
if (childChannel == null) {
// TODO: Combine with DefaultHttp2ConnectionDecoder.shouldIgnoreHeadersOrDataFrame logic.
ReferenceCountUtil.release(msg);
throw new StreamException(streamId, STREAM_CLOSED, format("Received %s frame for an unknown stream %d", frame.name(), streamId));
}
fireChildReadAndRegister(childChannel, frame);
} else if (msg instanceof Http2GoAwayFrame) {
Http2GoAwayFrame goAwayFrame = (Http2GoAwayFrame) msg;
for (PrimitiveEntry<Http2StreamChannel> entry : childChannels.entries()) {
Http2StreamChannel childChannel = entry.value();
int streamId = entry.key();
if (streamId > goAwayFrame.lastStreamId() && isOutboundStream(server, streamId)) {
childChannel.pipeline().fireUserEventTriggered(goAwayFrame.retainedDuplicate());
}
}
goAwayFrame.release();
} else {
// It's safe to release, as UnsupportedMessageTypeException just calls msg.getClass()
ReferenceCountUtil.release(msg);
throw new UnsupportedMessageTypeException(msg);
}
}
use of io.netty.handler.codec.http2.Http2GoAwayFrame in project netty by netty.
the class Http2FrameCodecTest method streamIdentifiersExhausted.
@Test
public void streamIdentifiersExhausted() throws Http2Exception {
int maxServerStreamId = Integer.MAX_VALUE - 1;
assertNotNull(frameCodec.connection().local().createStream(maxServerStreamId, false));
Http2FrameStream stream = frameCodec.newStream();
assertNotNull(stream);
ChannelPromise writePromise = channel.newPromise();
channel.writeAndFlush(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers()).stream(stream), writePromise);
Http2GoAwayFrame goAwayFrame = inboundHandler.readInbound();
assertNotNull(goAwayFrame);
assertEquals(NO_ERROR.code(), goAwayFrame.errorCode());
assertEquals(Integer.MAX_VALUE, goAwayFrame.lastStreamId());
goAwayFrame.release();
assertThat(writePromise.cause(), instanceOf(Http2NoMoreStreamIdsException.class));
}
use of io.netty.handler.codec.http2.Http2GoAwayFrame in project netty by netty.
the class Http2MultiplexHandler method channelRead.
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
parentReadInProgress = true;
if (msg instanceof Http2StreamFrame) {
if (msg instanceof Http2WindowUpdateFrame) {
// We dont want to propagate update frames to the user
return;
}
Http2StreamFrame streamFrame = (Http2StreamFrame) msg;
DefaultHttp2FrameStream s = (DefaultHttp2FrameStream) streamFrame.stream();
AbstractHttp2StreamChannel channel = (AbstractHttp2StreamChannel) s.attachment;
if (msg instanceof Http2ResetFrame) {
// Reset frames needs to be propagated via user events as these are not flow-controlled and so
// must not be controlled by suppressing channel.read() on the child channel.
channel.pipeline().fireUserEventTriggered(msg);
// RST frames will also trigger closing of the streams which then will call
// AbstractHttp2StreamChannel.streamClosed()
} else {
channel.fireChildRead(streamFrame);
}
return;
}
if (msg instanceof Http2GoAwayFrame) {
// goaway frames will also trigger closing of the streams which then will call
// AbstractHttp2StreamChannel.streamClosed()
onHttp2GoAwayFrame(ctx, (Http2GoAwayFrame) msg);
}
// Send everything down the pipeline
ctx.fireChannelRead(msg);
}
use of io.netty.handler.codec.http2.Http2GoAwayFrame in project netty by netty.
the class Http2FrameCodec method writeGoAwayFrame.
private void writeGoAwayFrame(Http2GoAwayFrame frame, ChannelPromise promise) {
if (frame.lastStreamId() > -1) {
throw new IllegalArgumentException("Last stream id must not be set on GOAWAY frame");
}
int lastStreamCreated = http2Handler.connection().remote().lastStreamCreated();
int lastStreamId = lastStreamCreated + frame.extraStreamIds() * 2;
// Check if the computation overflowed.
if (lastStreamId < lastStreamCreated) {
lastStreamId = Integer.MAX_VALUE;
}
http2Handler.goAway(http2HandlerCtx, lastStreamId, frame.errorCode(), frame.content().retain(), promise);
}
Aggregations