Search in sources :

Example 11 with Http2Stream

use of io.netty.handler.codec.http2.Http2Stream in project vert.x by eclipse.

the class Http2ServerTest method testStreamPauseResume.

private void testStreamPauseResume(Function<HttpServerRequest, 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 -> {
        ReadStream<Buffer> stream = streamProvider.apply(req);
        vertx.setPeriodic(1, timerID -> {
            if (paused.get()) {
                vertx.cancelTimer(timerID);
                done.set(true);
                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();
}
Also used : Buffer(io.vertx.core.buffer.Buffer) ChannelFuture(io.netty.channel.ChannelFuture) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Http2Stream(io.netty.handler.codec.http2.Http2Stream)

Example 12 with Http2Stream

use of io.netty.handler.codec.http2.Http2Stream in project jetty.project by eclipse.

the class FlowControlStrategyTest method testWindowSizeUpdates.

@Test
public void testWindowSizeUpdates() throws Exception {
    final CountDownLatch prefaceLatch = new CountDownLatch(1);
    final CountDownLatch stream1Latch = new CountDownLatch(1);
    final CountDownLatch stream2Latch = new CountDownLatch(1);
    final CountDownLatch settingsLatch = new CountDownLatch(1);
    start(new ServerSessionListener.Adapter() {

        @Override
        public Map<Integer, Integer> onPreface(Session session) {
            HTTP2Session serverSession = (HTTP2Session) session;
            Assert.assertEquals(FlowControlStrategy.DEFAULT_WINDOW_SIZE, serverSession.getSendWindow());
            Assert.assertEquals(FlowControlStrategy.DEFAULT_WINDOW_SIZE, serverSession.getRecvWindow());
            prefaceLatch.countDown();
            return null;
        }

        @Override
        public void onSettings(Session session, SettingsFrame frame) {
            for (Stream stream : session.getStreams()) {
                HTTP2Stream serverStream = (HTTP2Stream) stream;
                Assert.assertEquals(0, serverStream.getSendWindow());
                Assert.assertEquals(FlowControlStrategy.DEFAULT_WINDOW_SIZE, serverStream.getRecvWindow());
            }
            settingsLatch.countDown();
        }

        @Override
        public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
            HTTP2Stream serverStream = (HTTP2Stream) stream;
            MetaData.Request request = (MetaData.Request) frame.getMetaData();
            if ("GET".equalsIgnoreCase(request.getMethod())) {
                Assert.assertEquals(FlowControlStrategy.DEFAULT_WINDOW_SIZE, serverStream.getSendWindow());
                Assert.assertEquals(FlowControlStrategy.DEFAULT_WINDOW_SIZE, serverStream.getRecvWindow());
                stream1Latch.countDown();
            } else {
                Assert.assertEquals(0, serverStream.getSendWindow());
                Assert.assertEquals(FlowControlStrategy.DEFAULT_WINDOW_SIZE, serverStream.getRecvWindow());
                stream2Latch.countDown();
            }
            return null;
        }
    });
    HTTP2Session clientSession = (HTTP2Session) newClient(new Session.Listener.Adapter());
    Assert.assertEquals(FlowControlStrategy.DEFAULT_WINDOW_SIZE, clientSession.getSendWindow());
    Assert.assertEquals(FlowControlStrategy.DEFAULT_WINDOW_SIZE, clientSession.getRecvWindow());
    Assert.assertTrue(prefaceLatch.await(5, TimeUnit.SECONDS));
    MetaData.Request request1 = newRequest("GET", new HttpFields());
    FuturePromise<Stream> promise1 = new FuturePromise<>();
    clientSession.newStream(new HeadersFrame(request1, null, true), promise1, new Stream.Listener.Adapter());
    HTTP2Stream clientStream1 = (HTTP2Stream) promise1.get(5, TimeUnit.SECONDS);
    Assert.assertEquals(FlowControlStrategy.DEFAULT_WINDOW_SIZE, clientStream1.getSendWindow());
    Assert.assertEquals(FlowControlStrategy.DEFAULT_WINDOW_SIZE, clientStream1.getRecvWindow());
    Assert.assertTrue(stream1Latch.await(5, TimeUnit.SECONDS));
    // Send a SETTINGS frame that changes the window size.
    // This tells the server that its stream send window must be updated,
    // so on the client it's the receive window that must be updated.
    Map<Integer, Integer> settings = new HashMap<>();
    settings.put(SettingsFrame.INITIAL_WINDOW_SIZE, 0);
    SettingsFrame frame = new SettingsFrame(settings, false);
    FutureCallback callback = new FutureCallback();
    clientSession.settings(frame, callback);
    callback.get(5, TimeUnit.SECONDS);
    Assert.assertEquals(FlowControlStrategy.DEFAULT_WINDOW_SIZE, clientStream1.getSendWindow());
    Assert.assertEquals(0, clientStream1.getRecvWindow());
    settingsLatch.await(5, TimeUnit.SECONDS);
    // Now create a new stream, it must pick up the new value.
    MetaData.Request request2 = newRequest("POST", new HttpFields());
    FuturePromise<Stream> promise2 = new FuturePromise<>();
    clientSession.newStream(new HeadersFrame(request2, null, true), promise2, new Stream.Listener.Adapter());
    HTTP2Stream clientStream2 = (HTTP2Stream) promise2.get(5, TimeUnit.SECONDS);
    Assert.assertEquals(FlowControlStrategy.DEFAULT_WINDOW_SIZE, clientStream2.getSendWindow());
    Assert.assertEquals(0, clientStream2.getRecvWindow());
    Assert.assertTrue(stream2Latch.await(5, TimeUnit.SECONDS));
}
Also used : ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) HTTP2Stream(org.eclipse.jetty.http2.HTTP2Stream) HashMap(java.util.HashMap) FuturePromise(org.eclipse.jetty.util.FuturePromise) CountDownLatch(java.util.concurrent.CountDownLatch) HTTP2Session(org.eclipse.jetty.http2.HTTP2Session) HeadersFrame(org.eclipse.jetty.http2.frames.HeadersFrame) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SettingsFrame(org.eclipse.jetty.http2.frames.SettingsFrame) MetaData(org.eclipse.jetty.http.MetaData) HttpFields(org.eclipse.jetty.http.HttpFields) HTTP2Stream(org.eclipse.jetty.http2.HTTP2Stream) Stream(org.eclipse.jetty.http2.api.Stream) Map(java.util.Map) HashMap(java.util.HashMap) ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) FutureCallback(org.eclipse.jetty.util.FutureCallback) HTTP2Session(org.eclipse.jetty.http2.HTTP2Session) Session(org.eclipse.jetty.http2.api.Session) ISession(org.eclipse.jetty.http2.ISession) Test(org.junit.Test)

Example 13 with Http2Stream

use of io.netty.handler.codec.http2.Http2Stream in project jetty.project by eclipse.

the class StreamCloseTest method testPushedStreamIsClosed.

@Test
public void testPushedStreamIsClosed() throws Exception {
    final CountDownLatch serverLatch = new CountDownLatch(1);
    start(new ServerSessionListener.Adapter() {

        @Override
        public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
            PushPromiseFrame pushFrame = new PushPromiseFrame(stream.getId(), 0, newRequest("GET", new HttpFields()));
            stream.push(pushFrame, new Promise.Adapter<Stream>() {

                @Override
                public void succeeded(final Stream pushedStream) {
                    // When created, pushed stream must be implicitly remotely closed.
                    Assert.assertTrue(((HTTP2Stream) pushedStream).isRemotelyClosed());
                    // Send some data with endStream = true.
                    pushedStream.data(new DataFrame(pushedStream.getId(), ByteBuffer.allocate(16), true), new Callback() {

                        @Override
                        public void succeeded() {
                            Assert.assertTrue(pushedStream.isClosed());
                            serverLatch.countDown();
                        }
                    });
                }
            }, new Stream.Listener.Adapter());
            HeadersFrame response = new HeadersFrame(stream.getId(), new MetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields()), null, true);
            stream.headers(response, Callback.NOOP);
            return null;
        }
    });
    Session session = newClient(new Session.Listener.Adapter());
    HeadersFrame frame = new HeadersFrame(newRequest("GET", new HttpFields()), null, true);
    final CountDownLatch clientLatch = new CountDownLatch(1);
    session.newStream(frame, new Promise.Adapter<>(), new Stream.Listener.Adapter() {

        @Override
        public Stream.Listener onPush(Stream pushedStream, PushPromiseFrame frame) {
            Assert.assertTrue(((HTTP2Stream) pushedStream).isLocallyClosed());
            return new Adapter() {

                @Override
                public void onData(Stream pushedStream, DataFrame frame, Callback callback) {
                    Assert.assertTrue(pushedStream.isClosed());
                    callback.succeeded();
                    clientLatch.countDown();
                }
            };
        }
    });
    Assert.assertTrue(serverLatch.await(5, TimeUnit.SECONDS));
    Assert.assertTrue(clientLatch.await(5, TimeUnit.SECONDS));
}
Also used : ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) HTTP2Stream(org.eclipse.jetty.http2.HTTP2Stream) DataFrame(org.eclipse.jetty.http2.frames.DataFrame) CountDownLatch(java.util.concurrent.CountDownLatch) PushPromiseFrame(org.eclipse.jetty.http2.frames.PushPromiseFrame) HeadersFrame(org.eclipse.jetty.http2.frames.HeadersFrame) Promise(org.eclipse.jetty.util.Promise) FuturePromise(org.eclipse.jetty.util.FuturePromise) Callback(org.eclipse.jetty.util.Callback) HttpFields(org.eclipse.jetty.http.HttpFields) HTTP2Stream(org.eclipse.jetty.http2.HTTP2Stream) Stream(org.eclipse.jetty.http2.api.Stream) ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) HTTP2Session(org.eclipse.jetty.http2.HTTP2Session) Session(org.eclipse.jetty.http2.api.Session) Test(org.junit.Test)

