예제 #1
0
        public Http3LoopbackServer(QuicImplementationProvider quicImplementationProvider = null, Http3Options options = null)
        {
            options ??= new Http3Options();

            _cert = Configuration.Certificates.GetServerCertificate();

            var listenerOptions = new QuicListenerOptions()
            {
                ListenEndPoint = new IPEndPoint(options.Address, 0),
                ServerAuthenticationOptions = new SslServerAuthenticationOptions
                {
                    EnabledSslProtocols  = options.SslProtocols,
                    ApplicationProtocols = new List <SslApplicationProtocol>
                    {
                        new SslApplicationProtocol(options.Alpn)
                    },
                    ServerCertificate         = _cert,
                    ClientCertificateRequired = false
                },
                MaxUnidirectionalStreams = options.MaxUnidirectionalStreams,
                MaxBidirectionalStreams  = options.MaxBidirectionalStreams,
            };

            _listener = new QuicListener(quicImplementationProvider ?? QuicImplementationProviders.Default, listenerOptions);
        }
예제 #2
0
        protected override async Task <StreamPair> CreateConnectedStreamsAsync()
        {
            QuicImplementationProvider provider = Provider;
            var listener = new QuicListener(
                provider,
                new IPEndPoint(IPAddress.Loopback, 0),
                GetSslServerAuthenticationOptions());

            byte[] buffer = new byte[1] {
                42
            };
            QuicConnection connection1 = null, connection2 = null;
            QuicStream     stream1 = null, stream2 = null;

            await WhenAllOrAnyFailed(
                Task.Run(async() =>
            {
                connection1 = await listener.AcceptConnectionAsync();
                stream1     = await connection1.AcceptStreamAsync();
                Assert.Equal(1, await stream1.ReadAsync(buffer));
            }),
                Task.Run(async() =>
            {
                try
                {
                    connection2 = new QuicConnection(
                        provider,
                        listener.ListenEndPoint,
                        GetSslClientAuthenticationOptions());
                    await connection2.ConnectAsync();
                    stream2 = await connection2.OpenBidirectionalStreamAsync();
                    // OpenBidirectionalStream only allocates ID. We will force stream opening
                    // by Writing there and receiving data on the other side.
                    await stream2.WriteAsync(buffer);
                }
                catch (Exception ex)
                {
                    _output?.WriteLine($"Failed to {ex.Message}");
                    throw;
                }
            }));

            // No need to keep the listener once we have connected connection and streams
            listener.Dispose();

            var result = new StreamPairWithOtherDisposables(stream1, stream2);

            result.Disposables.Add(connection1);
            result.Disposables.Add(connection2);

            return(result);
        }
예제 #3
0
        protected override async Task <StreamPair> CreateConnectedStreamsAsync()
        {
            QuicImplementationProvider provider = Provider;
            var protocol = new SslApplicationProtocol("quictest");

            var listener = new QuicListener(
                provider,
                new IPEndPoint(IPAddress.Loopback, 0),
                new SslServerAuthenticationOptions {
                ApplicationProtocols = new List <SslApplicationProtocol> {
                    protocol
                }
            });

            listener.Start();

            QuicConnection connection1 = null, connection2 = null;
            QuicStream     stream1 = null, stream2 = null;

            await WhenAllOrAnyFailed(
                Task.Run(async() =>
            {
                connection1 = await listener.AcceptConnectionAsync();
                stream1     = await connection1.AcceptStreamAsync();
            }),
                Task.Run(async() =>
            {
                connection2 = new QuicConnection(
                    provider,
                    listener.ListenEndPoint,
                    new SslClientAuthenticationOptions()
                {
                    ApplicationProtocols = new List <SslApplicationProtocol>()
                    {
                        protocol
                    }
                });
                await connection2.ConnectAsync();
                stream2 = connection2.OpenBidirectionalStream();
            }));

            var result = new StreamPairWithOtherDisposables(stream1, stream2);

            result.Disposables.Add(connection1);
            result.Disposables.Add(connection2);
            result.Disposables.Add(listener);

            return(result);
        }
예제 #4
0
        public Http3LoopbackServer(QuicImplementationProvider quicImplementationProvider = null, GenericLoopbackOptions options = null)
        {
            options ??= new GenericLoopbackOptions();

            _cert = Configuration.Certificates.GetSelfSigned13ServerCertificate();

            var sslOpts = new SslServerAuthenticationOptions
            {
                EnabledSslProtocols  = options.SslProtocols,
                ApplicationProtocols = new List <SslApplicationProtocol> {
                    new SslApplicationProtocol("h3-29")
                },
                //ServerCertificate = _cert,
                ClientCertificateRequired = false
            };

            _listener = new QuicListener(quicImplementationProvider ?? QuicImplementationProviders.Default, new IPEndPoint(options.Address, 0), sslOpts);
            _listener.Start();
        }
예제 #5
0
 // !!! TEMPORARY: Remove "implementationProvider" before shipping
 public QuicConnection(IPEndPoint remoteEndPoint, SslClientAuthenticationOptions sslClientAuthenticationOptions, IPEndPoint localEndPoint = null, QuicImplementationProvider implementationProvider = null)
 {
     _provider = implementationProvider.CreateConnection(remoteEndPoint, sslClientAuthenticationOptions, localEndPoint);
 }
예제 #6
0
 public Http3LoopbackServerFactory(QuicImplementationProvider quicImplementationProvider)
 {
     _quicImplementationProvider = quicImplementationProvider;
 }
