Search in sources :

Example 11 with IStream

use of org.eclipse.jetty.http2.IStream in project jetty.project by eclipse.

the class HTTP2Session method push.

@Override
public void push(IStream stream, Promise<Stream> promise, PushPromiseFrame frame, Stream.Listener listener) {
    // Synchronization is necessary to atomically create
    // the stream id and enqueue the frame to be sent.
    boolean queued;
    synchronized (this) {
        int streamId = streamIds.getAndAdd(2);
        frame = new PushPromiseFrame(frame.getStreamId(), streamId, frame.getMetaData());
        final IStream pushStream = createLocalStream(streamId, promise);
        if (pushStream == null)
            return;
        pushStream.setListener(listener);
        ControlEntry entry = new ControlEntry(frame, pushStream, new PromiseCallback<>(promise, pushStream));
        queued = flusher.append(entry);
    }
    // Iterate outside the synchronized block.
    if (queued)
        flusher.iterate();
}
Also used : PushPromiseFrame(org.eclipse.jetty.http2.frames.PushPromiseFrame) EndPoint(org.eclipse.jetty.io.EndPoint)

Example 12 with IStream

use of org.eclipse.jetty.http2.IStream in project jetty.project by eclipse.

the class FlowControlStalledTest method testStreamStalledIsInvokedOnlyOnce.

@Test
public void testStreamStalledIsInvokedOnlyOnce() throws Exception {
    AtomicReference<CountDownLatch> stallLatch = new AtomicReference<>(new CountDownLatch(1));
    CountDownLatch unstallLatch = new CountDownLatch(1);
    start(() -> new BufferingFlowControlStrategy(0.5f) {

        @Override
        public void onStreamStalled(IStream stream) {
            super.onStreamStalled(stream);
            stallLatch.get().countDown();
        }

        @Override
        protected void onStreamUnstalled(IStream stream) {
            super.onStreamUnstalled(stream);
            unstallLatch.countDown();
        }
    }, new ServerSessionListener.Adapter() {

        @Override
        public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
            MetaData.Request request = (MetaData.Request) frame.getMetaData();
            MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, new HttpFields());
            if (request.getURIString().endsWith("/stall")) {
                stream.headers(new HeadersFrame(stream.getId(), response, null, false), new Callback() {

                    @Override
                    public void succeeded() {
                        // Send a large chunk of data so the stream gets stalled.
                        ByteBuffer data = ByteBuffer.allocate(FlowControlStrategy.DEFAULT_WINDOW_SIZE + 1);
                        stream.data(new DataFrame(stream.getId(), data, true), NOOP);
                    }
                });
            } else {
                stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP);
            }
            return null;
        }
    });
    // Use a large session window so that only the stream gets stalled.
    client.setInitialSessionRecvWindow(5 * FlowControlStrategy.DEFAULT_WINDOW_SIZE);
    Session client = newClient(new Session.Listener.Adapter());
    CountDownLatch latch = new CountDownLatch(1);
    Queue<Callback> callbacks = new ArrayDeque<>();
    MetaData.Request request = newRequest("GET", "/stall", new HttpFields());
    client.newStream(new HeadersFrame(request, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter() {

        @Override
        public void onData(Stream stream, DataFrame frame, Callback callback) {
            callbacks.offer(callback);
            if (frame.isEndStream())
                latch.countDown();
        }
    });
    Assert.assertTrue(stallLatch.get().await(5, TimeUnit.SECONDS));
    // First stream is now stalled, check that writing a second stream
    // does not result in the first be notified again of being stalled.
    stallLatch.set(new CountDownLatch(1));
    request = newRequest("GET", "/", new HttpFields());
    client.newStream(new HeadersFrame(request, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter());
    Assert.assertFalse(stallLatch.get().await(1, TimeUnit.SECONDS));
    // Consume all data.
    while (!latch.await(10, TimeUnit.MILLISECONDS)) {
        Callback callback = callbacks.poll();
        if (callback != null)
            callback.succeeded();
    }
    // Make sure the unstall callback is invoked.
    Assert.assertTrue(unstallLatch.await(5, TimeUnit.SECONDS));
}
Also used : ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) IStream(org.eclipse.jetty.http2.IStream) HeadersFrame(org.eclipse.jetty.http2.frames.HeadersFrame) MetaData(org.eclipse.jetty.http.MetaData) HttpFields(org.eclipse.jetty.http.HttpFields) Stream(org.eclipse.jetty.http2.api.Stream) IStream(org.eclipse.jetty.http2.IStream) BufferingFlowControlStrategy(org.eclipse.jetty.http2.BufferingFlowControlStrategy) AtomicReference(java.util.concurrent.atomic.AtomicReference) DataFrame(org.eclipse.jetty.http2.frames.DataFrame) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBuffer(java.nio.ByteBuffer) ArrayDeque(java.util.ArrayDeque) Promise(org.eclipse.jetty.util.Promise) FuturePromise(org.eclipse.jetty.util.FuturePromise) Callback(org.eclipse.jetty.util.Callback) ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) Session(org.eclipse.jetty.http2.api.Session) ISession(org.eclipse.jetty.http2.ISession) Test(org.junit.Test)

Example 13 with IStream

use of org.eclipse.jetty.http2.IStream in project jetty.project by eclipse.

the class HTTP2ClientSession method onHeaders.

@Override
public void onHeaders(HeadersFrame frame) {
    if (LOG.isDebugEnabled())
        LOG.debug("Received {}", frame);
    int streamId = frame.getStreamId();
    IStream stream = getStream(streamId);
    if (stream != null) {
        MetaData metaData = frame.getMetaData();
        if (metaData.isRequest()) {
            onConnectionFailure(ErrorCode.PROTOCOL_ERROR.code, "invalid_response");
        } else {
            stream.process(frame, Callback.NOOP);
            notifyHeaders(stream, frame);
        }
    } else {
        if (LOG.isDebugEnabled())
            LOG.debug("Ignoring {}, stream #{} not found", frame, streamId);
    }
}
Also used : MetaData(org.eclipse.jetty.http.MetaData) IStream(org.eclipse.jetty.http2.IStream) EndPoint(org.eclipse.jetty.io.EndPoint)

Aggregations

IStream (org.eclipse.jetty.http2.IStream)6 EndPoint (org.eclipse.jetty.io.EndPoint)6 Stream (org.eclipse.jetty.http2.api.Stream)5 MetaData (org.eclipse.jetty.http.MetaData)4 HeadersFrame (org.eclipse.jetty.http2.frames.HeadersFrame)3 WindowUpdateFrame (org.eclipse.jetty.http2.frames.WindowUpdateFrame)3 CountDownLatch (java.util.concurrent.CountDownLatch)2 HttpFields (org.eclipse.jetty.http.HttpFields)2 ISession (org.eclipse.jetty.http2.ISession)2 Session (org.eclipse.jetty.http2.api.Session)2 ServerSessionListener (org.eclipse.jetty.http2.api.server.ServerSessionListener)2 DataFrame (org.eclipse.jetty.http2.frames.DataFrame)2 Frame (org.eclipse.jetty.http2.frames.Frame)2 PriorityFrame (org.eclipse.jetty.http2.frames.PriorityFrame)2 ResetFrame (org.eclipse.jetty.http2.frames.ResetFrame)2 Callback (org.eclipse.jetty.util.Callback)2 FuturePromise (org.eclipse.jetty.util.FuturePromise)2 Test (org.junit.Test)2 ByteBuffer (java.nio.ByteBuffer)1 ArrayDeque (java.util.ArrayDeque)1