use of io.netty.handler.codec.http2.Http2Frame 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.Http2Frame in project aws-sdk-java-v2 by aws.
the class WindowSizeTest method execute_noExplicitValueSet_sendsDefaultValueInSettings.
@Test
public void execute_noExplicitValueSet_sendsDefaultValueInSettings() throws InterruptedException {
ConcurrentLinkedQueue<Http2Frame> receivedFrames = new ConcurrentLinkedQueue<>();
server = new TestH2Server(() -> new StreamHandler(receivedFrames));
server.init();
netty = NettyNioAsyncHttpClient.builder().protocol(Protocol.HTTP2).build();
AsyncExecuteRequest req = AsyncExecuteRequest.builder().requestContentPublisher(new EmptyPublisher()).request(SdkHttpFullRequest.builder().method(SdkHttpMethod.GET).protocol("http").host("localhost").port(server.port()).build()).responseHandler(new SdkAsyncHttpResponseHandler() {
@Override
public void onHeaders(SdkHttpResponse headers) {
}
@Override
public void onStream(Publisher<ByteBuffer> stream) {
}
@Override
public void onError(Throwable error) {
}
}).build();
netty.execute(req).join();
List<Http2Settings> receivedSettings = receivedFrames.stream().filter(f -> f instanceof Http2SettingsFrame).map(f -> (Http2SettingsFrame) f).map(Http2SettingsFrame::settings).collect(Collectors.toList());
assertThat(receivedSettings.size()).isGreaterThan(0);
for (Http2Settings s : receivedSettings) {
assertThat(s.initialWindowSize()).isEqualTo(DEFAULT_INIT_WINDOW_SIZE);
}
}
use of io.netty.handler.codec.http2.Http2Frame in project aws-sdk-java-v2 by aws.
the class WindowSizeTest method expectCorrectWindowSizeValueTest.
private void expectCorrectWindowSizeValueTest(Integer builderSetterValue, int settingsFrameValue) throws InterruptedException {
ConcurrentLinkedQueue<Http2Frame> receivedFrames = new ConcurrentLinkedQueue<>();
server = new TestH2Server(() -> new StreamHandler(receivedFrames));
server.init();
netty = NettyNioAsyncHttpClient.builder().protocol(Protocol.HTTP2).http2Configuration(Http2Configuration.builder().initialWindowSize(builderSetterValue).build()).build();
AsyncExecuteRequest req = AsyncExecuteRequest.builder().requestContentPublisher(new EmptyPublisher()).request(SdkHttpFullRequest.builder().method(SdkHttpMethod.GET).protocol("http").host("localhost").port(server.port()).build()).responseHandler(new SdkAsyncHttpResponseHandler() {
@Override
public void onHeaders(SdkHttpResponse headers) {
}
@Override
public void onStream(Publisher<ByteBuffer> stream) {
}
@Override
public void onError(Throwable error) {
}
}).build();
netty.execute(req).join();
List<Http2Settings> receivedSettings = receivedFrames.stream().filter(f -> f instanceof Http2SettingsFrame).map(f -> (Http2SettingsFrame) f).map(Http2SettingsFrame::settings).collect(Collectors.toList());
assertThat(receivedSettings.size()).isGreaterThan(0);
for (Http2Settings s : receivedSettings) {
assertThat(s.initialWindowSize()).isEqualTo(settingsFrameValue);
}
}
use of io.netty.handler.codec.http2.Http2Frame in project ambry by linkedin.
the class Http2ClientStreamStatsHandler method channelRead0.
@Override
protected void channelRead0(ChannelHandlerContext ctx, Http2Frame frame) throws Exception {
ReferenceCountUtil.retain(frame);
RequestInfo requestInfo = ctx.channel().attr(Http2NetworkClient.REQUEST_INFO).get();
requestInfo.responseFramesCount++;
long time = System.currentTimeMillis() - requestInfo.getStreamSendTime();
if (frame instanceof Http2HeadersFrame) {
http2ClientMetrics.http2StreamRoundTripTime.update(time);
requestInfo.setStreamHeaderFrameReceiveTime(System.currentTimeMillis());
logger.debug("Header Frame received. Time from send: {}ms. Request: {}", time, requestInfo);
} else if (frame instanceof Http2DataFrame) {
logger.debug("Data Frame size: {}. Time from send: {}ms. Request: {}", ((Http2DataFrame) frame).content().readableBytes(), time, requestInfo);
}
if (frame instanceof Http2DataFrame && ((Http2DataFrame) frame).isEndStream()) {
http2ClientMetrics.http2StreamFirstToLastFrameTime.update(time);
http2ClientMetrics.http2ResponseFrameCount.update(requestInfo.responseFramesCount);
logger.debug("All Frame received. Time from send: {}ms. Request: {}", time, requestInfo);
}
ctx.fireChannelRead(frame);
}
use of io.netty.handler.codec.http2.Http2Frame in project netty by netty.
the class Http2MultiplexTest method childQueueIsDrainedAndNewDataIsDispatchedInParentReadLoopNoAutoRead.
@Test
public void childQueueIsDrainedAndNewDataIsDispatchedInParentReadLoopNoAutoRead() {
final AtomicInteger numReads = new AtomicInteger(1);
final AtomicInteger channelReadCompleteCount = new AtomicInteger(0);
final AtomicBoolean shouldDisableAutoRead = new AtomicBoolean();
Consumer<ChannelHandlerContext> ctxConsumer = new Consumer<ChannelHandlerContext>() {
@Override
public void accept(ChannelHandlerContext obj) {
channelReadCompleteCount.incrementAndGet();
if (shouldDisableAutoRead.get()) {
obj.channel().config().setAutoRead(false);
}
}
};
final LastInboundHandler inboundHandler = new LastInboundHandler(ctxConsumer);
Http2StreamChannel childChannel = newInboundStream(3, false, numReads, inboundHandler);
childChannel.config().setAutoRead(false);
Http2DataFrame dataFrame1 = new DefaultHttp2DataFrame(bb("1")).stream(childChannel.stream());
Http2DataFrame dataFrame2 = new DefaultHttp2DataFrame(bb("2")).stream(childChannel.stream());
Http2DataFrame dataFrame3 = new DefaultHttp2DataFrame(bb("3")).stream(childChannel.stream());
Http2DataFrame dataFrame4 = new DefaultHttp2DataFrame(bb("4")).stream(childChannel.stream());
assertEquals(new DefaultHttp2HeadersFrame(request).stream(childChannel.stream()), inboundHandler.readInbound());
ChannelHandler readCompleteSupressHandler = new ChannelInboundHandlerAdapter() {
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
// We want to simulate the parent channel calling channelRead and delay calling channelReadComplete.
}
};
parentChannel.pipeline().addFirst(readCompleteSupressHandler);
frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("1"), 0, false);
assertEqualsAndRelease(dataFrame1, inboundHandler.<Http2Frame>readInbound());
// We want one item to be in the queue, and allow the numReads to be larger than 1. This will ensure that
// when beginRead() is called the child channel is added to the readPending queue of the parent channel.
frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("2"), 0, false);
numReads.set(2);
childChannel.read();
assertEqualsAndRelease(dataFrame2, inboundHandler.<Http2Frame>readInbound());
assertNull(inboundHandler.readInbound());
// This is the second item that was read, this should be the last until we call read() again. This should also
// notify of readComplete().
frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("3"), 0, false);
assertEqualsAndRelease(dataFrame3, inboundHandler.<Http2Frame>readInbound());
frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("4"), 0, false);
assertNull(inboundHandler.readInbound());
childChannel.read();
assertEqualsAndRelease(dataFrame4, inboundHandler.<Http2Frame>readInbound());
assertNull(inboundHandler.readInbound());
// Now we want to call channelReadComplete and simulate the end of the read loop.
parentChannel.pipeline().remove(readCompleteSupressHandler);
parentChannel.flushInbound();
// 3 = 1 for initialization + 1 for first read of 2 items + 1 for second read of 2 items +
// 1 for parent channel readComplete
assertEquals(4, channelReadCompleteCount.get());
}
Aggregations