public void Abort(ConnectionAbortedException ex, Http3ErrorCode errorCode)
 {
     _errorCodeFeature.Error = (long)errorCode;
     // TODO replace with IKestrelTrace log.
     Log.LogWarning(ex, ex.Message);
     _frameWriter.Abort(ex);
 }
Esempio n. 2
0
 public void Http3StreamAbort(string traceIdentifier, Http3ErrorCode error, ConnectionAbortedException abortReason)
 {
     if (_http3Logger.IsEnabled(LogLevel.Debug))
     {
         Http3StreamAbort(_http3Logger, traceIdentifier, Http3Formatting.ToFormattedErrorCode(error), abortReason);
     }
 }
Esempio n. 3
0
        public void Abort(ConnectionAbortedException abortReason, Http3ErrorCode errorCode)
        {
            lock (_completionLock)
            {
                if (IsCompleted)
                {
                    return;
                }

                var(oldState, newState) = ApplyCompletionFlag(StreamCompletionFlags.Aborted);

                if (oldState == newState)
                {
                    return;
                }

                Log.Http3StreamAbort(TraceIdentifier, errorCode, abortReason);

                _errorCodeFeature.Error = (long)errorCode;
                _frameWriter.Abort(abortReason);

                // Call _http3Output.Stop() prior to poisoning the request body stream or pipe to
                // ensure that an app that completes early due to the abort doesn't result in header frames being sent.
                _http3Output.Stop();

                CancelRequestAbortedToken();

                // Unblock the request body.
                PoisonBody(abortReason);
                RequestBodyPipe.Writer.Complete(abortReason);
            }
        }
Esempio n. 4
0
        internal void AssertConnectionError <TException>(Http3ErrorCode expectedErrorCode, params string[] expectedErrorMessage) where TException : Exception
        {
            Assert.Equal((Http3ErrorCode)expectedErrorCode, (Http3ErrorCode)MultiplexedConnectionContext.Error);

            if (expectedErrorMessage?.Length > 0)
            {
                var message = Assert.Single(LogMessages, m => m.Exception is TException);

                Assert.Contains(expectedErrorMessage, expected => message.Exception.Message.Contains(expected));
            }
        }
Esempio n. 5
0
        internal void AssertConnectionError <TException>(Http3ErrorCode expectedErrorCode, Action <Type, string[]> matchExpectedErrorMessage = null, params string[] expectedErrorMessage) where TException : Exception
        {
            var currentError = (Http3ErrorCode)MultiplexedConnectionContext.Error;

            if (currentError != expectedErrorCode)
            {
                throw new InvalidOperationException($"Expected error code {expectedErrorCode}, got {currentError}.");
            }

            matchExpectedErrorMessage?.Invoke(typeof(TException), expectedErrorMessage);
        }
Esempio n. 6
0
    public void Abort(ConnectionAbortedException abortReason, Http3ErrorCode errorCode)
    {
        // TODO - Should there be a check here to track abort state to avoid
        // running twice for a request?

        Log.Http3StreamAbort(_context.ConnectionId, errorCode, abortReason);

        _errorCodeFeature.Error = (long)errorCode;
        _frameWriter.Abort(abortReason);

        Input.Complete(abortReason);
    }
Esempio n. 7
0
        /// <summary>
        /// Aborts the connection with an error.
        /// </summary>
        /// <remarks>
        /// Used for e.g. I/O or connection-level frame parsing errors.
        /// </remarks>
        internal Exception Abort(Exception abortException)
        {
            // Only observe the first exception we get.
            Exception?firstException = Interlocked.CompareExchange(ref _abortException, abortException, null);

            if (firstException != null)
            {
                if (NetEventSource.Log.IsEnabled() && !ReferenceEquals(firstException, abortException))
                {
                    // Lost the race to set the field to another exception, so just trace this one.
                    Trace($"{nameof(abortException)}=={abortException}");
                }

                return(firstException);
            }

            // Stop sending requests to this connection.
            _pool.InvalidateHttp3Connection(this);

            Http3ErrorCode connectionResetErrorCode = (abortException as Http3ProtocolException)?.ErrorCode ?? Http3ErrorCode.InternalError;

            lock (SyncObj)
            {
                // Set _lastProcessedStreamId != -1 to make ShuttingDown = true.
                // It's possible GOAWAY is already being processed, in which case this would already be != -1.
                if (_lastProcessedStreamId == -1)
                {
                    _lastProcessedStreamId = long.MaxValue;
                }

                // Abort the connection. This will cause all of our streams to abort on their next I/O.
                if (_connection != null && _connectionClosedTask == null)
                {
                    _connectionClosedTask = _connection.CloseAsync((long)connectionResetErrorCode).AsTask();
                }

                CancelWaiters();
                CheckForShutdown();
            }

            return(abortException);
        }
