Ejemplo n.º 1
0
 public override async Task AcceptConnectionAsync(Func <GenericLoopbackConnection, Task> funcAsync)
 {
     using (GenericLoopbackConnection connection = await EstablishGenericConnectionAsync().ConfigureAwait(false))
     {
         await funcAsync(connection).ConfigureAwait(false);
     }
 }
Ejemplo n.º 2
0
 public override async Task <HttpRequestData> HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList <HttpHeaderData> headers = null, string content = "")
 {
     using (GenericLoopbackConnection connection = await EstablishGenericConnectionAsync().ConfigureAwait(false))
     {
         return(await connection.HandleRequestAsync(statusCode, headers, content).ConfigureAwait(false));
     }
 }
Ejemplo n.º 3
0
        public override async Task <HttpRequestData> HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList <HttpHeaderData> headers = null, string content = "")
        {
            using GenericLoopbackConnection con = await EstablishGenericConnectionAsync().ConfigureAwait(false);

            HttpRequestData request = await con.ReadRequestDataAsync().ConfigureAwait(false);

            await con.SendResponseAsync(statusCode, headers, content).ConfigureAwait(false);

            return(request);
        }
Ejemplo n.º 4
0
        public override async Task <GenericLoopbackConnection> EstablishGenericConnectionAsync()
        {
            Socket socket = await _listenSocket.AcceptAsync().ConfigureAwait(false);

            Stream stream = new NetworkStream(socket, ownsSocket: true);

            var options = new GenericLoopbackOptions()
            {
                Address       = _options.Address,
                SslProtocols  = _options.SslProtocols,
                UseSsl        = false,
                ListenBacklog = _options.ListenBacklog
            };

            GenericLoopbackConnection connection = null;

            try
            {
                if (_options.UseSsl)
                {
                    var sslStream = new SslStream(stream, false, delegate { return(true); });

                    using (X509Certificate2 cert = Configuration.Certificates.GetServerCertificate())
                    {
                        SslServerAuthenticationOptions sslOptions = new SslServerAuthenticationOptions();

                        sslOptions.EnabledSslProtocols  = _options.SslProtocols;
                        sslOptions.ApplicationProtocols = _options.SslApplicationProtocols;
                        sslOptions.ServerCertificate    = cert;

                        await sslStream.AuthenticateAsServerAsync(sslOptions, CancellationToken.None).ConfigureAwait(false);
                    }

                    stream = sslStream;
                    if (sslStream.NegotiatedApplicationProtocol == SslApplicationProtocol.Http2)
                    {
                        // Do not pass original options so the CreateConnectionAsync won't try to do ALPN again.
                        return(connection = await Http2LoopbackServerFactory.Singleton.CreateConnectionAsync(socket, stream, options).ConfigureAwait(false));
                    }
                    if (sslStream.NegotiatedApplicationProtocol == SslApplicationProtocol.Http11 ||
                        sslStream.NegotiatedApplicationProtocol == default)
                    {
                        // Do not pass original options so the CreateConnectionAsync won't try to do ALPN again.
                        return(connection = await Http11LoopbackServerFactory.Singleton.CreateConnectionAsync(socket, stream, options).ConfigureAwait(false));
                    }
                    else
                    {
                        throw new Exception($"Unsupported negotiated protocol {sslStream.NegotiatedApplicationProtocol}");
                    }
                }

                if (_options.ClearTextVersion is null)
                {
                    throw new Exception($"HTTP server does not accept clear text connections, either set '{nameof(HttpAgnosticOptions.UseSsl)}' or set up '{nameof(HttpAgnosticOptions.ClearTextVersion)}' in server options.");
                }

                var buffer   = new byte[24];
                var position = 0;
                while (position < buffer.Length)
                {
                    var readBytes = await stream.ReadAsync(buffer, position, buffer.Length - position).ConfigureAwait(false);

                    if (readBytes == 0)
                    {
                        break;
                    }
                    position += readBytes;
                }

                var memory = new Memory <byte>(buffer, 0, position);
                stream = new ReturnBufferStream(stream, memory);

                var prefix = Text.Encoding.ASCII.GetString(memory.Span);
                if (prefix == Http2LoopbackConnection.Http2Prefix)
                {
                    if (_options.ClearTextVersion == HttpVersion.Version20 || _options.ClearTextVersion == HttpVersion.Unknown)
                    {
                        return(connection = await Http2LoopbackServerFactory.Singleton.CreateConnectionAsync(socket, stream, options).ConfigureAwait(false));
                    }
                }
                else
                {
                    if (_options.ClearTextVersion == HttpVersion.Version11 || _options.ClearTextVersion == HttpVersion.Unknown)
                    {
                        return(connection = await Http11LoopbackServerFactory.Singleton.CreateConnectionAsync(socket, stream, options).ConfigureAwait(false));
                    }
                }

                throw new Exception($"HTTP/{_options.ClearTextVersion} server cannot establish connection due to unexpected data: '{prefix}'");
            }
            catch
            {
                connection?.Dispose();
                connection = null;
                stream.Dispose();
                throw;
            }
            finally
            {
                if (connection != null)
                {
                    await connection.InitializeConnectionAsync().ConfigureAwait(false);
                }
            }
        }
