in src/main/java/com/twitter/http2/HttpConnectionHandler.java [163:214]
public void readDataFramePadding(int streamId, boolean endStream, int padding) {
int deltaWindowSize = -1 * padding;
int newConnectionWindowSize = httpConnection.updateReceiveWindowSize(
HTTP_CONNECTION_STREAM_ID, deltaWindowSize);
// Check if connection window size is reduced beyond allowable lower bound
if (newConnectionWindowSize < 0) {
issueConnectionError(HttpErrorCode.PROTOCOL_ERROR);
return;
}
// Send a WINDOW_UPDATE frame if less than half the connection window size remains
if (newConnectionWindowSize <= initialConnectionReceiveWindowSize / 2) {
int windowSizeIncrement = initialConnectionReceiveWindowSize - newConnectionWindowSize;
httpConnection.updateReceiveWindowSize(HTTP_CONNECTION_STREAM_ID, windowSizeIncrement);
ByteBuf frame = httpFrameEncoder.encodeWindowUpdateFrame(
HTTP_CONNECTION_STREAM_ID, windowSizeIncrement);
context.writeAndFlush(frame);
}
// Check if we received a DATA frame for a stream which is half-closed (remote) or closed
if (httpConnection.isRemoteSideClosed(streamId)) {
if (streamId <= lastStreamId) {
issueStreamError(streamId, HttpErrorCode.STREAM_CLOSED);
} else if (!sentGoAwayFrame) {
issueStreamError(streamId, HttpErrorCode.PROTOCOL_ERROR);
}
return;
}
// Update receive window size
int newWindowSize = httpConnection.updateReceiveWindowSize(streamId, deltaWindowSize);
// Window size can become negative if we sent a SETTINGS frame that reduces the
// size of the transfer window after the peer has written data frames.
// The value is bounded by the length that SETTINGS frame decrease the window.
// This difference is stored for the connection when writing the SETTINGS frame
// and is cleared once we send a WINDOW_UPDATE frame.
if (newWindowSize < httpConnection.getReceiveWindowSizeLowerBound(streamId)) {
issueStreamError(streamId, HttpErrorCode.FLOW_CONTROL_ERROR);
return;
}
// Send a WINDOW_UPDATE frame if less than half the stream window size remains
// Recipient should not send a WINDOW_UPDATE frame as it consumes the last data frame.
if (handleStreamWindowUpdates && newWindowSize <= initialReceiveWindowSize / 2 && !endStream) {
int windowSizeIncrement = initialReceiveWindowSize - newWindowSize;
httpConnection.updateReceiveWindowSize(streamId, windowSizeIncrement);
ByteBuf frame = httpFrameEncoder.encodeWindowUpdateFrame(streamId, windowSizeIncrement);
context.writeAndFlush(frame);
}
}