public static IDisposable CreateServer(ILoggerFactory loggerFactory, out int port, Func <HttpContext, Task> app, Action <WebSocketOptions> configure = null)
        {
            configure = configure ?? (o => { });
            Action <IApplicationBuilder> startup = builder =>
            {
                builder.Use(async(ct, next) =>
                {
                    try
                    {
                        // Kestrel does not return proper error responses:
                        // https://github.com/aspnet/KestrelHttpServer/issues/43
                        await next();
                    }
                    catch (Exception ex)
                    {
                        if (ct.Response.HasStarted)
                        {
                            throw;
                        }

                        ct.Response.StatusCode = 500;
                        ct.Response.Headers.Clear();
                        await ct.Response.WriteAsync(ex.ToString());
                    }
                });
                builder.UseWebSockets();
                builder.Run(c => app(c));
            };

            var configBuilder = new ConfigurationBuilder();

            configBuilder.AddInMemoryCollection();
            var config = configBuilder.Build();

            config["server.urls"] = $"http://127.0.0.1:0";

            var host = new WebHostBuilder()
                       .ConfigureServices(s =>
            {
                s.AddWebSockets(configure);
                s.AddSingleton(loggerFactory);
            })
                       .UseConfiguration(config)
                       .UseKestrel()
                       .Configure(startup)
                       .Build();

            host.Start();
            port = host.GetPort();

            return(host);
        }
        public async Task LoggingConnectionAdapterCanBeAddedBeforeAndAfterHttpsAdapter()
        {
            var host = new WebHostBuilder()
                       .ConfigureLogging(builder =>
            {
                builder.SetMinimumLevel(LogLevel.Trace);
                builder.AddXunit(_output);
            })
                       .UseKestrel(options =>
            {
                options.Listen(new IPEndPoint(IPAddress.Loopback, 0), listenOptions =>
                {
                    listenOptions.UseConnectionLogging();
                    listenOptions.UseHttps(TestResources.TestCertificatePath, "testPassword");
                    listenOptions.UseConnectionLogging();
                });
            })
                       .Configure(app =>
            {
                app.Run(context =>
                {
                    context.Response.ContentLength = 12;
                    return(context.Response.WriteAsync("Hello World!"));
                });
            })
                       .Build();

            using (host)
            {
                await host.StartAsync();

                var response = await HttpClientSlim.GetStringAsync($"https://localhost:{host.GetPort()}/", validateCertificate : false)
                               .TimeoutAfter(TimeSpan.FromSeconds(10));

                Assert.Equal("Hello World!", response);
            }
        }