public async Task ProcessRequestAsync <TContext>(IHttpApplication <TContext> application) { Exception error = null; try { while (_isClosed == 0) { var result = await Input.ReadAsync(); var readableBuffer = result.Buffer; var consumed = readableBuffer.Start; var examined = readableBuffer.End; try { if (!readableBuffer.IsEmpty) { while (Http3FrameReader.TryReadFrame(ref readableBuffer, _incomingFrame, 16 * 1024, out var framePayload)) { consumed = examined = framePayload.End; await ProcessHttp3Stream(application, framePayload); } } if (result.IsCompleted) { await OnEndStreamReceived(); return; } } finally { Input.AdvanceTo(consumed, examined); } } } catch (Http3StreamErrorException ex) { error = ex; Abort(new ConnectionAbortedException(ex.Message, ex), ex.ErrorCode); } catch (Exception ex) { error = ex; Log.LogWarning(0, ex, "Stream threw an unexpected exception."); } finally { var streamError = error as ConnectionAbortedException ?? new ConnectionAbortedException("The stream has completed.", error); await Input.CompleteAsync(); await RequestBodyPipe.Writer.CompleteAsync(); // Make sure application func is completed before completing writer. if (_appCompleted != null) { await _appCompleted.Task; } try { await _frameWriter.CompleteAsync(); } catch { Abort(streamError, Http3ErrorCode.ProtocolError); throw; } finally { _http3Connection.RemoveStream(_streamIdFeature.StreamId); } } }
public async Task ProcessRequestAsync <TContext>(IHttpApplication <TContext> application) where TContext : notnull { Exception?error = null; try { while (_isClosed == 0) { var result = await Input.ReadAsync(); var readableBuffer = result.Buffer; var consumed = readableBuffer.Start; var examined = readableBuffer.End; try { if (!readableBuffer.IsEmpty) { while (Http3FrameReader.TryReadFrame(ref readableBuffer, _incomingFrame, out var framePayload)) { Log.Http3FrameReceived(ConnectionId, _streamIdFeature.StreamId, _incomingFrame); consumed = examined = framePayload.End; await ProcessHttp3Stream(application, framePayload, result.IsCompleted&& readableBuffer.IsEmpty); } } if (result.IsCompleted) { await OnEndStreamReceived(); return; } } finally { Input.AdvanceTo(consumed, examined); } } } // catch ConnectionResetException here? catch (Http3StreamErrorException ex) { error = ex; Abort(new ConnectionAbortedException(ex.Message, ex), ex.ErrorCode); } catch (Http3ConnectionErrorException ex) { error = ex; _errorCodeFeature.Error = (long)ex.ErrorCode; _context.StreamLifetimeHandler.OnStreamConnectionError(ex); } catch (Exception ex) { error = ex; Log.LogWarning(0, ex, "Stream threw an unexpected exception."); } finally { var streamError = error as ConnectionAbortedException ?? new ConnectionAbortedException("The stream has completed.", error !); await Input.CompleteAsync(); // Make sure application func is completed before completing writer. if (_appCompleted != null) { await _appCompleted.Task; } try { await _frameWriter.CompleteAsync(); } catch { Abort(streamError, Http3ErrorCode.ProtocolError); throw; } finally { await _context.StreamContext.DisposeAsync(); _context.StreamLifetimeHandler.OnStreamCompleted(this); } } }
public async Task ProcessRequestAsync <TContext>(IHttpApplication <TContext> application) where TContext : notnull { Exception?error = null; try { while (_isClosed == 0) { var result = await Input.ReadAsync(); var readableBuffer = result.Buffer; var consumed = readableBuffer.Start; var examined = readableBuffer.End; try { if (!readableBuffer.IsEmpty) { while (Http3FrameReader.TryReadFrame(ref readableBuffer, _incomingFrame, out var framePayload)) { Log.Http3FrameReceived(ConnectionId, _streamIdFeature.StreamId, _incomingFrame); consumed = examined = framePayload.End; await ProcessHttp3Stream(application, framePayload, result.IsCompleted&& readableBuffer.IsEmpty); } } if (result.IsCompleted) { await OnEndStreamReceived(); return; } } finally { Input.AdvanceTo(consumed, examined); } } } catch (Http3StreamErrorException ex) { error = ex; Abort(new ConnectionAbortedException(ex.Message, ex), ex.ErrorCode); } catch (Http3ConnectionErrorException ex) { error = ex; _errorCodeFeature.Error = (long)ex.ErrorCode; _context.StreamLifetimeHandler.OnStreamConnectionError(ex); } catch (ConnectionResetException ex) { // TODO: This is temporary. Don't want to tie HTTP/3 layer to one transport. // This is here to check what other exceptions can cause ConnectionResetException. Debug.Assert(ex.InnerException is QuicStreamAbortedException); error = ex; Abort(new ConnectionAbortedException(ex.Message, ex), (Http3ErrorCode)_errorCodeFeature.Error); } catch (Exception ex) { error = ex; Log.LogWarning(0, ex, "Stream threw an unexpected exception."); } finally { var streamError = error as ConnectionAbortedException ?? new ConnectionAbortedException("The stream has completed.", error !); await Input.CompleteAsync(); // Make sure application func is completed before completing writer. if (_appCompleted != null) { await _appCompleted.Task; } try { await _frameWriter.CompleteAsync(); } catch { Abort(streamError, Http3ErrorCode.ProtocolError); throw; } finally { ApplyCompletionFlag(StreamCompletionFlags.Completed); // Tells the connection to remove the stream from its active collection. _context.StreamLifetimeHandler.OnStreamCompleted(this); // Dispose must happen after stream is no longer active. await _context.StreamContext.DisposeAsync(); } } }