Example 14 with Http2Stream

use of io.netty.handler.codec.http2.Http2Stream in project jetty.project by eclipse.

the class StreamCloseTest method testRequestClosedRemotelyClosesStream.

@Test
public void testRequestClosedRemotelyClosesStream() throws Exception {
    final CountDownLatch latch = new CountDownLatch(1);
    start(new ServerSessionListener.Adapter() {

        @Override
        public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
            Assert.assertTrue(((HTTP2Stream) stream).isRemotelyClosed());
            latch.countDown();
            return null;
        }
    });
    Session session = newClient(new Session.Listener.Adapter());
    HeadersFrame frame = new HeadersFrame(newRequest("GET", new HttpFields()), null, true);
    FuturePromise<Stream> promise = new FuturePromise<>();
    session.newStream(frame, promise, null);
    Stream stream = promise.get(5, TimeUnit.SECONDS);
    Assert.assertTrue(((HTTP2Stream) stream).isLocallyClosed());
    Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
}
Also used : ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) HTTP2Stream(org.eclipse.jetty.http2.HTTP2Stream) FuturePromise(org.eclipse.jetty.util.FuturePromise) CountDownLatch(java.util.concurrent.CountDownLatch) HeadersFrame(org.eclipse.jetty.http2.frames.HeadersFrame) HttpFields(org.eclipse.jetty.http.HttpFields) HTTP2Stream(org.eclipse.jetty.http2.HTTP2Stream) Stream(org.eclipse.jetty.http2.api.Stream) ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) HTTP2Session(org.eclipse.jetty.http2.HTTP2Session) Session(org.eclipse.jetty.http2.api.Session) Test(org.junit.Test)

