Search in sources :

Example 41 with Http2Stream

use of io.netty.handler.codec.http2.Http2Stream in project grpc-java by grpc.

the class NettyHandlerTestBase method windowUpdateMatchesTarget.

@Test
public void windowUpdateMatchesTarget() throws Exception {
    manualSetUp();
    Http2Stream connectionStream = connection().connectionStream();
    Http2LocalFlowController localFlowController = connection().local().flowController();
    makeStream();
    AbstractNettyHandler handler = (AbstractNettyHandler) handler();
    handler.setAutoTuneFlowControl(true);
    ByteBuf data = ctx().alloc().buffer(1024);
    while (data.isWritable()) {
        data.writeLong(1111);
    }
    int length = data.readableBytes();
    ByteBuf frame = dataFrame(3, false, data.copy());
    channelRead(frame);
    int accumulator = length;
    // 40 is arbitrary, any number large enough to trigger a window update would work
    for (int i = 0; i < 40; i++) {
        channelRead(dataFrame(3, false, data.copy()));
        accumulator += length;
    }
    long pingData = handler.flowControlPing().payload();
    channelRead(pingFrame(true, pingData));
    assertEquals(accumulator, handler.flowControlPing().getDataSincePing());
    assertEquals(2 * accumulator, localFlowController.initialWindowSize(connectionStream));
}
Also used : Http2LocalFlowController(io.netty.handler.codec.http2.Http2LocalFlowController) Http2Stream(io.netty.handler.codec.http2.Http2Stream) CompositeByteBuf(io.netty.buffer.CompositeByteBuf) ByteBuf(io.netty.buffer.ByteBuf) Test(org.junit.Test)

Example 42 with Http2Stream

use of io.netty.handler.codec.http2.Http2Stream in project grpc-java by grpc.

the class NettyClientHandler method createStreamTraced.

private void createStreamTraced(final int streamId, final NettyClientStream.TransportState stream, final Http2Headers headers, boolean isGet, final boolean shouldBeCountedForInUse, final ChannelPromise promise) {
    // Create an intermediate promise so that we can intercept the failure reported back to the
    // application.
    ChannelPromise tempPromise = ctx().newPromise();
    encoder().writeHeaders(ctx(), streamId, headers, 0, isGet, tempPromise).addListener(new ChannelFutureListener() {

        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
            if (future.isSuccess()) {
                // The http2Stream will be null in case a stream buffered in the encoder
                // was canceled via RST_STREAM.
                Http2Stream http2Stream = connection().stream(streamId);
                if (http2Stream != null) {
                    stream.getStatsTraceContext().clientOutboundHeaders();
                    http2Stream.setProperty(streamKey, stream);
                    // be later than we would like.
                    if (shouldBeCountedForInUse) {
                        inUseState.updateObjectInUse(http2Stream, true);
                    }
                    // Attach the client stream to the HTTP/2 stream object as user data.
                    stream.setHttp2Stream(http2Stream);
                }
                // Otherwise, the stream has been cancelled and Netty is sending a
                // RST_STREAM frame which causes it to purge pending writes from the
                // flow-controller and delete the http2Stream. The stream listener has already
                // been notified of cancellation so there is nothing to do.
                // Just forward on the success status to the original promise.
                promise.setSuccess();
            } else {
                Throwable cause = future.cause();
                if (cause instanceof StreamBufferingEncoder.Http2GoAwayException) {
                    StreamBufferingEncoder.Http2GoAwayException e = (StreamBufferingEncoder.Http2GoAwayException) cause;
                    Status status = statusFromH2Error(Status.Code.UNAVAILABLE, "GOAWAY closed buffered stream", e.errorCode(), e.debugData());
                    cause = status.asRuntimeException();
                    stream.transportReportStatus(status, RpcProgress.MISCARRIED, true, new Metadata());
                } else if (cause instanceof StreamBufferingEncoder.Http2ChannelClosedException) {
                    Status status = lifecycleManager.getShutdownStatus();
                    if (status == null) {
                        status = Status.UNAVAILABLE.withCause(cause).withDescription("Connection closed while stream is buffered");
                    }
                    stream.transportReportStatus(status, RpcProgress.MISCARRIED, true, new Metadata());
                }
                promise.setFailure(cause);
            }
        }
    });
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) Status(io.grpc.Status) StreamBufferingEncoder(io.netty.handler.codec.http2.StreamBufferingEncoder) Metadata(io.grpc.Metadata) ChannelPromise(io.netty.channel.ChannelPromise) ChannelFutureListener(io.netty.channel.ChannelFutureListener) Http2Exception(io.netty.handler.codec.http2.Http2Exception) StatusException(io.grpc.StatusException) ClosedChannelException(java.nio.channels.ClosedChannelException) Http2Stream(io.netty.handler.codec.http2.Http2Stream)