Esempio n. 8
0
        public void Abort(ConnectionAbortedException abortReason, Http3ErrorCode errorCode)
        {
            // TODO - Should there be a check here to track abort state to avoid
            // running twice for a request?

            Log.Http3StreamAbort(TraceIdentifier, errorCode, abortReason);

            _errorCodeFeature.Error = (long)errorCode;
            _frameWriter.Abort(abortReason);

            // Call _http3Output.Stop() prior to poisoning the request body stream or pipe to
            // ensure that an app that completes early due to the abort doesn't result in header frames being sent.
            _http3Output.Stop();

            CancelRequestAbortedToken();

            // Unblock the request body.
            PoisonBody(abortReason);
            RequestBodyPipe.Writer.Complete(abortReason);
        }
Esempio n. 9
0
        /// <summary>
        /// Accepts unidirectional streams (control, QPack, ...) from the server.
        /// </summary>
        private async Task AcceptStreamsAsync()
        {
            try
            {
                while (true)
                {
                    ValueTask <QuicStream> streamTask;

                    lock (SyncObj)
                    {
                        if (ShuttingDown)
                        {
                            return;
                        }

                        // No cancellation token is needed here; we expect the operation to cancel itself when _connection is disposed.
                        streamTask = _connection !.AcceptInboundStreamAsync(CancellationToken.None);
                    }

                    QuicStream stream = await streamTask.ConfigureAwait(false);

                    // This process is cleaned up when _connection is disposed, and errors are observed via Abort().
                    _ = ProcessServerStreamAsync(stream);
                }
            }
            catch (QuicException ex) when(ex.QuicError == QuicError.OperationAborted)
            {
                // Shutdown initiated by us, no need to abort.
            }
            catch (QuicException ex) when(ex.QuicError == QuicError.ConnectionAborted)
            {
                Debug.Assert(ex.ApplicationErrorCode.HasValue);
                Http3ErrorCode code = (Http3ErrorCode)ex.ApplicationErrorCode.Value;

                Abort(HttpProtocolException.CreateHttp3ConnectionException(code, SR.net_http_http3_connection_close));
            }
            catch (Exception ex)
            {
                Abort(ex);
            }
        }
Esempio n. 10
0
        public void Abort(ConnectionAbortedException ex, Http3ErrorCode errorCode)
        {
            bool previousState;

            lock (_protocolSelectionLock)
            {
                previousState = _aborted;
                _aborted      = true;
            }

            if (!previousState)
            {
                if (TryClose())
                {
                    SendGoAway(_highestOpenedStreamId);
                }

                _errorCodeFeature.Error = (long)errorCode;
                _multiplexedContext.Abort(ex);
            }
        }
Esempio n. 11
0
        public void Abort(ConnectionAbortedException ex, Http3ErrorCode errorCode)
        {
            bool previousState;

            lock (_protocolSelectionLock)
            {
                previousState = _aborted;
                _aborted      = true;
            }

            if (!previousState)
            {
                _errorCodeFeature.Error = (long)errorCode;

                if (TryStopAcceptingStreams())
                {
                    SendGoAwayAsync(GetCurrentGoAwayStreamId()).Preserve();
                }

                _multiplexedContext.Abort(ex);
            }
        }
Esempio n. 12
0
 public void Http3StreamAbort(string traceIdentifier, Http3ErrorCode error, ConnectionAbortedException abortReason)
 {
 }
Esempio n. 13
0
 internal static HttpProtocolException CreateHttp3ConnectionException(Http3ErrorCode protocolError, string?message = null)
 {
     message = SR.Format(message ?? SR.net_http_http3_connection_error, GetName(protocolError), ((int)protocolError).ToString("x"));
     return(new HttpProtocolException((long)protocolError, message, null));
 }
Esempio n. 14
0
 public Http3StreamErrorException(string message, Http3ErrorCode errorCode)
     : base($"HTTP/3 stream error ({errorCode}): {message}")
 {
     ErrorCode = errorCode;
 }
Esempio n. 15
0
 public void Abort(ConnectionAbortedException ex, Http3ErrorCode errorCode)
 {
 }
 protected Http3ProtocolException(string message, Http3ErrorCode errorCode) : base(message)
 {
     ErrorCode = errorCode;
 }
Esempio n. 17
0
 public Http3ConnectionErrorException(string message, Http3ErrorCode errorCode)
     : base($"HTTP/3 connection error ({errorCode}): {message}")
 {
     ErrorCode = errorCode;
 }
Esempio n. 18
0
 public void Abort(ConnectionAbortedException ex, Http3ErrorCode errorCode)
 {
     // TODO something with request aborted?
 }
 public Http3ConnectionException(Http3ErrorCode errorCode)
     : base(SR.Format(SR.net_http_http3_connection_error, GetName(errorCode), ((long)errorCode).ToString("x")), errorCode)
 {
 }
Esempio n. 20
0
        internal void VerifyGoAway(Http3FrameWithPayload frame, long expectedLastStreamId, Http3ErrorCode expectedErrorCode)
        {
            Assert.Equal(Http3FrameType.GoAway, frame.Type);
            var payload = frame.Payload;

            Assert.True(VariableLengthIntegerHelper.TryRead(payload.Span, out var streamId, out var _));
            Assert.Equal(expectedLastStreamId, streamId);
        }
