return null;
}
else
{
// For every stream, send down half the window size of data.
MetaData.Response metaData = new MetaData.Response(HttpVersion.HTTP_2, 200, new HttpFields());
HeadersFrame responseFrame = new HeadersFrame(stream.getId(), metaData, null, false);
stream.headers(responseFrame, Callback.Adapter.INSTANCE);
DataFrame dataFrame = new DataFrame(stream.getId(), ByteBuffer.allocate(windowSize / 2), true);
stream.data(dataFrame, Callback.Adapter.INSTANCE);
return null;
}
}
});
Session session = newClient(new Session.Listener.Adapter());
// First request is just to consume the session window.
final CountDownLatch prepareLatch = new CountDownLatch(1);
MetaData.Request request1 = newRequest("POST", new HttpFields());
session.newStream(new HeadersFrame(0, request1, null, true), new Promise.Adapter<Stream>(), new Stream.Listener.Adapter()
{
@Override
public void onData(Stream stream, DataFrame frame, Callback callback)
{
// Do not consume the data to reduce the session window.
if (frame.isEndStream())
prepareLatch.countDown();
}
});
Assert.assertTrue(prepareLatch.await(5, TimeUnit.SECONDS));
final AtomicReference<Callback> callbackRef2 = new AtomicReference<>();
final AtomicReference<Callback> callbackRef3 = new AtomicReference<>();
// Second request will consume half the session window.
MetaData.Request request2 = newRequest("GET", new HttpFields());
session.newStream(new HeadersFrame(0, request2, null, true), new Promise.Adapter<Stream>(), new Stream.Listener.Adapter()
{
@Override
public void onData(Stream stream, DataFrame frame, Callback callback)
{
// Do not consume it to stall flow control.
callbackRef2.set(callback);
}
});
// Third request will consume the session window, which is now stalled.
// A fourth request will not be able to receive data.
MetaData.Request request3 = newRequest("GET", new HttpFields());
session.newStream(new HeadersFrame(0, request3, null, true), new Promise.Adapter<Stream>(), new Stream.Listener.Adapter()
{
@Override
public void onData(Stream stream, DataFrame frame, Callback callback)
{
// Do not consume it to stall flow control.
callbackRef3.set(callback);
}
});
// Fourth request is now stalled.
final CountDownLatch latch = new CountDownLatch(1);
MetaData.Request request4 = newRequest("GET", new HttpFields());
session.newStream(new HeadersFrame(0, request4, null, true), new Promise.Adapter<Stream>(), new Stream.Listener.Adapter()
{
@Override
public void onData(Stream stream, DataFrame frame, Callback callback)
{