Example 43 with Http2Stream

use of io.netty.handler.codec.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());
}
Also used : ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) HTTP2Stream(org.eclipse.jetty.http2.HTTP2Stream) FuturePromise(org.eclipse.jetty.util.FuturePromise) DataFrame(org.eclipse.jetty.http2.frames.DataFrame) CountDownLatch(java.util.concurrent.CountDownLatch) HeadersFrame(org.eclipse.jetty.http2.frames.HeadersFrame) ByteBuffer(java.nio.ByteBuffer) Callback(org.eclipse.jetty.util.Callback) 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) 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 44 with Http2Stream

use of io.netty.handler.codec.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);
    }
}
Also used : Http2Stream(io.netty.handler.codec.http2.Http2Stream)

Example 45 with Http2Stream

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

the class Http2ServerConnection method sendPush.

synchronized void sendPush(int streamId, String host, HttpMethod method, MultiMap headers, String path, Handler<AsyncResult<HttpServerResponse>> completionHandler) {
    Http2Headers headers_ = new DefaultHttp2Headers();
    if (method == HttpMethod.OTHER) {
        throw new IllegalArgumentException("Cannot push HttpMethod.OTHER");
    } else {
        headers_.method(method.name());
    }
    headers_.path(path);
    headers_.scheme(isSsl() ? "https" : "http");
    if (host != null) {
        headers_.authority(host);
    }
    if (headers != null) {
        headers.forEach(header -> headers_.add(header.getKey(), header.getValue()));
    }
    handler.writePushPromise(streamId, headers_, new Handler<AsyncResult<Integer>>() {

        @Override
        public void handle(AsyncResult<Integer> ar) {
            if (ar.succeeded()) {
                synchronized (Http2ServerConnection.this) {
                    int promisedStreamId = ar.result();
                    String contentEncoding = HttpUtils.determineContentEncoding(headers_);
                    Http2Stream promisedStream = handler.connection().stream(promisedStreamId);
                    boolean writable = handler.encoder().flowController().isWritable(promisedStream);
                    Push push = new Push(promisedStream, contentEncoding, method, path, writable, completionHandler);
                    streams.put(promisedStreamId, push);
                    if (maxConcurrentStreams == null || concurrentStreams < maxConcurrentStreams) {
                        concurrentStreams++;
                        context.executeFromIO(push::complete);
                    } else {
                        pendingPushes.add(push);
                    }
                }
            } else {
                context.executeFromIO(() -> {
                    completionHandler.handle(Future.failedFuture(ar.cause()));
                });
            }
        }
    });
}
Also used : Http2Headers(io.netty.handler.codec.http2.Http2Headers) DefaultHttp2Headers(io.netty.handler.codec.http2.DefaultHttp2Headers) DefaultHttp2Headers(io.netty.handler.codec.http2.DefaultHttp2Headers) Http2Stream(io.netty.handler.codec.http2.Http2Stream) AsyncResult(io.vertx.core.AsyncResult)

Aggregations

Http2Stream (io.netty.handler.codec.http2.Http2Stream)44 Http2Exception (io.netty.handler.codec.http2.Http2Exception)15 ByteBuf (io.netty.buffer.ByteBuf)12 Test (org.junit.Test)12 Test (org.junit.jupiter.api.Test)9 Http2Connection (io.netty.handler.codec.http2.Http2Connection)8 ChannelFuture (io.netty.channel.ChannelFuture)7 Http2StreamVisitor (io.netty.handler.codec.http2.Http2StreamVisitor)7 CountDownLatch (java.util.concurrent.CountDownLatch)7 Metadata (io.grpc.Metadata)6 Http2LocalFlowController (io.netty.handler.codec.http2.Http2LocalFlowController)6 Status (io.grpc.Status)5 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)5 StreamException (io.netty.handler.codec.http2.Http2Exception.StreamException)5 Channel (io.netty.channel.Channel)4 DefaultHttp2Headers (io.netty.handler.codec.http2.DefaultHttp2Headers)4 Http2Headers (io.netty.handler.codec.http2.Http2Headers)4 AsyncResult (io.vertx.core.AsyncResult)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 Bootstrap (io.netty.bootstrap.Bootstrap)3