Esempio n. 21
0
        internal async Task WaitForConnectionErrorAsync(bool ignoreNonGoAwayFrames, long expectedLastStreamId, Http3ErrorCode expectedErrorCode)
        {
            var frame = await _inboundControlStream.ReceiveFrameAsync();

            if (ignoreNonGoAwayFrames)
            {
                while (frame.Type != Http3FrameType.GoAway)
                {
                    frame = await _inboundControlStream.ReceiveFrameAsync();
                }
            }

            VerifyGoAway(frame, expectedLastStreamId, expectedErrorCode);
        }
Esempio n. 22
0
        internal async Task WaitForConnectionErrorAsync <TException>(bool ignoreNonGoAwayFrames, long?expectedLastStreamId, Http3ErrorCode expectedErrorCode, params string[] expectedErrorMessage)
            where TException : Exception
        {
            var frame = await _inboundControlStream.ReceiveFrameAsync();

            if (ignoreNonGoAwayFrames)
            {
                while (frame.Type != Http3FrameType.GoAway)
                {
                    frame = await _inboundControlStream.ReceiveFrameAsync();
                }
            }

            if (expectedLastStreamId != null)
            {
                VerifyGoAway(frame, expectedLastStreamId.GetValueOrDefault());
            }

            Assert.Equal((Http3ErrorCode)expectedErrorCode, (Http3ErrorCode)MultiplexedConnectionContext.Error);

            if (expectedErrorMessage?.Length > 0)
            {
                var message = Assert.Single(LogMessages, m => m.Exception is TException);

                Assert.Contains(expectedErrorMessage, expected => message.Exception.Message.Contains(expected));
            }
        }
 public Http3ConnectionErrorException(string message, Http3ErrorCode errorCode)
     : base($"HTTP/3 connection error ({Http3Formatting.ToFormattedErrorCode(errorCode)}): {message}")
 {
     ErrorCode = errorCode;
 }
Esempio n. 24
0
        internal static HttpProtocolException CreateHttp3StreamException(Http3ErrorCode protocolError)
        {
            string message = SR.Format(SR.net_http_http3_stream_error, GetName(protocolError), ((int)protocolError).ToString("x"));

            return(new HttpProtocolException((long)protocolError, message, null));
        }
 protected Http3ProtocolException(SerializationInfo info, StreamingContext context) : base(info, context)
 {
     ErrorCode = (Http3ErrorCode)info.GetUInt32(nameof(ErrorCode));
 }
Esempio n. 26
0
 public void Abort(ConnectionAbortedException abortReason, Http3ErrorCode errorCode)
 {
     AbortCore(abortReason, errorCode);
 }
 protected static string GetName(Http3ErrorCode errorCode) =>
 // These strings come from the H3 spec and should not be localized.
 errorCode switch
 {
Esempio n. 28
0
        internal async Task WaitForConnectionErrorAsync <TException>(bool ignoreNonGoAwayFrames, long?expectedLastStreamId, Http3ErrorCode expectedErrorCode, Action <Type, string[]> matchExpectedErrorMessage = null, params string[] expectedErrorMessage)
            where TException : Exception
        {
            await WaitForGoAwayAsync(ignoreNonGoAwayFrames, expectedLastStreamId);

            AssertConnectionError <TException>(expectedErrorCode, matchExpectedErrorMessage, expectedErrorMessage);

            // Verify HttpConnection.ProcessRequestsAsync has exited.
#if IS_FUNCTIONAL_TESTS
            await _connectionTask.DefaultTimeout();
#else
            await _connectionTask;
#endif
        }
Esempio n. 29
0
        internal async Task WaitForConnectionErrorAsync <TException>(bool ignoreNonGoAwayFrames, long?expectedLastStreamId, Http3ErrorCode expectedErrorCode, Action <Type, string[]> matchExpectedErrorMessage = null, params string[] expectedErrorMessage)
            where TException : Exception
        {
            var frame = await _inboundControlStream.ReceiveFrameAsync();

            if (ignoreNonGoAwayFrames)
            {
                while (frame.Type != Http3FrameType.GoAway)
                {
                    frame = await _inboundControlStream.ReceiveFrameAsync();
                }
            }

            if (expectedLastStreamId != null)
            {
                VerifyGoAway(frame, expectedLastStreamId.GetValueOrDefault());
            }

            AssertConnectionError <TException>(expectedErrorCode, matchExpectedErrorMessage, expectedErrorMessage);

            // Verify HttpConnection.ProcessRequestsAsync has exited.
#if IS_FUNCTIONAL_TESTS
            await _connectionTask.DefaultTimeout();
#else
            await _connectionTask;
#endif

            // Verify server-to-client control stream has completed.
            await _inboundControlStream.ReceiveEndAsync();
        }