File: QuicTransportFactory.cs
Web Access
Project: src\src\Servers\Kestrel\Transport.Quic\src\Microsoft.AspNetCore.Server.Kestrel.Transport.Quic.csproj (Microsoft.AspNetCore.Server.Kestrel.Transport.Quic)
// 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.Http.Features;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Quic.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
 
namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Quic;
 
/// <summary>
/// A factory for QUIC based connections.
/// </summary>
internal sealed class QuicTransportFactory : IMultiplexedConnectionListenerFactory, IConnectionListenerFactorySelector
{
    private readonly ILogger _log;
    private readonly QuicTransportOptions _options;
 
    public QuicTransportFactory(ILoggerFactory loggerFactory, IOptions<QuicTransportOptions> options)
    {
        ArgumentNullException.ThrowIfNull(options);
        ArgumentNullException.ThrowIfNull(loggerFactory);
 
        var logger = loggerFactory.CreateLogger("Microsoft.AspNetCore.Server.Kestrel.Transport.Quic");
        _log = logger;
        _options = options.Value;
    }
 
    /// <summary>
    /// Binds an endpoint to be used for QUIC connections.
    /// </summary>
    /// <param name="endpoint">The endpoint to bind to.</param>
    /// <param name="features">Additional features to be used to create the listener.</param>
    /// <param name="cancellationToken">To cancel the </param>
    /// <returns>A </returns>
    public async ValueTask<IMultiplexedConnectionListener> BindAsync(EndPoint endpoint, IFeatureCollection? features = null, CancellationToken cancellationToken = default)
    {
        ArgumentNullException.ThrowIfNull(endpoint);
 
        var tlsConnectionOptions = features?.Get<TlsConnectionCallbackOptions>();
 
        if (tlsConnectionOptions == null)
        {
            throw new InvalidOperationException("Couldn't find HTTPS configuration for QUIC transport.");
        }
        if (tlsConnectionOptions.ApplicationProtocols == null || tlsConnectionOptions.ApplicationProtocols.Count == 0)
        {
            throw new InvalidOperationException("No application protocols specified for QUIC transport.");
        }
 
        var transport = new QuicConnectionListener(_options, _log, endpoint, tlsConnectionOptions);
        await transport.CreateListenerAsync();
 
        return transport;
    }
 
    public bool CanBind(EndPoint endpoint)
    {
        return endpoint is IPEndPoint;
    }
}