use of io.netty.handler.codec.http2.LastInboundHandler.Consumer in project vert.x by eclipse.
the class Http2ServerTest method testPushPromise.
private void testPushPromise(Http2Headers requestHeaders, BiConsumer<HttpServerResponse, Handler<AsyncResult<HttpServerResponse>>> pusher, Consumer<Http2Headers> headerChecker) throws Exception {
Context ctx = vertx.getOrCreateContext();
server.requestHandler(req -> {
Handler<AsyncResult<HttpServerResponse>> handler = ar -> {
assertSame(ctx, Vertx.currentContext());
assertTrue(ar.succeeded());
HttpServerResponse response = ar.result();
response.end("the_content");
assertIllegalStateException(() -> response.push(HttpMethod.GET, "/wibble2", resp -> {
}));
};
pusher.accept(req.response(), handler);
});
startServer(ctx);
TestClient client = new TestClient();
ChannelFuture fut = client.connect(DEFAULT_HTTPS_PORT, DEFAULT_HTTPS_HOST, request -> {
int id = request.nextStreamId();
Http2ConnectionEncoder encoder = request.encoder;
encoder.writeHeaders(request.context, id, requestHeaders, 0, true, request.context.newPromise());
Map<Integer, Http2Headers> pushed = new HashMap<>();
request.decoder.frameListener(new Http2FrameAdapter() {
@Override
public void onPushPromiseRead(ChannelHandlerContext ctx, int streamId, int promisedStreamId, Http2Headers headers, int padding) throws Http2Exception {
pushed.put(promisedStreamId, headers);
}
@Override
public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding, boolean endOfStream) throws Http2Exception {
int delta = super.onDataRead(ctx, streamId, data, padding, endOfStream);
String content = data.toString(StandardCharsets.UTF_8);
vertx.runOnContext(v -> {
assertEquals(Collections.singleton(streamId), pushed.keySet());
assertEquals("the_content", content);
Http2Headers pushedHeaders = pushed.get(streamId);
headerChecker.accept(pushedHeaders);
testComplete();
});
return delta;
}
});
});
fut.sync();
await();
}
use of io.netty.handler.codec.http2.LastInboundHandler.Consumer in project vert.x by eclipse.
the class HttpTest method testDeliverPausedBufferWhenResume.
private void testDeliverPausedBufferWhenResume(Consumer<Runnable> scheduler) throws Exception {
Buffer data = TestUtils.randomBuffer(2048);
int num = 10;
waitFor(num);
List<CompletableFuture<Void>> resumes = Collections.synchronizedList(new ArrayList<>());
for (int i = 0; i < num; i++) {
resumes.add(new CompletableFuture<>());
}
server.requestHandler(req -> {
int idx = Integer.parseInt(req.path().substring(1));
HttpServerResponse resp = req.response();
resumes.get(idx).thenAccept(v -> {
resp.end();
});
resp.setChunked(true).write(data);
});
startServer(testAddress);
client.close();
client = vertx.createHttpClient(createBaseClientOptions().setMaxPoolSize(1).setKeepAlive(true));
for (int i = 0; i < num; i++) {
int idx = i;
client.request(new RequestOptions(requestOptions).setURI("/" + i)).onComplete(onSuccess(req -> {
req.send(onSuccess(resp -> {
Buffer body = Buffer.buffer();
Thread t = Thread.currentThread();
resp.handler(buff -> {
assertSame(t, Thread.currentThread());
resumes.get(idx).complete(null);
body.appendBuffer(buff);
});
resp.endHandler(v -> {
// assertEquals(data, body);
complete();
});
resp.pause();
scheduler.accept(resp::resume);
}));
}));
}
await();
}
use of io.netty.handler.codec.http2.LastInboundHandler.Consumer in project ambry by linkedin.
the class MultiplexedChannelRecord method closeAndExecuteOnChildChannels.
private void closeAndExecuteOnChildChannels(Consumer<Channel> childChannelConsumer) {
NettyUtils.doInEventLoop(parentChannel.eventLoop(), () -> {
if (state == RecordState.CLOSED) {
return;
}
state = RecordState.CLOSED;
// Create a copy of the children, because they may be modified by the consumer.
List<Http2StreamChannel> childrenToClose = new ArrayList<>(streamChannels.values());
for (Channel childChannel : childrenToClose) {
childChannelConsumer.accept(childChannel);
log.debug("fire exception to stream {} {} pipeline: {}. Active: {}", childChannel.hashCode(), childChannel, childChannel.pipeline(), childChannel.isOpen());
}
});
}
use of io.netty.handler.codec.http2.LastInboundHandler.Consumer 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());
}
use of io.netty.handler.codec.http2.LastInboundHandler.Consumer in project netty by netty.
the class Http2MultiplexTest method childQueueIsDrainedAndNewDataIsDispatchedInParentReadLoopAutoRead.
@Test
public void childQueueIsDrainedAndNewDataIsDispatchedInParentReadLoopAutoRead() {
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);
}
}
};
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());
// 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(10);
shouldDisableAutoRead.set(true);
childChannel.config().setAutoRead(true);
frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("3"), 0, false);
frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("4"), 0, false);
// Detecting EOS should flush all pending data regardless of read calls.
assertEqualsAndRelease(dataFrame2, inboundHandler.<Http2DataFrame>readInbound());
assertEqualsAndRelease(dataFrame3, inboundHandler.<Http2DataFrame>readInbound());
assertEqualsAndRelease(dataFrame4, inboundHandler.<Http2DataFrame>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 read when auto read was off + 1 for when auto read was back on
assertEquals(3, channelReadCompleteCount.get());
}
Aggregations