private async Task RunReaderAsync() { try { if (IsServer) { EnsureBuffer(ClientPreface.Length); await ClientPreface.ReadAsync(inputStream, config.ClientPrefaceTimeout); } var continueRead = true; if (serverUpgradeRequest != null) { var upgrade = serverUpgradeRequest; serverUpgradeRequest = null; var headers = new CompleteHeadersFrameData { StreamId = 1u, Priority = null, Headers = upgrade.Headers, EndOfStream = upgrade.Payload == null, }; var err = await HandleHeaders(headers); if (err != null) { if (err.Value.StreamId == 0) { continueRead = false; } await HandleFrameProcessingError(err.Value); } else if (upgrade.Payload != null) { var buf = config.BufferPool.Rent(upgrade.Payload.Length); Array.Copy( upgrade.Payload, 0, buf, 0, upgrade.Payload.Length); StreamImpl stream = null; lock (shared.Mutex) { shared.streamMap.TryGetValue(1u, out stream); } bool tookBufferOwnership; err = stream.PushBuffer( new ArraySegment <byte>(buf, 0, upgrade.Payload.Length), true, out tookBufferOwnership); if (!tookBufferOwnership) { config.BufferPool.Return(buf); } if (err != null) { if (err.Value.StreamId == 0) { continueRead = false; } await HandleFrameProcessingError(err.Value); } } } while (continueRead) { EnsureBuffer(PersistentBufferSize); var err = await ReadOneFrame(); ReleaseBuffer(PersistentBufferSize); if (err != null) { if (err.Value.StreamId == 0) { continueRead = false; } await HandleFrameProcessingError(err.Value); } } } catch (Exception e) { } await writer.CloseNow(); await writer.Done; Dictionary <uint, StreamImpl> activeStreams = null; lock (shared.Mutex) { activeStreams = shared.streamMap; shared.streamMap = null; shared.Closed = true; } foreach (var kvp in activeStreams) { await kvp.Value.Reset(ErrorCode.ConnectError, fromRemote : true); } PingState pingState = null; lock (shared.Mutex) { if (shared.PingState != null) { pingState = shared.PingState; shared.PingState = null; } } if (pingState != null) { var ex = new ConnectionClosedException(); foreach (var kvp in pingState.PingMap) { kvp.Value.SetException(ex); } } if (!remoteGoAwayTcs.Task.IsCompleted) { remoteGoAwayTcs.TrySetException(new EndOfStreamException()); } if (receiveBuffer != null) { config.BufferPool.Return(receiveBuffer); receiveBuffer = null; } headerReader.Dispose(); }
private async ValueTask <Http2Error?> HandleHeaders(CompleteHeadersFrameData headers) { if (headers.StreamId == 0) { return(new Http2Error { StreamId = headers.StreamId, Code = ErrorCode.ProtocolError, Message = "Received HEADERS frame with stream ID 0", }); } StreamImpl stream = null; uint lastOutgoingStream = 0u; uint lastIncomingStream = 0u; lock (shared.Mutex) { lastIncomingStream = shared.LastIncomingStreamId; lastOutgoingStream = shared.LastOutgoingStreamId; shared.streamMap.TryGetValue(headers.StreamId, out stream); } if (stream != null) { if (headers.Priority.HasValue) { var handlePrioErr = HandlePriorityData( headers.StreamId, headers.Priority.Value); if (handlePrioErr != null) { return(handlePrioErr); } } return(stream.ProcessHeaders(headers)); } var isServerInitiated = headers.StreamId % 2 == 0; var isRemoteInitiated = (IsServer && !isServerInitiated) || (!IsServer && isServerInitiated); var isValidNewStream = IsServer && isRemoteInitiated && (headers.StreamId > lastIncomingStream); if (!isValidNewStream) { return(new Http2Error { StreamId = headers.StreamId, Code = ErrorCode.StreamClosed, Message = "拒绝不打开新流的头", }); } lock (shared.Mutex) { shared.LastIncomingStreamId = headers.StreamId; if (shared.GoAwaySent) { return(new Http2Error { StreamId = headers.StreamId, Code = ErrorCode.RefusedStream, Message = "离开", }); } if ((uint)shared.streamMap.Count + 1 > localSettings.MaxConcurrentStreams) { return(new Http2Error { StreamId = headers.StreamId, Code = ErrorCode.RefusedStream, Message = "由于最大并发流而拒绝流", }); } } var newStream = new StreamImpl( this, headers.StreamId, StreamState.Idle, (int)localSettings.InitialWindowSize); lock (shared.Mutex) { shared.streamMap[headers.StreamId] = newStream; } if (!writer.RegisterStream(headers.StreamId)) { return(new Http2Error { StreamId = 0, Code = ErrorCode.InternalError, Message = "Can't register stream at writer", }); } var err = newStream.ProcessHeaders(headers); if (err != null) { return(err); } if (headers.Priority.HasValue) { err = HandlePriorityData( headers.StreamId, headers.Priority.Value); if (err != null) { return(err); } } var handledByUser = config.StreamListener(newStream); if (!handledByUser) { await newStream.Reset(ErrorCode.RefusedStream, false); } return(null); }
/// <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); }