Repository: dotnet/aspnetcore
File: src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs (C#)

Code before:

    private void CompleteStream(bool errored)
    {
        if (!EndStreamReceived)
        {
            if (!errored)
            {
                Log.RequestBodyNotEntirelyRead(ConnectionIdFeature, TraceIdentifier);
            }

            var (oldState, newState) = ApplyCompletionFlag(StreamCompletionFlags.AbortedRead);
            if (oldState != newState)
            {
                // https://quicwg.org/base-drafts/draft-ietf-quic-http.html#section-4.1-15
                // When the server does not need to receive the remainder of the request, it MAY abort reading
                // the request stream, send a complete response, and cleanly close the sending part of the stream.
                // The error code H3_NO_ERROR SHOULD be used when requesting that the client stop sending on the
                // request stream.
                _streamAbortFeature.AbortRead((long)Http3ErrorCode.NoError, new ConnectionAbortedException("The application completed without reading the entire request body."));
                RequestBodyPipe.Writer.Complete();
            }

            TryClose();
        }
        RequestBodyPipe.Reader.Complete();
        _http3Output.Complete();

        // Stream will be pooled after app completed.
        // Wait to signal app completed after any potential aborts on the stream.
        _appCompletedTaskSource.SetResult(null);
    }

    private bool TryClose()
    {
        if (Interlocked.Exchange(ref _isClosed, 1) == 0)
        {
            // Wake ProcessRequestAsync loop so that it can exit.
            Input.CancelPendingRead();

            return true;
        }

        return false;
    }

    public async Task ProcessRequestAsync<TContext>(IHttpApplication<TContext> application) where TContext : notnull
    {
        Exception? error = null;

        // With HTTP/3 the write-side of the stream can be aborted by the client after the server
        // has finished reading incoming content. That means errors can happen after the Input loop

Review comment (suggestion):
```suggestion

        RequestBodyPipe.Reader.Complete();

```

Code after:

    private void CompleteStream(bool errored)
    {
        if (!EndStreamReceived)
        {
            if (!errored)
            {
                Log.RequestBodyNotEntirelyRead(ConnectionIdFeature, TraceIdentifier);
            }

            var (oldState, newState) = ApplyCompletionFlag(StreamCompletionFlags.AbortedRead);
            if (oldState != newState)
            {
                // https://quicwg.org/base-drafts/draft-ietf-quic-http.html#section-4.1-15
                // When the server does not need to receive the remainder of the request, it MAY abort reading
                // the request stream, send a complete response, and cleanly close the sending part of the stream.
                // The error code H3_NO_ERROR SHOULD be used when requesting that the client stop sending on the
                // request stream.
                _streamAbortFeature.AbortRead((long)Http3ErrorCode.NoError, new ConnectionAbortedException("The application completed without reading the entire request body."));
                RequestBodyPipe.Writer.Complete();
            }

            TryClose();
        }

        RequestBodyPipe.Reader.Complete();

        _http3Output.Complete();

        // Stream will be pooled after app completed.
        // Wait to signal app completed after any potential aborts on the stream.
        _appCompletedTaskSource.SetResult(null);
    }

    private bool TryClose()
    {
        if (Interlocked.Exchange(ref _isClosed, 1) == 0)
        {
            // Wake ProcessRequestAsync loop so that it can exit.
            Input.CancelPendingRead();

            return true;
        }

        return false;
    }

    public async Task ProcessRequestAsync<TContext>(IHttpApplication<TContext> application) where TContext : notnull
    {
        Exception? error = null;