/// <summary>
/// Process Protocol control frame.
/// </summary>
/// <param name="frame">The control frame.</param>
private void ProcessControlFrame(ControlFrame frame)
{
if (frame.Version != Version)
{
throw new ProtocolExeption(StatusCode.UnsupportedVersion);
}
if (frame.Type == FrameType.GoAway)
{
GoAwayFrame goAway = (GoAwayFrame)frame;
CloseInternal(goAway.Status, goAway.LastSeenGoodStreamId, false);
}
else
{
Http2Stream stream = this.streamsStore.GetStreamById(frame.StreamId);
// if this is rst frame - don't send error or it will go in rst loop
if (stream == null && frame.Type != FrameType.RTS && frame.Type != FrameType.Settings && frame.Type != FrameType.SynStream)
{
this.SendRST(frame.StreamId, StatusCode.InvalidStream);
return;
}
switch (frame.Type)
{
case FrameType.SynStream:
//TODO validate syn_stream and send syn_reply or rst
this.OnSessionFrame(this, new ControlFrameEventArgs(frame));
break;
case FrameType.SynReply:
this.OnSessionFrame(this, new ControlFrameEventArgs(frame));
break;
case FrameType.Headers:
this.OnStreamFrame(this, new HeadersEventArgs(this.streamsStore.GetStreamById(frame.StreamId), frame.Headers));
break;
case FrameType.RTS:
this.OnStreamFrame(this, new RSTEventArgs(this.streamsStore.GetStreamById(frame.StreamId), frame.StatusCode));
break;
case FrameType.Ping:
this.OnSocketPing(this, new PingEventArgs(frame.StreamId));
break;
case FrameType.Settings:
OnSessionFrame(this, new SettingsEventArgs(frame));
break;
case FrameType.WindowUpdate:
Http2Stream http2Stream = this.streamsStore.GetStreamById(frame.StreamId);
http2Stream.UpdateWindowBalance(frame.DeltaWindowSize);
break;
}
}
}