HTTP/2 inbound flow control requests too many bytes in WINDOW_UPDATE.

Motivation:
The DefaultHttp2InboundFlowController uses processedBytes to determine
when to send the WINDOW_UPDATE, but uses window to determine the delta
to send in the request. This is incorrect since we shouldn't be
requesting bytes that haven't been processed.

Modifications:
Changed DefaultHttp2InboundFlowController to use processedBytes in the
calculation of the delta to send in the WINDOW_UPDATE request.

Result:
Inbound flow control only asks for bytes that have been processed in
WINDOW_UPDATE.
This commit is contained in:
nmittler 2014-11-21 07:31:34 -08:00
parent 171fbf3b41
commit c9e5238ea6
2 changed files with 5 additions and 3 deletions

View File

@ -314,7 +314,7 @@ public class DefaultHttp2InboundFlowController implements Http2InboundFlowContro
*/ */
void updateWindow(ChannelHandlerContext ctx) { void updateWindow(ChannelHandlerContext ctx) {
// Expand the window for this stream back to the size of the initial window. // Expand the window for this stream back to the size of the initial window.
int deltaWindowSize = initialWindowSize() - window; int deltaWindowSize = initialWindowSize() - processedWindow;
processedWindow += deltaWindowSize; processedWindow += deltaWindowSize;
try { try {
addAndGet(deltaWindowSize); addAndGet(deltaWindowSize);

View File

@ -179,12 +179,14 @@ public class DefaultHttp2InboundFlowControllerTest {
int data2 = window(STREAM_ID); int data2 = window(STREAM_ID);
applyFlowControl(STREAM_ID, data2, 0, false); applyFlowControl(STREAM_ID, data2, 0, false);
returnProcessedBytes(STREAM_ID, data2); returnProcessedBytes(STREAM_ID, data2);
verifyWindowUpdateSent(STREAM_ID, data1 + data2); verifyWindowUpdateSent(STREAM_ID, data2);
verifyWindowUpdateNotSent(CONNECTION_STREAM_ID); verifyWindowUpdateNotSent(CONNECTION_STREAM_ID);
assertEquals(DEFAULT_WINDOW_SIZE, window(STREAM_ID)); assertEquals(DEFAULT_WINDOW_SIZE - data1, window(STREAM_ID));
assertEquals(DEFAULT_WINDOW_SIZE * 2 - data2 , window(CONNECTION_STREAM_ID)); assertEquals(DEFAULT_WINDOW_SIZE * 2 - data2 , window(CONNECTION_STREAM_ID));
reset(frameWriter); reset(frameWriter);
returnProcessedBytes(STREAM_ID, data1);
verifyWindowUpdateNotSent(STREAM_ID);
// Read enough data to cause a WINDOW_UPDATE for both the stream and connection and // Read enough data to cause a WINDOW_UPDATE for both the stream and connection and
// verify the new maximum of the connection window. // verify the new maximum of the connection window.