private static bool BindCertificate(HttpServerConfiguration <TAccount> config) { AssemblyPath = System.Reflection.Assembly.GetExecutingAssembly().Location; Port = config.Port.ToString(); IpAddress = "0.0.0.0"; BindingParams bindingParams; switch (config.CertificateBindType) { case BindType.CertificateThumbprint: bindingParams = new CertificateThumbprintBindingParams(config.CertificateThumbprint); break; case BindType.SubjectName: bindingParams = new CertificateSubjectnameParams(config.SubjectName, config.AllowGeneratedCertificates); break; case BindType.FromFile: bindingParams = new CertificateFileBindingParams(config.CertificateFilename, null); break; default: return(false); } var result = Binder.Bind(AssemblyPath, IpAddress, Port, config.CertificateBindType, bindingParams); if (result.Status != BindingStatus.Ok) { LogMessage(LogLevel.Warning, result.Reason ?? "Binding failed"); return(false); } return(true); }
private static void ConfigureResponseBuilding(HttpServerConfiguration <TAccount> configuration) { if (configuration.LogBodyReplacePatterns != null) { ResponseFactory.LogBodyReplacePatterns.AddRange(configuration.LogBodyReplacePatterns); } if (configuration.LogProhibitedHeaders != null) { ResponseFactory.LogProhibitedHeaders.AddRange(configuration.LogProhibitedHeaders); } ResponseFactory.NonSerializableTypes = configuration.NonSerializableTypes; ResponseFactory.SetBodyEncoders(configuration.BodyEncoders); ResponseFactory.LogResponseBodies = configuration.LogResponseBodies; ResponseFactory.RequestTracingEnabled = configuration.RequestTracingEnabled; ResponseFactory.ResponseBodyLogLimit = configuration.ResponseBodyLogLimit; CommonHelper.SetSerializationLimitations(configuration.RequestBodyLogLimit, configuration.LogProhibitedQueryParams, configuration.LogProhibitedHeaders, configuration.BodyEncoders.First(be => be.IsDefault).Encoding); if (configuration.ServerName != null) { ResponseFactory.SetCommonHeaders(new Dictionary <string, string> { { "Server", configuration.ServerName } }); } }
private static void PrepareStatistics(HttpServerConfiguration <TAccount> configuration) { _statisticsController = configuration.StatisticsEnabled ? new StatisticsController <TAccount>(new ServerStatistics <TAccount>( configuration.CriticalMemoryValue, configuration.MemoryAlarmStrategy), configuration.StatisticsAuthorizer) : new StatisticsController <TAccount>(null, null); }
private static void StartListenerThread(HttpServerConfiguration <TAccount> configuration) { var protocolString = configuration.Protocol == Protocol.Http ? "http" : "https"; ServicePointManager.DefaultConnectionLimit = 1000; _requestExecutonBlock = new ActionBlock <HttpListenerContext>(HandleRequestAsync, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = configuration.MaxConcurrentRequests > 0 ? configuration.MaxConcurrentRequests : -1, BoundedCapacity = configuration.MaxRequestQueue > 0 ? configuration.MaxRequestQueue : -1 }); _serviceUnavailabeBlock = new ActionBlock <HttpListenerContext>((Action <HttpListenerContext>)ReportServiceUnavailable, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 1 }); _listener = new HttpListener(); _listener.Prefixes.Add($"{protocolString}://+:{configuration.Port}/"); _listener.IgnoreWriteExceptions = true; _listener.Start(); _listenerThread = new Thread(() => { LogMessage(LogLevel.Info, "Server listener thread started"); LogMessage(LogLevel.Info, $"Started listening port {configuration.Port}"); while (true) { try { var context = _listener.GetContext(); LogDebug($"Client connected: {context.Request.RemoteEndPoint}"); if (!_requestExecutonBlock.Post(context)) { _serviceUnavailabeBlock.Post(context); } } catch (ThreadAbortException) { LogMessage(LogLevel.Info, "Server listener thread stopped"); break; } catch (Exception ex) { LogException(LogLevel.Error, ex); } } }); _listenerThread.Start(); _serverAddress = $"{protocolString}://{configuration.SubjectName}:{configuration.Port}/"; }
private static bool StartFileProcessing(HttpServerConfiguration <TAccount> configuration) { _fileRequestController = new FileRequestController <TAccount>(); return(_fileRequestController.Start(new FileRequestControllerConfiguration <TAccount> { FilesEnabled = configuration.FilesEnabled, FilesBaseUri = configuration.FilesBaseUri, ExistingFilesPreprocessingFrequency = configuration.ExistingFilesPreprocessingFrequency, FaviconPath = configuration.FaviconPath, FilesAuthorizer = configuration.FilesAuthorizer, FileSections = configuration.FileSections, FilesLocation = configuration.FilesLocation, FilesNeedAuthorization = configuration.FilesNeedAuthorization, FilesPreprocessingEnabled = configuration.FilesPreprocessingEnabled, FilesCompressionEnabled = configuration.FilesCompressionEnabled, FilesPreprocessorThreads = configuration.FilesPreprocessorThreads }, _statisticsController.Statistics)); }
private static void StartServices(HttpServerConfiguration <TAccount> configuration) { ServiceUris.AddRange(configuration.GetReservedUris()); if (ServiceUris.Any()) { LogDebug($"Reserved sections:\n{string.Join("\n", ServiceUris)}"); } ServiceRequestProcessors.Add(_optionsController); if (configuration.FilesEnabled) { ServiceRequestProcessors.Add(_fileRequestController); } if (configuration.StatisticsEnabled) { ServiceRequestProcessors.Add(_statisticsController); } ServiceRequestProcessors.Add(_pingController); if (configuration.ConfigurationViewEnabled) { ServiceRequestProcessors.Add(_configurationController); } ServiceRequestProcessors.Add(_authentificationController); }
public static ServerStartStatus Start(HttpServerConfiguration <TAccount> configuration) { if (_started) { LogMessage(LogLevel.Warning, "Server is already running"); return(ServerStartStatus.AlreadyStarted); } lock (OperationLock) { if (_operationInProgress) { LogMessage(LogLevel.Info, "Cannot start now, operation in progress"); return(ServerStartStatus.AlreadyStarted); } _operationInProgress = true; } if (configuration == null || !configuration.IsEnough()) { return(ServerStartStatus.BadParameters); } DebugLogsEnabled = configuration.DebugLogsEnabled; RequestTracingEnabled = configuration.RequestTracingEnabled; try { PrepareStatistics(configuration); _optionsController = new OptionsController <TAccount>(InnerRequestProcessors); _pingController = new PingController(); _configurationController = new ConfigurationController <TAccount>(configuration); Protocol = configuration.Protocol; _authorizer = configuration.Authorizer; _authentificationController = new AuthentificationController(configuration.Authentificator); ConfigureResponseBuilding(configuration); if (configuration.FilesEnabled) { if (!StartFileProcessing(configuration)) { return(ServerStartStatus.BadParameters); } } _requestMaxServeTime = configuration.RequestMaxServeTime; if (Protocol == Protocol.Https) { if (!BindCertificate(configuration)) { LogMessage(LogLevel.Warning, "Binding failed"); return(ServerStartStatus.BindingError); } } StartListenerThread(configuration); StartServices(configuration); _started = true; return(ServerStartStatus.Ok); } catch (SocketException) { LogMessage(LogLevel.Critical, $"Error binding to port {configuration.Port}. Is it in use?"); _fileRequestController?.Stop(); return(ServerStartStatus.BindingError); } catch (Exception ex) { LogException(LogLevel.Critical, ex); _fileRequestController?.Stop(); return(ServerStartStatus.UnknownError); } finally { lock (OperationLock) { _operationInProgress = false; } } }