public void WriteWindowUpdate(Int32 windowSize) { if (windowSize <= 0) throw new ArgumentOutOfRangeException("windowSize should be greater than 0"); if (windowSize > Constants.MaxWindowSize) throw new ProtocolError(ResetStatusCode.FlowControlError, "window size is too large"); //09 -> 6.9.4. Ending Flow Control //After a receiver reads in a frame that marks the end of a stream (for //example, a data stream with a END_STREAM flag set), it MUST cease //transmission of WINDOW_UPDATE frames for that stream. if (Closed) return; //TODO handle idle state var frame = new WindowUpdateFrame(_id, windowSize); _writeQueue.WriteFrame(frame); Http2Logger.LogDebug("Sending WINDOW_UPDATE: stream id={0}, delta={1}", frame.StreamId, frame.Delta); if (OnFrameSent != null) { OnFrameSent(this, new FrameSentEventArgs(frame)); } }
private void HandleWindowUpdateFrame(WindowUpdateFrame windowUpdateFrame, out Http2Stream stream) { if (_useFlowControl) { Http2Logger.LogDebug("WindowUpdate frame. Delta: {0} StreamId: {1}", windowUpdateFrame.Delta, windowUpdateFrame.StreamId); stream = GetStream(windowUpdateFrame.StreamId); //06 //The legal range for the increment to the flow control window is 1 to //2^31 - 1 (0x7fffffff) bytes. if (!(0 < windowUpdateFrame.Delta && windowUpdateFrame.Delta <= Constants.MaxPriority)) { Http2Logger.LogDebug("Incorrect window update delta : {0}", windowUpdateFrame.Delta); throw new ProtocolError(ResetStatusCode.FlowControlError, String.Format("Incorrect window update delta : {0}", windowUpdateFrame.Delta)); } //06 //A receiver can ignore WINDOW_UPDATE [WINDOW_UPDATE] or PRIORITY //[PRIORITY] frames in this state. if (stream != null) { stream.UpdateWindowSize(windowUpdateFrame.Delta); stream.PumpUnshippedFrames(); } //Do not signal an error because (06) //WINDOW_UPDATE [WINDOW_UPDATE], PRIORITY [PRIORITY], or RST_STREAM //[RST_STREAM] frames can be received in this state for a short //period after a frame containing an END_STREAM flag is sent. } else { stream = null; } }
private void HandleWindowUpdateFrame(WindowUpdateFrame windowUpdateFrame, out Http2Stream stream) { Http2Logger.LogDebug("WINDOW_UPDATE frame: stream id={0}, delta={1}",windowUpdateFrame.StreamId, windowUpdateFrame.Delta); if (!_useFlowControl) { stream = null; return; } // TODO Remove this hack /* The WINDOW_UPDATE frame can be specific to a stream or to the entire connection. In the former case, the frame's stream identifier indicates the affected stream; in the latter, the value "0" indicates that the _entire connection_ is the subject of the frame. */ if (windowUpdateFrame.StreamId == 0) { _flowControlManager.StreamsInitialWindowSize += windowUpdateFrame.Delta; stream = null; return; } stream = GetStream(windowUpdateFrame.StreamId); /* 12 -> 6.9 WINDOW_UPDATE can be sent by a peer that has sent a frame bearing the END_STREAM flag. This means that a receiver could receive a WINDOW_UPDATE frame on a "half closed (remote)" or "closed" stream. A receiver MUST NOT treat this as an error. */ if (!(stream.Opened || stream.HalfClosedRemote || stream.HalfClosedLocal || stream.Closed)) throw new ProtocolError(ResetStatusCode.ProtocolError, "window update in incorrect state"); //09 -> 6.9. WINDOW_UPDATE //The payload of a WINDOW_UPDATE frame is one reserved bit, plus an //unsigned 31-bit integer indicating the number of bytes that the //sender can transmit in addition to the existing flow control window. //The legal range for the increment to the flow control window is 1 to //2^31 - 1 (0x7fffffff) bytes. if (!(0 < windowUpdateFrame.Delta && windowUpdateFrame.Delta <= Constants.MaxPriority)) { Http2Logger.LogDebug("Incorrect window update delta : {0}", windowUpdateFrame.Delta); throw new ProtocolError(ResetStatusCode.FlowControlError, String.Format("Incorrect window update delta : {0}", windowUpdateFrame.Delta)); } stream.UpdateWindowSize(windowUpdateFrame.Delta); stream.PumpUnshippedFrames(); }
private void HandleWindowUpdateFrame(WindowUpdateFrame windowUpdateFrame, out Http2Stream stream) { if (_useFlowControl) { Http2Logger.LogDebug("WindowUpdate frame. Delta: {0} StreamId: {1}", windowUpdateFrame.Delta, windowUpdateFrame.StreamId); stream = GetStream(windowUpdateFrame.StreamId); //09 -> 6.9. WINDOW_UPDATE //The payload of a WINDOW_UPDATE frame is one reserved bit, plus an //unsigned 31-bit integer indicating the number of bytes that the //sender can transmit in addition to the existing flow control window. //The legal range for the increment to the flow control window is 1 to //2^31 - 1 (0x7fffffff) bytes. if (!(0 < windowUpdateFrame.Delta && windowUpdateFrame.Delta <= Constants.MaxPriority)) { Http2Logger.LogDebug("Incorrect window update delta : {0}", windowUpdateFrame.Delta); throw new ProtocolError(ResetStatusCode.FlowControlError, String.Format("Incorrect window update delta : {0}", windowUpdateFrame.Delta)); } //TODO Remove this hack //Connection window size if (windowUpdateFrame.StreamId == 0) { _flowControlManager.StreamsInitialWindowSize += windowUpdateFrame.Delta; } //09 -> 5.1. Stream States //A receiver can ignore WINDOW_UPDATE [WINDOW_UPDATE] or PRIORITY //[PRIORITY] frames in this state. if (stream != null) { stream.UpdateWindowSize(windowUpdateFrame.Delta); stream.PumpUnshippedFrames(); } //09 -> 5.1. Stream States //WINDOW_UPDATE, PRIORITY, or RST_STREAM frames can be received in //this state for a short period after a DATA or HEADERS frame //containing an END_STREAM flag is sent. Until the remote peer //receives and processes the frame bearing the END_STREAM flag, it //might send frame of any of these types. Endpoints MUST ignore //WINDOW_UPDATE, PRIORITY, or RST_STREAM frames received in this //state, though endpoints MAY choose to treat frames that arrive a //significant time after sending END_STREAM as a connection error //(Section 5.4.1) of type PROTOCOL_ERROR. } else { stream = null; } }
public void WriteWindowUpdate(Int32 windowSize) { if (windowSize <= 0) throw new ArgumentOutOfRangeException("windowSize should be greater thasn 0"); if (windowSize > Constants.MaxWindowSize) throw new ProtocolError(ResetStatusCode.FlowControlError, "window size is too large"); //Spec 06 //After a receiver reads in a frame that marks the end of a stream (for //example, a data stream with a END_STREAM flag set), it MUST cease //transmission of WINDOW_UPDATE frames for that stream. if (Disposed || EndStreamReceived) return; var frame = new WindowUpdateFrame(_id, windowSize); _writeQueue.WriteFrame(frame); if (OnFrameSent != null) { OnFrameSent(this, new FrameSentArgs(frame)); } }