Example 15 with Http2Stream

use of io.netty.handler.codec.http2.Http2Stream in project vert.x by eclipse.

the class Http2ClientConnection method onPushPromiseRead.

@Override
public synchronized void onPushPromiseRead(ChannelHandlerContext ctx, int streamId, int promisedStreamId, Http2Headers headers, int padding) throws Http2Exception {
    Http2ClientStream stream = (Http2ClientStream) streams.get(streamId);
    if (stream != null) {
        Handler<HttpClientRequest> pushHandler = stream.pushHandler();
        if (pushHandler != null) {
            context.executeFromIO(() -> {
                String rawMethod = headers.method().toString();
                HttpMethod method = HttpUtils.toVertxMethod(rawMethod);
                String uri = headers.path().toString();
                String host = headers.authority() != null ? headers.authority().toString() : null;
                MultiMap headersMap = new Http2HeadersAdaptor(headers);
                Http2Stream promisedStream = handler.connection().stream(promisedStreamId);
                int port = remoteAddress().port();
                HttpClientRequestPushPromise pushReq = new HttpClientRequestPushPromise(this, promisedStream, http2Pool.client, isSsl(), method, rawMethod, uri, host, port, headersMap);
                if (metrics.isEnabled()) {
                    pushReq.metric(metrics.responsePushed(queueMetric, metric(), localAddress(), remoteAddress(), pushReq));
                }
                streams.put(promisedStreamId, pushReq.getStream());
                pushHandler.handle(pushReq);
            });
            return;
        }
    }
    handler.writeReset(promisedStreamId, Http2Error.CANCEL.code());
}
Also used : MultiMap(io.vertx.core.MultiMap) HttpClientRequest(io.vertx.core.http.HttpClientRequest) Http2Stream(io.netty.handler.codec.http2.Http2Stream) HttpMethod(io.vertx.core.http.HttpMethod)

Aggregations

Http2Stream (io.netty.handler.codec.http2.Http2Stream)21 Test (org.junit.Test)16 Http2Exception (io.netty.handler.codec.http2.Http2Exception)9 ByteBuf (io.netty.buffer.ByteBuf)8 CountDownLatch (java.util.concurrent.CountDownLatch)7 Http2StreamVisitor (io.netty.handler.codec.http2.Http2StreamVisitor)5 Metadata (io.grpc.Metadata)4 ChannelFuture (io.netty.channel.ChannelFuture)4 Http2LocalFlowController (io.netty.handler.codec.http2.Http2LocalFlowController)4 Endpoint (io.netty.handler.codec.http2.Http2Connection.Endpoint)3 FlowControlled (io.netty.handler.codec.http2.Http2RemoteFlowController.FlowControlled)3 HttpFields (org.eclipse.jetty.http.HttpFields)3 HTTP2Session (org.eclipse.jetty.http2.HTTP2Session)3 HTTP2Stream (org.eclipse.jetty.http2.HTTP2Stream)3 Session (org.eclipse.jetty.http2.api.Session)3 Stream (org.eclipse.jetty.http2.api.Stream)3 ServerSessionListener (org.eclipse.jetty.http2.api.server.ServerSessionListener)3 HeadersFrame (org.eclipse.jetty.http2.frames.HeadersFrame)3 FuturePromise (org.eclipse.jetty.util.FuturePromise)3 Status (io.grpc.Status)2