use of org.eclipse.jetty.http2.HTTP2Stream in project vert.x by eclipse.
the class Http2ServerConnection method createRequest.
private Http2ServerRequest createRequest(int streamId, Http2Headers headers, boolean streamEnded) {
Http2Stream stream = handler.connection().stream(streamId);
String contentEncoding = options.isCompressionSupported() ? HttpUtils.determineContentEncoding(headers) : null;
Http2ServerRequest request = new Http2ServerRequest(this, options.getTracingPolicy(), streamContextSupplier.get(), serverOrigin, headers, contentEncoding, streamEnded);
request.isConnect = request.method() == HttpMethod.CONNECT;
request.init(stream);
return request;
}
use of org.eclipse.jetty.http2.HTTP2Stream in project vert.x by eclipse.
the class Http2ServerTest method testStreamPauseResume.
private void testStreamPauseResume(Function<HttpServerRequest, Future<ReadStream<Buffer>>> streamProvider) throws Exception {
Buffer expected = Buffer.buffer();
String chunk = TestUtils.randomAlphaString(1000);
AtomicBoolean done = new AtomicBoolean();
AtomicBoolean paused = new AtomicBoolean();
Buffer received = Buffer.buffer();
server.requestHandler(req -> {
Future<ReadStream<Buffer>> fut = streamProvider.apply(req);
fut.onComplete(onSuccess(stream -> {
vertx.setPeriodic(1, timerID -> {
if (paused.get()) {
vertx.cancelTimer(timerID);
done.set(true);
// Let some time to accumulate some more buffers
vertx.setTimer(100, id -> {
stream.resume();
});
}
});
stream.handler(received::appendBuffer);
stream.endHandler(v -> {
assertEquals(expected, received);
testComplete();
});
stream.pause();
}));
});
startServer();
TestClient client = new TestClient();
ChannelFuture fut = client.connect(DEFAULT_HTTPS_PORT, DEFAULT_HTTPS_HOST, request -> {
int id = request.nextStreamId();
request.encoder.writeHeaders(request.context, id, POST("/form").set("content-type", "text/plain"), 0, false, request.context.newPromise());
request.context.flush();
Http2Stream stream = request.connection.stream(id);
class Anonymous {
void send() {
boolean writable = request.encoder.flowController().isWritable(stream);
if (writable) {
Buffer buf = Buffer.buffer(chunk);
expected.appendBuffer(buf);
request.encoder.writeData(request.context, id, buf.getByteBuf(), 0, false, request.context.newPromise());
request.context.flush();
request.context.executor().execute(this::send);
} else {
request.encoder.writeData(request.context, id, Unpooled.EMPTY_BUFFER, 0, true, request.context.newPromise());
request.context.flush();
paused.set(true);
}
}
}
new Anonymous().send();
});
fut.sync();
await();
}
use of org.eclipse.jetty.http2.HTTP2Stream in project rest.li by linkedin.
the class Http2PipelinePropertyUtil method doAction.
private static <T> T doAction(ChannelHandlerContext ctx, Http2Connection http2Connection, int streamId, AttributeKey<Http2Connection.PropertyKey> key, BiFunction<Http2Stream, Http2Connection.PropertyKey, T> function) {
ArgumentUtil.notNull(http2Connection, "http2Connection");
final Http2Stream stream = http2Connection.stream(streamId);
if (stream == null) {
LOG.debug("Stream {} no longer exists", streamId);
return null;
}
final Http2Connection.PropertyKey propertyKey = getKey(ctx, key);
if (propertyKey == null) {
LOG.debug("Property key {} is not valid", key);
return null;
}
return function.apply(stream, propertyKey);
}
use of org.eclipse.jetty.http2.HTTP2Stream in project jetty.project by eclipse.
the class StreamCloseTest method testRequestDataClosedResponseDataClosedClosesStream.
@Test
public void testRequestDataClosedResponseDataClosedClosesStream() throws Exception {
final CountDownLatch serverDataLatch = new CountDownLatch(1);
start(new ServerSessionListener.Adapter() {
@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
MetaData.Response metaData = new MetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
HeadersFrame response = new HeadersFrame(stream.getId(), metaData, null, false);
Callback.Completable completable = new Callback.Completable();
stream.headers(response, completable);
return new Stream.Listener.Adapter() {
@Override
public void onData(final Stream stream, DataFrame frame, final Callback callback) {
Assert.assertTrue(((HTTP2Stream) stream).isRemotelyClosed());
// We must copy the data that we send asynchronously.
ByteBuffer data = frame.getData();
ByteBuffer copy = ByteBuffer.allocate(data.remaining());
copy.put(data).flip();
completable.thenRun(() -> stream.data(new DataFrame(stream.getId(), copy, frame.isEndStream()), new Callback() {
@Override
public void succeeded() {
Assert.assertTrue(stream.isClosed());
Assert.assertEquals(0, stream.getSession().getStreams().size());
callback.succeeded();
serverDataLatch.countDown();
}
}));
}
};
}
});
final CountDownLatch completeLatch = new CountDownLatch(1);
Session session = newClient(new Session.Listener.Adapter());
HeadersFrame frame = new HeadersFrame(newRequest("GET", new HttpFields()), null, false);
FuturePromise<Stream> promise = new FuturePromise<>();
session.newStream(frame, promise, new Stream.Listener.Adapter() {
@Override
public void onData(Stream stream, DataFrame frame, Callback callback) {
// The sent data callback may not be notified yet here.
callback.succeeded();
completeLatch.countDown();
}
});
final Stream stream = promise.get(5, TimeUnit.SECONDS);
Assert.assertFalse(stream.isClosed());
Assert.assertFalse(((HTTP2Stream) stream).isLocallyClosed());
final CountDownLatch clientDataLatch = new CountDownLatch(1);
stream.data(new DataFrame(stream.getId(), ByteBuffer.wrap(new byte[512]), true), new Callback() {
@Override
public void succeeded() {
// Here the stream may be just locally closed or fully closed.
clientDataLatch.countDown();
}
});
Assert.assertTrue(clientDataLatch.await(5, TimeUnit.SECONDS));
Assert.assertTrue(serverDataLatch.await(5, TimeUnit.SECONDS));
Assert.assertTrue(completeLatch.await(5, TimeUnit.SECONDS));
Assert.assertTrue(stream.isClosed());
Assert.assertEquals(0, stream.getSession().getStreams().size());
}
use of org.eclipse.jetty.http2.HTTP2Stream in project vert.x by eclipse.
the class Http2ServerConnection method onHeadersRead.
@Override
public synchronized void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int padding, boolean endOfStream) {
VertxHttp2Stream stream = streams.get(streamId);
if (stream == null) {
if (isMalformedRequest(headers)) {
handler.writeReset(streamId, Http2Error.PROTOCOL_ERROR.code());
return;
}
String contentEncoding = options.isCompressionSupported() ? HttpUtils.determineContentEncoding(headers) : null;
Http2Stream s = handler.connection().stream(streamId);
boolean writable = handler.encoder().flowController().isWritable(s);
Http2ServerRequestImpl req = new Http2ServerRequestImpl(this, s, metrics, serverOrigin, headers, contentEncoding, writable);
stream = req;
CharSequence value = headers.get(HttpHeaderNames.EXPECT);
if (options.isHandle100ContinueAutomatically() && ((value != null && HttpHeaderValues.CONTINUE.equals(value)) || headers.contains(HttpHeaderNames.EXPECT, HttpHeaderValues.CONTINUE))) {
req.response().writeContinue();
}
streams.put(streamId, req);
context.executeFromIO(() -> {
Http2ServerResponseImpl resp = req.response();
resp.beginRequest();
requestHandler.handle(req);
boolean hasPush = resp.endRequest();
if (hasPush) {
ctx.flush();
}
});
} else {
// Http server request trailer - not implemented yet (in api)
}
if (endOfStream) {
context.executeFromIO(stream::onEnd);
}
}
Aggregations