Example #1
0
        private void OnRemoteSettingChanged(HTTP2SettingsRegistry registry, HTTP2Settings setting, uint oldValue, uint newValue)
        {
            switch (setting)
            {
            case HTTP2Settings.INITIAL_WINDOW_SIZE:
                // https://httpwg.org/specs/rfc7540.html#InitialWindowSize
                // "Prior to receiving a SETTINGS frame that sets a value for SETTINGS_INITIAL_WINDOW_SIZE,
                // an endpoint can only use the default initial window size when sending flow-controlled frames."
                // "In addition to changing the flow-control window for streams that are not yet active,
                // a SETTINGS frame can alter the initial flow-control window size for streams with active flow-control windows
                // (that is, streams in the "open" or "half-closed (remote)" state). When the value of SETTINGS_INITIAL_WINDOW_SIZE changes,
                // a receiver MUST adjust the size of all stream flow-control windows that it maintains by the difference between the new value and the old value."

                // So, if we created a stream before the remote peer's initial settings frame is received, we
                // will adjust the window size. For example: initial window size by default is 65535, if we later
                // receive a change to 1048576 (1 MB) we will increase the current remoteWindow by (1 048 576 - 65 535 =) 983 041

                // But because initial window size in a setting frame can be smaller then the default 65535 bytes,
                // the difference can be negative:
                // "A change to SETTINGS_INITIAL_WINDOW_SIZE can cause the available space in a flow-control window to become negative.
                // A sender MUST track the negative flow-control window and MUST NOT send new flow-controlled frames
                // until it receives WINDOW_UPDATE frames that cause the flow-control window to become positive.

                // For example, if the client sends 60 KB immediately on connection establishment
                // and the server sets the initial window size to be 16 KB, the client will recalculate
                // the available flow - control window to be - 44 KB on receipt of the SETTINGS frame.
                // The client retains a negative flow-control window until WINDOW_UPDATE frames restore the
                // window to being positive, after which the client can resume sending."

                this.remoteWindow += newValue - oldValue;

                HTTPManager.Logger.Information("HTTP2Stream", string.Format("[{0}] Remote Setting's Initial Window Updated from {1:N0} to {2:N0}, diff: {3:N0}, new remoteWindow: {4:N0}, total data sent: {5:N0}", this.Id, oldValue, newValue, newValue - oldValue, this.remoteWindow, this.sentData));
                break;
            }
        }
        public UInt32 this[HTTP2Settings setting]
        {
            get { return(this.values[(ushort)setting]); }

            set
            {
                if (this.IsReadOnly)
                {
                    throw new NotSupportedException("It's a read-only one!");
                }

                ushort idx = (ushort)setting;

                // https://httpwg.org/specs/rfc7540.html#SettingValues
                // An endpoint that receives a SETTINGS frame with any unknown or unsupported identifier MUST ignore that setting.
                if (idx == 0 || idx >= this.values.Length)
                {
                    return;
                }

                UInt32 oldValue = this.values[idx];
                if (oldValue != value)
                {
                    this.values[idx]      = value;
                    this.changeFlags[idx] = true;
                    IsChanged             = true;

                    if (this.OnSettingChangedEvent != null)
                    {
                        this.OnSettingChangedEvent(this, setting, oldValue, value);
                    }
                }
            }
        }
        public void Merge(List <KeyValuePair <HTTP2Settings, UInt32> > settings)
        {
            if (settings == null)
            {
                return;
            }

            for (int i = 0; i < settings.Count; ++i)
            {
                HTTP2Settings setting = settings[i].Key;
                UInt16        key     = (UInt16)setting;
                UInt32        value   = settings[i].Value;

                if (key > 0 && key <= HTTP2SettingsManager.SettingsCount)
                {
                    UInt32 oldValue = this.values[key];
                    this.values[key] = value;

                    if (oldValue != value && this.OnSettingChangedEvent != null)
                    {
                        this.OnSettingChangedEvent(this, setting, oldValue, value);
                    }

                    if (HTTPManager.Logger.Level <= Logger.Loglevels.All)
                    {
                        HTTPManager.Logger.Information("HTTP2SettingsRegistry", string.Format("Merge {0}({1}) = {2}", setting, key, value), this._parent.Parent.Context);
                    }
                }
            }
        }
Example #4
0
        public void Merge(List <KeyValuePair <HTTP2Settings, UInt32> > settings)
        {
            if (settings == null)
            {
                return;
            }

            for (int i = 0; i < settings.Count; ++i)
            {
                HTTP2Settings setting = settings[i].Key;
                UInt16        key     = (UInt16)setting;
                UInt32        value   = settings[i].Value;

                if (key > 0 && key <= HTTP2SettingsManager.SettingsCount)
                {
                    UInt32 oldValue = this.values[key];
                    this.values[key] = value;

                    if (oldValue != value && this.OnSettingChangedEvent != null)
                    {
                        this.OnSettingChangedEvent(this, setting, oldValue, value);
                    }
                }
            }
        }
Example #5
0
 private void OnRemoteSettingChanged(HTTP2SettingsRegistry registry, HTTP2Settings setting, uint oldValue, uint newValue)
 {
     switch (setting)
     {
     case HTTP2Settings.INITIAL_WINDOW_SIZE:
         this.remoteWindow = newValue - (oldValue - this.remoteWindow);
         break;
     }
 }
        public static HTTP2SettingsFrame ReadSettings(HTTP2FrameHeaderAndPayload header)
        {
            HTTP2SettingsFrame frame = new HTTP2SettingsFrame(header);

            if (header.PayloadLength > 0)
            {
                int kvpCount = (int)(header.PayloadLength / 6);

                frame.Settings = new List <KeyValuePair <HTTP2Settings, uint> >(kvpCount);
                for (int i = 0; i < kvpCount; ++i)
                {
                    HTTP2Settings key   = (HTTP2Settings)BufferHelper.ReadUInt16(header.Payload, i * 6);
                    UInt32        value = BufferHelper.ReadUInt32(header.Payload, (i * 6) + 2);

                    frame.Settings.Add(new KeyValuePair <HTTP2Settings, uint>(key, value));
                }
            }

            return(frame);
        }