Ejemplo n.º 1
0
        /// <summary>
        /// Writes the settings frame.
        /// </summary>
        /// <param name="settings">The settings.</param>
        public void WriteSettings(SettingsPair[] settings, bool isAck)
        {
            if (settings == null)
                throw new ArgumentNullException("settings array is null");

            var frame = new SettingsFrame(new List<SettingsPair>(settings), isAck);

            _writeQueue.WriteFrame(frame);


            if (!isAck && !_settingsAckReceived.WaitOne(60000))
            {
                WriteGoAway(ResetStatusCode.SettingsTimeout);
                Dispose();
            }
            
            _settingsAckReceived.Reset();

            if (OnSettingsSent != null)
            {
                OnSettingsSent(this, new SettingsSentEventArgs(frame));
            }
        }
Ejemplo n.º 2
0
 protected virtual void ProcessSettings(SettingsFrame frame)
 {
     _isPushEnabled = _session.IsPushEnabled;
 }
        private void HandleSettingsFrame(SettingsFrame settingsFrame)
        {
            _wasSettingsReceived = true;
            Http2Logger.LogDebug("Settings frame. Entry count: {0} StreamId: {1}", settingsFrame.EntryCount,
                                 settingsFrame.StreamId);

            for (int i = 0; i < settingsFrame.EntryCount; i++)
            {

                switch (settingsFrame[i].Id)
                {
                    case SettingsIds.MaxConcurrentStreams:
                        RemoteMaxConcurrentStreams = settingsFrame[i].Value;
                        break;
                    case SettingsIds.InitialWindowSize:
                        int newInitWindowSize = settingsFrame[i].Value;
                        int windowSizeDiff = newInitWindowSize - _flowControlManager.StreamsInitialWindowSize;

                        foreach (var stream in ActiveStreams.FlowControlledStreams.Values)
                        {
                            stream.WindowSize += windowSizeDiff;
                        }

                        _flowControlManager.StreamsInitialWindowSize = newInitWindowSize;
                        InitialWindowSize = newInitWindowSize;
                        break;
                    case SettingsIds.FlowControlOptions:
                        _flowControlManager.Options = settingsFrame[i].Value;
                        break;
                }
            }
        }
