示例#1
0
        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;
            }
        }
示例#5
0
        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));
            }
        }