use of io.netty.handler.codec.http2.DefaultHttp2DataFrame in project netty by netty.
the class Http2MultiplexTest method endOfStreamDoesNotDiscardData.
@Test
public void endOfStreamDoesNotDiscardData() {
AtomicInteger numReads = new AtomicInteger(1);
final AtomicBoolean shouldDisableAutoRead = new AtomicBoolean();
Consumer<ChannelHandlerContext> ctxConsumer = new Consumer<ChannelHandlerContext>() {
@Override
public void accept(ChannelHandlerContext obj) {
if (shouldDisableAutoRead.get()) {
obj.channel().config().setAutoRead(false);
}
}
};
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) {
// 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.<Http2DataFrame>readInbound());
// Deliver frames, and then a stream closed while read is inactive.
frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("2"), 0, false);
frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("3"), 0, false);
frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("4"), 0, false);
shouldDisableAutoRead.set(true);
childChannel.config().setAutoRead(true);
numReads.set(1);
frameInboundWriter.writeInboundRstStream(childChannel.stream().id(), Http2Error.NO_ERROR.code());
// Detecting EOS should flush all pending data regardless of read calls.
assertEqualsAndRelease(dataFrame2, inboundHandler.<Http2DataFrame>readInbound());
assertNull(inboundHandler.readInbound());
// As we limited the number to 1 we also need to call read() again.
childChannel.read();
assertEqualsAndRelease(dataFrame3, inboundHandler.<Http2DataFrame>readInbound());
assertEqualsAndRelease(dataFrame4, inboundHandler.<Http2DataFrame>readInbound());
Http2ResetFrame resetFrame = useUserEventForResetFrame() ? inboundHandler.<Http2ResetFrame>readUserEvent() : inboundHandler.<Http2ResetFrame>readInbound();
assertEquals(childChannel.stream(), resetFrame.stream());
assertEquals(Http2Error.NO_ERROR.code(), resetFrame.errorCode());
assertNull(inboundHandler.readInbound());
// Now we want to call channelReadComplete and simulate the end of the read loop.
parentChannel.pipeline().remove(readCompleteSupressHandler);
parentChannel.flushInbound();
childChannel.closeFuture().syncUninterruptibly();
}
use of io.netty.handler.codec.http2.DefaultHttp2DataFrame in project netty by netty.
the class Http2FrameCodecTest method newOutboundStream.
@Test
@Timeout(value = 5000, unit = TimeUnit.MILLISECONDS)
public void newOutboundStream() {
final Http2FrameStream stream = frameCodec.newStream();
assertNotNull(stream);
assertFalse(isStreamIdValid(stream.id()));
final Promise<Void> listenerExecuted = new DefaultPromise<Void>(GlobalEventExecutor.INSTANCE);
channel.writeAndFlush(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers(), false).stream(stream)).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
assertTrue(future.isSuccess());
assertTrue(isStreamIdValid(stream.id()));
listenerExecuted.setSuccess(null);
}
});
ByteBuf data = Unpooled.buffer().writeZero(100);
ChannelFuture f = channel.writeAndFlush(new DefaultHttp2DataFrame(data).stream(stream));
assertTrue(f.isSuccess());
listenerExecuted.syncUninterruptibly();
assertTrue(listenerExecuted.isSuccess());
}
use of io.netty.handler.codec.http2.DefaultHttp2DataFrame in project netty by netty.
the class Http2StaticFileServerHandler method sendError.
private void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {
Http2Headers headers = new DefaultHttp2Headers();
headers.status(status.toString());
headers.add(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");
Http2HeadersFrame headersFrame = new DefaultHttp2HeadersFrame(headers);
headersFrame.stream(stream);
Http2DataFrame dataFrame = new DefaultHttp2DataFrame(Unpooled.copiedBuffer("Failure: " + status + "\r\n", CharsetUtil.UTF_8), true);
dataFrame.stream(stream);
ctx.write(headersFrame);
ctx.writeAndFlush(dataFrame);
}
use of io.netty.handler.codec.http2.DefaultHttp2DataFrame in project netty by netty.
the class HelloWorldHttp2Handler method sendResponse.
/**
* Sends a "Hello World" DATA frame to the client.
*/
private static void sendResponse(ChannelHandlerContext ctx, ByteBuf payload) {
// Send a frame for the response status
Http2Headers headers = new DefaultHttp2Headers().status(OK.codeAsText());
ctx.write(new DefaultHttp2HeadersFrame(headers));
ctx.write(new DefaultHttp2DataFrame(payload, true));
}
use of io.netty.handler.codec.http2.DefaultHttp2DataFrame in project ambry by linkedin.
the class AmbrySendToHttp2AdaptorTest method testServerWrite.
/**
* Test when write {@link Send} from server to client. There are two cases tested in this method
* 1. {@link Send} returns a non-null value for {@link Send#content()} method.
* 2. {@link Send} returns a null value for {@link Send#content()} method.
* Make sure both cases don't leak memory.
* @throws Exception
*/
@Test
public void testServerWrite() throws Exception {
int maxFrameSize = 2001;
EmbeddedChannel channel = new EmbeddedChannel(new AmbrySendToHttp2Adaptor(true, maxFrameSize));
int contentSize = 7000;
byte[] byteArray = new byte[contentSize];
new Random().nextBytes(byteArray);
ByteBuf content = PooledByteBufAllocator.DEFAULT.heapBuffer(contentSize).writeBytes(byteArray);
// Retain the ByteBuf for data comparison
content.retain();
Send send = new MockSend(content);
channel.writeOutbound(send);
DefaultHttp2HeadersFrame header = channel.readOutbound();
Assert.assertNotNull(header.headers());
Assert.assertEquals(header.headers().status().toString(), "200");
byte[] resultArray = new byte[contentSize];
int i;
for (i = 0; i < contentSize / maxFrameSize; i++) {
DefaultHttp2DataFrame data = channel.readOutbound();
data.content().readBytes(resultArray, i * maxFrameSize, maxFrameSize);
data.content().release();
}
// The last frame
DefaultHttp2DataFrame data = channel.readOutbound();
data.content().readBytes(resultArray, i * maxFrameSize, data.content().readableBytes());
data.content().release();
Assert.assertArrayEquals(byteArray, resultArray);
content.release();
}
Aggregations