public async Task <EndPoint> BindAsync(EndPoint endPoint, MultiplexedConnectionDelegate multiplexedConnectionDelegate, ListenOptions listenOptions, CancellationToken cancellationToken) { if (_multiplexedTransportFactory is null) { throw new InvalidOperationException($"Cannot bind with {nameof(MultiplexedConnectionDelegate)} no {nameof(IMultiplexedConnectionListenerFactory)} is registered."); } var features = new FeatureCollection(); // HttpsOptions or HttpsCallbackOptions should always be set in production, but it's not set for InMemory tests. // The QUIC transport will check if TlsConnectionCallbackOptions is missing. if (listenOptions.HttpsOptions != null) { var sslServerAuthenticationOptions = HttpsConnectionMiddleware.CreateHttp3Options(listenOptions.HttpsOptions); features.Set(new TlsConnectionCallbackOptions { ApplicationProtocols = sslServerAuthenticationOptions.ApplicationProtocols ?? new List <SslApplicationProtocol> { SslApplicationProtocol.Http3 }, OnConnection = (context, cancellationToken) => ValueTask.FromResult(sslServerAuthenticationOptions), OnConnectionState = null, }); } else if (listenOptions.HttpsCallbackOptions != null) { features.Set(new TlsConnectionCallbackOptions { ApplicationProtocols = new List <SslApplicationProtocol> { SslApplicationProtocol.Http3 }, OnConnection = (context, cancellationToken) => { return(listenOptions.HttpsCallbackOptions.OnConnection(new TlsHandshakeCallbackContext { ClientHelloInfo = context.ClientHelloInfo, CancellationToken = cancellationToken, State = context.State, Connection = new ConnectionContextAdapter(context.Connection), })); }, OnConnectionState = listenOptions.HttpsCallbackOptions.OnConnectionState, }); } var transport = await _multiplexedTransportFactory.BindAsync(endPoint, features, cancellationToken).ConfigureAwait(false); StartAcceptLoop(new GenericMultiplexedConnectionListener(transport), c => multiplexedConnectionDelegate(c), listenOptions.EndpointConfig); return(transport.EndPoint); }
public async Task <EndPoint> BindAsync(EndPoint endPoint, MultiplexedConnectionDelegate multiplexedConnectionDelegate, ListenOptions listenOptions, CancellationToken cancellationToken) { if (_multiplexedTransportFactory is null) { throw new InvalidOperationException($"Cannot bind with {nameof(MultiplexedConnectionDelegate)} no {nameof(IMultiplexedConnectionListenerFactory)} is registered."); } var features = new FeatureCollection(); // This should always be set in production, but it's not set for InMemory tests. // The transport will check if the feature is missing. if (listenOptions.HttpsOptions != null) { features.Set(HttpsConnectionMiddleware.CreateHttp3Options(listenOptions.HttpsOptions)); } var transport = await _multiplexedTransportFactory.BindAsync(endPoint, features, cancellationToken).ConfigureAwait(false); StartAcceptLoop(new GenericMultiplexedConnectionListener(transport), c => multiplexedConnectionDelegate(c), listenOptions.EndpointConfig); return(transport.EndPoint); }