Ejemplo n.º 4
0
 public SettingsSentEventArgs(SettingsFrame frame)
 {
     SettingsFrame = frame;
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Writes the settings frame.
        /// </summary>
        /// <param name="settings">The settings.</param>
        public void WriteSettings(SettingsPair[] settings)
        {
            if (settings == null)
                throw new ArgumentNullException("settings array is null");

            var frame = new SettingsFrame(new List<SettingsPair>(settings));

            _writeQueue.WriteFrame(frame);

            if (OnSettingsSent != null)
            {
                OnSettingsSent(this, new SettingsSentEventArgs(frame));
            }
        }
        private void HandleSettingsFrame(SettingsFrame settingsFrame)
        {
            _wasSettingsReceived = true;
            Http2Logger.LogDebug("Settings frame. Entry count: {0} StreamId: {1}", settingsFrame.EntryCount,
                                 settingsFrame.StreamId);

            //Receipt of a SETTINGS frame with the ACK flag set and a length
            //field value other than 0 MUST be treated as a connection error
            //(Section 5.4.1) of type FRAME_SIZE_ERROR.
            if (settingsFrame.IsAck)
            {
                _settingsAckReceived.Set();

                if (settingsFrame.FrameLength != 0)
                    throw new ProtocolError(ResetStatusCode.FrameSizeError, "ack settings frame is not 0");

                return;
            }

            for (int i = 0; i < settingsFrame.EntryCount; i++)
            {

                switch (settingsFrame[i].Id)
                {
                    case SettingsIds.SettingsHeadersTableSize:
                        if (_comprProc is CompressionProcessor)
                            (_comprProc as CompressionProcessor).NotifySettingsChanges(settingsFrame[i].Value);
                        break;
                    case SettingsIds.SettingsEnableServerPush:
                        IsPushEnabled = settingsFrame[i].Value != 0;
                        break;
                    case SettingsIds.MaxConcurrentStreams:
                        RemoteMaxConcurrentStreams = settingsFrame[i].Value;
                        break;
                    case SettingsIds.InitialWindowSize:
                        int newInitWindowSize = settingsFrame[i].Value;
                        int windowSizeDiff = newInitWindowSize - _flowControlManager.StreamsInitialWindowSize;

                        foreach (var stream in ActiveStreams.FlowControlledStreams.Values)
                        {
                            stream.WindowSize += windowSizeDiff;
                        }

                        _flowControlManager.StreamsInitialWindowSize = newInitWindowSize;
                        InitialWindowSize = newInitWindowSize;
                        break;
                    case SettingsIds.FlowControlOptions:
                        _flowControlManager.Options = settingsFrame[i].Value;
                        break;
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Writes the SETTINGS frame.
        /// </summary>
        /// <param name="settings">The settings pairs.</param>
        /// <param name="isAck">The ACK flag.</param>
        public void WriteSettings(SettingsPair[] settings, bool isAck)
        {
            if (settings == null)
                throw new ArgumentNullException("settings");

            var frame = new SettingsFrame(new List<SettingsPair>(settings), isAck);

            Http2Logger.LogDebug("Sending SETTINGS frame: stream id={0}, payload len={1}, is ack={2}, count={3}",
                frame.StreamId, frame.PayloadLength, frame.IsAck, frame.EntryCount);

            foreach(var s in settings)
            {
                Http2Logger.LogDebug("{0}: {1}", s.Id.ToString(), s.Value);
            }

            _writeQueue.WriteFrame(frame);

            if (!isAck && !_settingsAckReceived.WaitOne(60000))
            {
                WriteGoAway(ResetStatusCode.SettingsTimeout);
                Dispose();
            }
            
            _settingsAckReceived.Reset();

            if (OnSettingsSent != null)
            {
                OnSettingsSent(this, new SettingsSentEventArgs(frame));
            }
        }
        private void HandleSettingsFrame(SettingsFrame settingsFrame)
        {
            Http2Logger.LogDebug("SETTINGS frame: stream id={0}, payload len={1}, is ack={2}, count={3}",
                settingsFrame.StreamId, settingsFrame.PayloadLength, settingsFrame.IsAck, settingsFrame.EntryCount);

            _wasSettingsReceived = true;
            
            /* 12 -> 6.5
            If an endpoint receives a SETTINGS frame whose stream identifier 
            field is other than 0x0, the endpoint MUST respond with a connection
            error of type PROTOCOL_ERROR. */
            if (settingsFrame.StreamId != 0)
                throw new ProtocolError(ResetStatusCode.ProtocolError, "Settings frame stream id is not 0");

            /* 12 -> 6.5
            Receipt of a SETTINGS frame with the ACK flag set and a length
            field value other than 0 MUST be treated as a connection error
            of type FRAME_SIZE_ERROR. */
            if (settingsFrame.IsAck)
            {
                _settingsAckReceived.Set();

                if (settingsFrame.PayloadLength != 0)
                    throw new ProtocolError(ResetStatusCode.FrameSizeError, 
                        "Settings frame with ACK flag set and non-zero payload");               
                return;
            }

            for (int i = 0; i < settingsFrame.EntryCount; i++)
            {
                var setting = settingsFrame[i];
                Http2Logger.LogDebug("{0}: {1}", setting.Id.ToString(), setting.Value);

                switch (setting.Id)
                {
                    case SettingsIds.HeadersTableSize:
                        if (_comprProc is CompressionProcessor)
                            (_comprProc as CompressionProcessor).NotifySettingsChanges(setting.Value);
                        break;
                    case SettingsIds.EnablePush:
                        IsPushEnabled = setting.Value != 0;
                        break;
                    case SettingsIds.MaxConcurrentStreams:
                        RemoteMaxConcurrentStreams = setting.Value;
                        /* 12 -> 8.2.2
                        Advertising a SETTINGS_MAX_CONCURRENT_STREAMS value of zero disables
                        server push by preventing the server from creating the necessary streams. */
                        IsPushEnabled = setting.Value == 0;
                        break;
                    case SettingsIds.InitialWindowSize:
                        int newInitWindowSize = setting.Value;
                        int windowSizeDiff = newInitWindowSize - _flowControlManager.StreamsInitialWindowSize;

                        foreach (var stream in StreamDictionary.FlowControlledStreams.Values)
                        {
                            stream.WindowSize += windowSizeDiff;
                        }

                        _flowControlManager.StreamsInitialWindowSize = newInitWindowSize;
                        InitialWindowSize = newInitWindowSize;
                        break;
                    // TODO:
                    // _GzipCompressionProcessor.Enabled = true;
                    // ignore CompressData setting for now
                    case SettingsIds.CompressData:
                        break;      

                    /* 12 -> 5.2.1 
                    Flow control cannot be disabled. */
                    /*case SettingsIds.FlowControlOptions:
                        _flowControlManager.Options = settingsFrame[i].Value;
                        break;*/
                    default:
                        /* 12 -> 6.5.2 
                        An endpoint that receives a SETTINGS frame with any other identifier
                        MUST treat this as a connection error of type PROTOCOL_ERROR. */
                        throw new ProtocolError(ResetStatusCode.ProtocolError, "Unknown setting identifier");
                }
            }
        }