@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame requestFrame)
{
HttpFields fields = new HttpFields();
MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, 200, fields);
HeadersFrame responseFrame = new HeadersFrame(stream.getId(), response, null, true);
stream.headers(responseFrame, Callback.Adapter.INSTANCE);
return new Stream.Listener.Adapter()
{
private final AtomicInteger dataFrames = new AtomicInteger();
@Override
public void onData(Stream stream, DataFrame frame, Callback callback)
{
dataLatch.countDown();
int dataFrameCount = dataFrames.incrementAndGet();
if (dataFrameCount == 1)
{
callbackRef.set(callback);
Map<Integer, Integer> settings = new HashMap<>();
settings.put(SettingsFrame.INITIAL_WINDOW_SIZE, size);
stream.getSession().settings(new SettingsFrame(settings, false), Callback.Adapter.INSTANCE);
// Do not succeed the callback here.
}
else if (dataFrameCount > 1)
{
// Consume the data.
callback.succeeded();
}
}
};
}
});
// Two SETTINGS frames, the initial one and the one we send from the server.
final CountDownLatch settingsLatch = new CountDownLatch(2);
Session session = newClient(new Session.Listener.Adapter()
{
@Override
public void onSettings(Session session, SettingsFrame frame)
{
settingsLatch.countDown();
}
});
MetaData.Request request = newRequest("POST", new HttpFields());
FuturePromise<Stream> promise = new FuturePromise<>();
session.newStream(new HeadersFrame(0, request, null, false), promise, new Stream.Listener.Adapter());
Stream stream = promise.get(5, TimeUnit.SECONDS);
// Send first chunk that exceeds the window.
stream.data(new DataFrame(stream.getId(), ByteBuffer.allocate(size * 2), false), Callback.Adapter.INSTANCE);
settingsLatch.await(5, TimeUnit.SECONDS);