Search in sources :

Example 21 with Http2Stream

use of io.netty.handler.codec.http2.Http2Stream in project Payara by payara.

the class ApplicationPushBuilder method push.

@Override
public void push() {
    if (path == null) {
        throw new IllegalStateException(rb.getString(LogFacade.NO_PUSH_PATH_EXCEPTION));
    }
    Http2Stream http2Stream = (Http2Stream) coyoteRequest.getAttribute(Http2Stream.HTTP2_STREAM_ATTRIBUTE);
    if (http2Stream == null || !http2Stream.isPushEnabled()) {
        return;
    }
    // modify pathLocal rather than path
    String pathLocal = ((path.charAt(0) == '/') ? path : coyoteRequest.getContextPath() + '/' + path);
    if (queryString != null) {
        pathLocal += ((pathLocal.indexOf('?') != -1) ? '&' + queryString : '?' + queryString);
    }
    // Session ID (do this before setting the path since it may change it)
    if (sessionId != null) {
        if (addSessionPathParameter) {
            pathLocal = pathLocal + ";" + sessionCookieName + "=" + sessionId;
        }
        if (addSessionCookie) {
            cookies.add(new Cookie(sessionCookieName, sessionId));
        }
    }
    PushEvent.PushEventBuilder pushEventBuilder = PushEvent.builder();
    pushEventBuilder.method(method);
    pushEventBuilder.headers(headers);
    pushEventBuilder.path(pathLocal);
    pushEventBuilder.httpRequest(coyoteRequest.getRequest());
    coyoteRequest.getContext().notifyDownstream(pushEventBuilder.build());
    // Reset for next call
    path = null;
    for (Header conditionalHeader : CONDITIONAL_HEADERS) {
        headers.removeHeader(conditionalHeader);
    }
}
Also used : Cookie(org.glassfish.grizzly.http.Cookie) PushEvent(org.glassfish.grizzly.http.server.http2.PushEvent) Header(org.glassfish.grizzly.http.util.Header) Http2Stream(org.glassfish.grizzly.http2.Http2Stream)

Example 22 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 23 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 24 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)

Example 25 with Http2Stream

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

the class VertxHttp2ConnectionHandler method _writeData.

private void _writeData(Http2Stream stream, ByteBuf chunk, boolean end) {
    encoder().writeData(ctx, stream.id(), chunk, 0, end, ctx.newPromise());
    Http2RemoteFlowController controller = encoder().flowController();
    if (!controller.isWritable(stream) || end) {
        try {
            encoder().flowController().writePendingBytes();
        } catch (Http2Exception e) {
            onError(ctx, e);
        }
    }
    ctx.channel().flush();
}
Also used : Http2Exception(io.netty.handler.codec.http2.Http2Exception) Http2RemoteFlowController(io.netty.handler.codec.http2.Http2RemoteFlowController)

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