/// <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)); } }
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; } } }
public SettingsSentEventArgs(SettingsFrame frame) { SettingsFrame = frame; }
/// <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; } } }
/// <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"); } } }