예제 #7
0
 // !!! TEMPORARY: Remove "implementationProvider" before shipping
 public QuicListener(QuicImplementationProvider implementationProvider, IPEndPoint listenEndPoint, SslServerAuthenticationOptions sslServerAuthenticationOptions)
 {
     _provider = implementationProvider.CreateListener(listenEndPoint, sslServerAuthenticationOptions);
 }
예제 #8
0
        protected static LoopbackServerFactory GetFactoryForVersion(Version useVersion, QuicImplementationProvider quicImplementationProvider = null)
        {
            return(useVersion.Major switch
            {
#if NETCOREAPP
#if HTTP3
                3 => new Http3LoopbackServerFactory(quicImplementationProvider),
#endif
                2 => Http2LoopbackServerFactory.Singleton,
#endif
                _ => Http11LoopbackServerFactory.Singleton
            });
예제 #9
0
        protected static HttpClientHandler CreateHttpClientHandler(Version useVersion = null, QuicImplementationProvider quicImplementationProvider = null, bool allowAllHttp2Certificates = true)
        {
            useVersion ??= HttpVersion.Version11;

            HttpClientHandler handler = (PlatformDetection.SupportsAlpn && useVersion != HttpVersion.Version30) ? new HttpClientHandler() : new VersionHttpClientHandler(useVersion);

            if (useVersion >= HttpVersion.Version20 && allowAllHttp2Certificates)
            {
                handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates;
            }

            if (quicImplementationProvider != null)
            {
                SocketsHttpHandler socketsHttpHandler = (SocketsHttpHandler)GetUnderlyingSocketsHttpHandler(handler);
                socketsHttpHandler.QuicImplementationProvider = quicImplementationProvider;
            }

            return(handler);
        }
예제 #10
0
 // !!! TEMPORARY: Remove or make internal before shipping
 public QuicListener(QuicImplementationProvider implementationProvider, QuicListenerOptions options)
 {
     _provider = implementationProvider.CreateListener(options);
 }
예제 #11
0
 // !!! TEMPORARY: Remove or make internal before shipping
 public QuicListener(QuicImplementationProvider implementationProvider, IPEndPoint listenEndPoint, SslServerAuthenticationOptions sslServerAuthenticationOptions)
     : this(implementationProvider, new QuicListenerOptions() { ListenEndPoint = listenEndPoint, ServerAuthenticationOptions = sslServerAuthenticationOptions })
 {
 }
예제 #12
0
        protected static async Task <StreamPair> CreateConnectedStreamsAsync()
        {
            QuicImplementationProvider provider = ImplementationProvider;
            var protocol = new SslApplicationProtocol("quictest");

            QuicListener listener = new QuicListener(provider, new QuicListenerOptions()
            {
                ListenEndPoint = new IPEndPoint(IPAddress.Loopback, 0),
                ServerAuthenticationOptions = new SslServerAuthenticationOptions {
                    ApplicationProtocols = new List <SslApplicationProtocol> {
                        protocol
                    }
                },
                CertificateFilePath = "Certs/cert.crt",
                PrivateKeyFilePath  = "Certs/cert.key"
            });

            listener.Start();

            QuicConnection connection1 = null, connection2 = null;
            QuicStream     stream1 = null, stream2 = null;

            await Task.WhenAll(
                Task.Run(async() =>
            {
                connection1 = await listener.AcceptConnectionAsync();
                stream1     = await connection1.AcceptStreamAsync();

                // Hack to force stream creation
                byte[] buffer = new byte[1];
                await stream1.ReadAsync(buffer);
            }),
                Task.Run(async() =>
            {
                connection2 = new QuicConnection(
                    provider,
                    listener.ListenEndPoint,
                    new SslClientAuthenticationOptions()
                {
                    ApplicationProtocols = new List <SslApplicationProtocol>()
                    {
                        protocol
                    }
                });
                await connection2.ConnectAsync();
                stream2 = connection2.OpenBidirectionalStream();

                // Hack to force stream creation
                byte[] buffer = new byte[1];
                await stream2.WriteAsync(buffer);
                await stream2.FlushAsync();
            }));

            var result = new StreamPair(stream1, stream2);

            result.Disposables.Add(connection1);
            result.Disposables.Add(connection2);
            result.Disposables.Add(listener);

            return(result);
        }
예제 #13
0
 protected static LoopbackServerFactory GetFactoryForVersion(string useVersion, QuicImplementationProvider quicImplementationProvider = null) =>
 GetFactoryForVersion(Version.Parse(useVersion), quicImplementationProvider);
 public QuicConnection(QuicImplementationProvider implementationProvider, QuicClientConnectionOptions options)
 {
     _provider = implementationProvider.CreateConnection(options);
 }
 // !!! TEMPORARY: Remove "implementationProvider" before shipping
 public QuicConnection(QuicImplementationProvider implementationProvider, IPEndPoint remoteEndPoint, SslClientAuthenticationOptions sslClientAuthenticationOptions, IPEndPoint localEndPoint = null)
     : this(implementationProvider, new QuicClientConnectionOptions() { RemoteEndPoint = remoteEndPoint, ClientAuthenticationOptions = sslClientAuthenticationOptions, LocalEndPoint = localEndPoint })
 {
 }
        protected static void SetQuicImplementationProvider(SocketsHttpHandler handler, QuicImplementationProvider quicImplementationProvider)
        {
            FieldInfo settingsField = typeof(SocketsHttpHandler).GetField("_settings", BindingFlags.Instance | BindingFlags.NonPublic);
            object    settings      = settingsField.GetValue(handler);
            FieldInfo field         = settings.GetType().GetField("_quicImplementationProvider", BindingFlags.Instance | BindingFlags.NonPublic);

            field.SetValue(settings, quicImplementationProvider);
        }