protected override Task OnConsumeAsync() { try { while (TryReadInternal(out var readResult)) { AdvanceTo(readResult.Buffer.End); if (readResult.IsCompleted) { return(Task.CompletedTask); } } } catch (BadHttpRequestException ex) { // At this point, the response has already been written, so this won't result in a 4XX response; // however, we still need to stop the request processing loop and log. _context.SetBadRequestState(ex); return(Task.CompletedTask); } catch (InvalidOperationException ex) { var connectionAbortedException = new ConnectionAbortedException(CoreStrings.ConnectionAbortedByApplication, ex); _context.ReportApplicationError(connectionAbortedException); // Have to abort the connection because we can't finish draining the request _context.StopProcessingNextRequest(); return(Task.CompletedTask); } return(OnConsumeAsyncAwaited()); }
public Task StopProcessingNextRequestAsync() { Debug.Assert(_http1Connection != null, $"{nameof(_http1Connection)} is null"); Debug.Assert(_http2Connection != null, $"{nameof(_http2Connection)} is null"); if (Interlocked.Exchange(ref _http2ConnectionState, Http2ConnectionClosed) == Http2ConnectionStarted) { _http2Connection.Stop(); } else { _http1Connection.StopProcessingNextRequest(); } return(_lifetimeTask); }
private void CheckForTimeout(long timestamp) { // TODO: Use PlatformApis.VolatileRead equivalent again if (timestamp > Interlocked.Read(ref _timeoutTimestamp)) { if (!Debugger.IsAttached) { CancelTimeout(); switch (_timeoutAction) { case TimeoutAction.StopProcessingNextRequest: // Http/2 keep-alive timeouts are not yet supported. _http1Connection?.StopProcessingNextRequest(); break; case TimeoutAction.SendTimeoutResponse: // HTTP/2 timeout responses are not yet supported. if (_http1Connection != null) { RequestTimedOut = true; _http1Connection.SendTimeoutResponse(); } break; case TimeoutAction.AbortConnection: // This is actually supported with HTTP/2! Abort(new TimeoutException()); break; } } } }
public void OnTimeout(TimeoutReason reason) { // In the cases that don't log directly here, we expect the setter of the timeout to also be the input // reader, so when the read is canceled or aborted, the reader should write the appropriate log. switch (reason) { case TimeoutReason.KeepAlive: _http1Connection.StopProcessingNextRequest(); break; case TimeoutReason.RequestHeaders: _http1Connection.SendTimeoutResponse(); break; case TimeoutReason.ReadDataRate: Log.RequestBodyMinimumDataRateNotSatisfied(_context.ConnectionId, _http1Connection.TraceIdentifier, _http1Connection.MinRequestBodyDataRate.BytesPerSecond); _http1Connection.SendTimeoutResponse(); break; case TimeoutReason.WriteDataRate: Log.ResponseMinimumDataRateNotSatisfied(_http1Connection.ConnectionIdFeature, _http1Connection.TraceIdentifier); Abort(new ConnectionAbortedException(CoreStrings.ConnectionTimedBecauseResponseMininumDataRateNotSatisfied)); break; case TimeoutReason.RequestBodyDrain: case TimeoutReason.TimeoutFeature: Abort(new ConnectionAbortedException(CoreStrings.ConnectionTimedOutByServer)); break; default: Debug.Assert(false, "Invalid TimeoutReason"); break; } }