Ejemplo n.º 5
0
        public override async Task <GenericLoopbackConnection> EstablishGenericConnectionAsync()
        {
            Socket socket = await _listenSocket.AcceptAsync().ConfigureAwait(false);

            Stream stream = new NetworkStream(socket, ownsSocket: true);

            var options = new GenericLoopbackOptions()
            {
                Address       = _options.Address,
                SslProtocols  = _options.SslProtocols,
                UseSsl        = false,
                ListenBacklog = _options.ListenBacklog
            };

            GenericLoopbackConnection connection = null;

            try
            {
                if (_options.UseSsl)
                {
                    var sslStream = new SslStream(stream, false, delegate { return(true); });

                    using (X509Certificate2 cert = Configuration.Certificates.GetServerCertificate())
                    {
                        SslServerAuthenticationOptions sslOptions = new SslServerAuthenticationOptions();

                        sslOptions.EnabledSslProtocols  = _options.SslProtocols;
                        sslOptions.ApplicationProtocols = _options.SslApplicationProtocols;
                        sslOptions.ServerCertificate    = cert;

                        await sslStream.AuthenticateAsServerAsync(sslOptions, CancellationToken.None).ConfigureAwait(false);
                    }

                    stream = sslStream;
                    if (sslStream.NegotiatedApplicationProtocol == SslApplicationProtocol.Http2)
                    {
                        // Do not pass original options so the CreateConnectionAsync won't try to do ALPN again.
                        return(connection = await Http2LoopbackServerFactory.Singleton.CreateConnectionAsync(socket, stream, options).ConfigureAwait(false));
                    }
                    if (sslStream.NegotiatedApplicationProtocol == SslApplicationProtocol.Http11 ||
                        sslStream.NegotiatedApplicationProtocol == default)
                    {
                        // Do not pass original options so the CreateConnectionAsync won't try to do ALPN again.
                        return(connection = await Http11LoopbackServerFactory.Singleton.CreateConnectionAsync(socket, stream, options).ConfigureAwait(false));
                    }
                    else
                    {
                        throw new Exception($"Unsupported negotiated protocol {sslStream.NegotiatedApplicationProtocol}");
                    }
                }

                if (_options.ClearTextVersion == HttpVersion.Version11)
                {
                    return(connection = await Http11LoopbackServerFactory.Singleton.CreateConnectionAsync(socket, stream, options).ConfigureAwait(false));
                }
                else if (_options.ClearTextVersion == HttpVersion.Version20)
                {
                    return(connection = await Http2LoopbackServerFactory.Singleton.CreateConnectionAsync(socket, stream, options).ConfigureAwait(false));
                }
                else
                {
                    throw new Exception($"Invalid ClearTextVersion={_options.ClearTextVersion} specified");
                }
            }
            catch
            {
                connection?.Dispose();
                connection = null;
                stream.Dispose();
                throw;
            }
            finally
            {
                if (connection != null)
                {
                    await connection.InitializeConnectionAsync().ConfigureAwait(false);
                }
            }
        }