public async Task WriteTrailersAsync(IEnumerable <HeaderField> headers) { HeaderValidationResult hvr = HeaderValidator.ValidateTrailingHeaders(headers); if (hvr != HeaderValidationResult.Ok) { throw new Exception(hvr.ToString()); } var removeStream = false; await writeMutex.WaitAsync(); try { lock (stateMutex) { if (!dataSent) { throw new Exception("试图在没有数据的情况下写入"); } switch (state) { case StreamState.Open: state = StreamState.HalfClosedLocal; break; case StreamState.HalfClosedRemote: state = StreamState.HalfClosedRemote; state = StreamState.Closed; removeStream = true; break; case StreamState.Idle: case StreamState.ReservedRemote: case StreamState.HalfClosedLocal: case StreamState.Closed: throw new Exception("发送的状态无效"); case StreamState.Reset: throw new StreamResetException(); case StreamState.ReservedLocal: throw new Exception("意外状态:发送数据后保留本地"); } } await SendHeaders(headers, true); // TODO: Use result } finally { writeMutex.Release(); if (removeStream) { connection.UnregisterStream(this); } } }
/// <summary> /// 处理传入头的接收 /// </summary> public Http2Error?ProcessHeaders( CompleteHeadersFrameData headers) { var wakeupDataWaiter = false; var wakeupHeaderWaiter = false; var wakeupTrailerWaiter = false; var removeStream = false; lock (stateMutex) { switch (state) { case StreamState.ReservedLocal: case StreamState.ReservedRemote: return(new Http2Error { StreamId = Id, Code = ErrorCode.InternalError, Message = "接收到的头帧处于未覆盖的推送约定状态", }); case StreamState.Idle: case StreamState.Open: case StreamState.HalfClosedLocal: if (headersReceived != HeaderReceptionState.ReceivedAllHeaders) { HeaderValidationResult hvr; if (connection.IsServer) { hvr = HeaderValidator.ValidateRequestHeaders(headers.Headers); } else { hvr = HeaderValidator.ValidateResponseHeaders(headers.Headers); } if (hvr != HeaderValidationResult.Ok) { return(new Http2Error { StreamId = Id, Code = ErrorCode.ProtocolError, Message = "Received invalid headers", }); } if (!connection.config.IsServer && headers.Headers.IsInformationalHeaders()) { headersReceived = HeaderReceptionState.ReceivedInformationalHeaders; } else { headersReceived = HeaderReceptionState.ReceivedAllHeaders; } wakeupHeaderWaiter = true; declaredInContentLength = headers.Headers.GetContentLength(); inHeaders = headers.Headers; } else if (!dataReceived) { return(new Http2Error { StreamId = Id, Code = ErrorCode.ProtocolError, Message = "接收的无标题", }); } else { if (!headers.EndOfStream) { return(new Http2Error { StreamId = Id, Code = ErrorCode.ProtocolError, Message = "接收到没有endofstream标志", }); } var hvr = HeaderValidator.ValidateTrailingHeaders(headers.Headers); if (hvr != HeaderValidationResult.Ok) { return(new Http2Error { StreamId = Id, Code = ErrorCode.ProtocolError, Message = "接收到无效", }); } if (declaredInContentLength >= 0 && declaredInContentLength != totalInData) { return(new Http2Error { StreamId = Id, Code = ErrorCode.ProtocolError, Message = "数据帧的长度与内容长度不匹配", }); } wakeupTrailerWaiter = true; inTrailers = headers.Headers; } if (state == StreamState.Idle) { state = StreamState.Open; } if (headers.EndOfStream) { if (state == StreamState.HalfClosedLocal) { state = StreamState.Closed; removeStream = true; } else { state = StreamState.HalfClosedRemote; } wakeupTrailerWaiter = true; wakeupDataWaiter = true; } break; case StreamState.HalfClosedRemote: case StreamState.Closed: return(new Http2Error { Code = ErrorCode.StreamClosed, StreamId = Id, Message = "已接收封闭流的头", }); case StreamState.Reset: break; default: throw new Exception("未处理的流状态"); } } if (wakeupHeaderWaiter) { readHeadersPossible.Set(); } if (wakeupDataWaiter) { readDataPossible.Set(); } if (wakeupTrailerWaiter) { readTrailersPossible.Set(); } if (removeStream) { connection.UnregisterStream(this); } return(null); }