public ChutzpahWebServerHost CreateServer(ChutzpahWebServerConfiguration configuration) { if (ChutzpahWebServerHost.ActiveWebServer != null && ChutzpahWebServerHost.ActiveWebServer.RootPath.Equals(configuration.RootPath, StringComparison.OrdinalIgnoreCase)) { // If the requested server is already running just re-use it return(ChutzpahWebServerHost.ActiveWebServer); } var hostConfiguration = new HostConfiguration { RewriteLocalhost = true, UrlReservations = new UrlReservations { CreateAutomatically = true } }; var port = GetNextAvailablePort(configuration.DefaultPort.Value); var builtInDependencyFolder = fileProbe.BuiltInDependencyDirectory; ChutzpahTracer.TraceInformation("Creating Web Server Host at path {0} and port {1}", configuration.RootPath, port); var host = new NancyHost(new Uri(string.Format("http://localhost:{0}", port)), new NancySettingsBootstrapper(configuration.RootPath, builtInDependencyFolder), hostConfiguration); host.Start(); var chutzpahWebServerHost = ChutzpahWebServerHost.Create(host, configuration.RootPath, port); return(chutzpahWebServerHost); }
private ChutzpahWebServerHost BuildHost(string rootPath, int defaultPort, string builtInDependencyFolder) { var attemptLimit = Constants.WebServerCreationAttemptLimit; var success = false; do { // We can try multiple times to build the webserver. The reason is there is a possible race condition where // between when we find a free port and when we start the server that port may have been taken. To mitigate this we // can retry to hopefully avoid this issue. attemptLimit--; var port = FindFreePort(defaultPort); try { ChutzpahTracer.TraceInformation("Creating Web Server Host at path {0} and port {1}", rootPath, port); var host = new WebHostBuilder() .UseUrls($"http://localhost:{port}") .UseContentRoot(rootPath) .UseWebRoot("") .UseKestrel() .Configure((app) => { var env = (IHostingEnvironment)app.ApplicationServices.GetService(typeof(IHostingEnvironment)); app.UseStaticFiles(new StaticFileOptions { OnPrepareResponse = AddFileCacheHeaders, ServeUnknownFileTypes = true, FileProvider = new ChutzpahServerFileProvider(env.ContentRootPath, builtInDependencyFolder) }); app.Run(async(context) => { if (context.Request.Path == "/") { await context.Response.WriteAsync($"Chutzpah Web Server (Version { Assembly.GetEntryAssembly().GetName().Version})"); } else { context.Response.StatusCode = (int)HttpStatusCode.NotFound; } }); }) .Build(); host.Start(); success = true; return(ChutzpahWebServerHost.Create(host, rootPath, port)); } catch (Exception ex) when(attemptLimit > 0) { ChutzpahTracer.TraceError(ex, "Unable to create web server host at path {0} and port {1}. Trying again...", rootPath, port); } }while (!success && attemptLimit > 0); throw new ChutzpahException("Failed to create web server. This should never be hit!"); }
private ChutzpahWebServerHost SetupWebServerHost(ConcurrentBag <TestContext> testContexts) { ChutzpahWebServerHost webServerHost = null; var contextUsingWebServer = testContexts.Where(x => x.TestFileSettings.Server != null && x.TestFileSettings.Server.Enabled.GetValueOrDefault()).ToList(); var contextWithChosenServerConfiguration = contextUsingWebServer.FirstOrDefault(); if (contextWithChosenServerConfiguration != null) { var webServerConfiguration = contextWithChosenServerConfiguration.TestFileSettings.Server; webServerHost = webServerFactory.CreateServer(webServerConfiguration); // Stash host object on context for use in url generation contextUsingWebServer.ForEach(x => x.WebServerHost = webServerHost); } return(webServerHost); }