File: Middleware\HttpMultiplexedConnectionMiddleware.cs
Web Access
Project: src\src\Servers\Kestrel\Core\src\Microsoft.AspNetCore.Server.Kestrel.Core.csproj (Microsoft.AspNetCore.Server.Kestrel.Core)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Net;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Connections.Features;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
 
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
 
internal sealed class HttpMultiplexedConnectionMiddleware<TContext> where TContext : notnull
{
    private readonly ServiceContext _serviceContext;
    private readonly IHttpApplication<TContext> _application;
    private readonly HttpProtocols _protocols;
    private readonly bool _addAltSvcHeader;
 
    public HttpMultiplexedConnectionMiddleware(ServiceContext serviceContext, IHttpApplication<TContext> application, HttpProtocols protocols, bool addAltSvcHeader)
    {
        _serviceContext = serviceContext;
        _application = application;
        _protocols = protocols;
        _addAltSvcHeader = addAltSvcHeader;
    }
 
    public Task OnConnectionAsync(MultiplexedConnectionContext connectionContext)
    {
        var memoryPoolFeature = connectionContext.Features.Get<IMemoryPoolFeature>();
        var localEndPoint = connectionContext.LocalEndPoint as IPEndPoint;
        var altSvcHeader = _addAltSvcHeader && localEndPoint != null ? HttpUtilities.GetEndpointAltSvc(localEndPoint, _protocols) : null;
        var metricContext = connectionContext.Features.GetRequiredFeature<IConnectionMetricsContextFeature>().MetricsContext;
 
        var httpConnectionContext = new HttpMultiplexedConnectionContext(
            connectionContext.ConnectionId,
            _protocols,
            altSvcHeader,
            connectionContext,
            _serviceContext,
            connectionContext.Features,
            memoryPoolFeature?.MemoryPool ?? System.Buffers.MemoryPool<byte>.Shared,
            localEndPoint,
            connectionContext.RemoteEndPoint as IPEndPoint,
            metricContext);
 
        if (connectionContext.Features.Get<IConnectionMetricsTagsFeature>() is { } metricsTags)
        {
            // HTTP/3 is always TLS 1.3. If multiple versions are support in the future then this value will need to be detected.
            metricsTags.Tags.Add(new KeyValuePair<string, object?>("tls.protocol.version", "1.3"));
        }
 
        var connection = new HttpConnection(httpConnectionContext);
 
        return connection.ProcessRequestsAsync(_application);
    }
}