public void Start() { if (_isRunning) { throw new InvalidOperationException(); } _isRunning = true; Console.WriteLine("Starting server..."); var server = new HttpServer(_settings.HttpOptions); _resolver = new UrlResolver(); _resolver.Add(new UrlHook(path: "/", specificPath: true), handleIndex); _resolver.Add(new UrlHook(path: "/app.html", specificPath: true), handleApp); _resolver.Add(new UrlHook(path: "/api", specificPath: true), handleApi); _resolver.Add(new UrlHook(path: null), handleStatic); server.Handler = serverHandler; server.ErrorHandler = exceptionHandler; _services.Add(new ReloadService(this, _settings.StaticPath)); if (_settings.WeatherSettings != null) { _services.Add(new WeatherService(this, _settings.WeatherSettings)); } if (_settings.TimeSettings != null) { _services.Add(new TimeService(this, _settings.TimeSettings)); } if (_settings.PingSettings != null) { _services.Add(new PingService(this, _settings.PingSettings)); } if (_settings.HttpingSettings != null) { _services.Add(new HttpingService(this, _settings.HttpingSettings, _services.OfType <PingService>().Single())); } if (_settings.RouterSettings != null) { _services.Add(new RouterService(this, _settings.RouterSettings)); } Console.WriteLine("Initialising database..."); var absoluteDbPath = Path.Combine(Path.GetDirectoryName(SettingsUtil.GetAttribute <Settings>().GetFileName()), _settings.DbFilePath); Db.Initialise(absoluteDbPath, _services); foreach (var svc in _services) { Console.WriteLine($"Initialising {svc.ServiceName}..."); svc.Start(); } server.StartListening(blocking: false); }
/// <summary> /// Executes a Propeller module in standalone mode (as opposed to being hosted by the Propeller engine).</summary> /// <param name="module"> /// An instance of the module to be executed.</param> /// <param name="settingsPath"> /// Path and filename of the Propeller settings file. This file must contain a Propeller configuration containing /// exactly one module configuration.</param> /// <param name="propagateExceptions"> /// Specifies whether exceptions get propagated to the debugger. Setting this to <c>true</c> will cause exceptions /// to bring down the server, so only do this when debugging.</param> public static void RunStandalone(string settingsPath, IPropellerModule module, bool propagateExceptions = false) { var settings = LoadSettings(settingsPath, new ConsoleLogger(), true); if (settings.Modules.Length == 0) { settings.Modules = Ut.NewArray(new PropellerModuleSettings { ModuleName = module.Name, ModuleDll = null, Settings = new JsonDict(), Hooks = Ut.NewArray(new UrlHook(domain: "localhost", protocols: Protocols.All)) }); } if (settings.Modules.Length != 1) { throw new InvalidOperationException("Propeller Standalone mode can only accept a settings file that has exactly one module configuration."); } var log = GetLogger(true, settings.LogFile, settings.LogVerbosity); log.Info("Running Propeller module {0} in standalone mode.".Fmt(module.Name)); var resolver = new UrlResolver(); var server = new HttpServer(settings.ServerOptions) { Handler = resolver.Handle, PropagateExceptions = propagateExceptions }; var pretendPluginPath = PathUtil.AppPathCombine(module.Name + ".dll"); module.Init(log, settings.Modules[0].Settings, new SettingsSaver(s => { settings.Modules[0].Settings = s; try { settings.Save(settingsPath); } catch (Exception e) { log.Error("Error saving settings for module {0}:".Fmt(settings.Modules[0].ModuleName)); LogException(log, e); } })); if (settings.Modules[0].Hooks.Length == 0) { log.Warn("The settings did not configure any UrlHook for the module. It will not be accessible through any URL."); } else { foreach (var hook in settings.Modules[0].Hooks) { resolver.Add(new UrlMapping(hook, module.Handle)); } log.Info("Module URLs: " + settings.Modules[0].Hooks.JoinString("; ")); } log.Info("Starting server on {0}.".Fmt(settings.ServerOptions.Endpoints.Select(ep => "port " + ep.Value.Port + (ep.Value.Secure ? " (HTTPS)" : " (HTTP)")).JoinString(", "))); settings.Save(settingsPath); server.StartListening(true); }
public override HttpResponse Handle(HttpRequest request) { var auth = _config.UsersFile?.Apply(file => new FileAuthenticator(file, _ => request.Url.WithPath("").ToHref(), "Repository of Manual Pages")); return(new KtaneWebSession(_config).EnableAutomatic(request, session => { var resolver = new UrlResolver( #if DEBUG new UrlMapping(path: "/js", specificPath: true, handler: req => HttpResponse.File(_config.JavaScriptFile, "text/javascript; charset=utf-8")), new UrlMapping(path: "/css", specificPath: true, handler: req => HttpResponse.File(_config.CssFile, "text/css; charset=utf-8")), #else new UrlMapping(path: "/js", specificPath: true, handler: req => HttpResponse.JavaScript(Resources.Js)), new UrlMapping(path: "/css", specificPath: true, handler: req => HttpResponse.Css(Resources.Css)), #endif new UrlMapping(path: "/", specificPath: true, handler: mainPage), new UrlMapping(path: "/profile", handler: generateProfileZip), new UrlMapping(path: "/json", handler: req => { if (req.Url.Path != "/raw") { return HttpResponse.Redirect(req.Url.WithPathParent().WithPathOnly("/JSON/" + req.Url.Path)); } return HttpResponse.Json(getModuleInfoCache().ModulesJson, HttpStatusCode._200_OK, new HttpResponseHeaders { AccessControlAllowOrigin = "*" }); }), new UrlMapping(path: "/pull", handler: pull), new UrlMapping(path: "/ManualLastUpdated", handler: ManualLastUpdated), new UrlMapping(path: "/proxy", handler: proxy), new UrlMapping(path: "/merge-pdf", handler: mergePdfs), new UrlMapping(path: "/pdf-diag", handler: pdfDiag), new UrlMapping(path: "/upload-log", handler: uploadLogfile), new UrlMapping(path: "/find-log", handler: findLogfile), new UrlMapping(path: "/generate-json", handler: generateJson), new UrlMapping(path: "/iconsprite", handler: req => HttpResponse.Create(getModuleInfoCache().IconSpritePng, "image/png")), new UrlMapping(path: "/ignore-table", handler: ignoreTable), new UrlMapping(path: "/sitemap", specificPath: true, handler: sitemapXml), new UrlMapping(path: "/puzzles", handler: req => puzzles(req, _config.Puzzles, session)), new UrlMapping(path: "/Unfinished", handler: unfinished, skippable: true), new UrlMapping(path: "/Logfiles", handler: req => new FileSystemHandler(_config.LogfilesDir).Handle(req)), new UrlMapping(path: "/MergedPdfs", handler: req => new FileSystemHandler(_config.MergedPdfsDir).Handle(req)), // Shortcut URLs new UrlMapping(path: "/lfa", handler: req => HttpResponse.Redirect(req.Url.WithPathParent().WithPathOnly("/More/Logfile Analyzer.html"))), new UrlMapping(path: "/faq", handler: req => HttpResponse.Redirect(req.Url.WithPathParent().WithPathOnly("/More/FAQs.html"))), new UrlMapping(path: "/pe", handler: req => HttpResponse.Redirect(req.Url.WithPathParent().WithPathOnly("/More/Profile Editor.html"))), new UrlMapping(path: "/mse", handler: req => HttpResponse.Redirect(req.Url.WithPathParent().WithPathOnly("/More/Mode Settings Editor.html"))), // Default fallback: file system handler or PDF generator new UrlMapping(handler: pdfOrFileSystem) ); if (auth != null) { resolver.Add(new UrlMapping(path: "/auth", handler: req => auth.Handle(req, session.Username, user => { session.Username = user; lock (_config) { if (user == null) { _config.Sessions.Remove(session.SessionID); } else { _config.Sessions[session.SessionID] = user; } saveConfig(); } }))); } return resolver.Handle(request); })); }
public override HttpResponse Handle(HttpRequest request) { var auth = _config.UsersFile?.Apply(file => new FileAuthenticator(file, _ => request.Url.WithPath("").ToHref(), "Repository of Manual Pages")); return(new KtaneWebSession(_config).EnableAutomatic(request, session => { var resolver = new UrlResolver( #if DEBUG new UrlMapping(path: "/js", specificPath: true, handler: req => HttpResponse.File(_config.JavaScriptFile, "text/javascript; charset=utf-8")), new UrlMapping(path: "/css", specificPath: true, handler: req => HttpResponse.File(_config.CssFile, "text/css; charset=utf-8")), #else new UrlMapping(path: "/js", specificPath: true, handler: req => HttpResponse.JavaScript(Resources.Js)), new UrlMapping(path: "/css", specificPath: true, handler: req => HttpResponse.Css(Resources.Css)), #endif new UrlMapping(path: "/", specificPath: true, handler: mainPage), new UrlMapping(path: "/profile", handler: generateProfileZip), new UrlMapping(path: "/json", handler: req => { if (req.Url.Path != "/raw") { return HttpResponse.Redirect(req.Url.WithPathParent().WithPathOnly("/JSON/")); } ensureModuleInfoCache(); return HttpResponse.Json(_moduleInfoCache.ModulesJson, HttpStatusCode._200_OK, new HttpResponseHeaders { AccessControlAllowOrigin = "*" }); }), new UrlMapping(path: "/pull", handler: pull), new UrlMapping(path: "/proxy", handler: proxy), new UrlMapping(path: "/merge-pdf", handler: pdf), new UrlMapping(path: "/upload-log", handler: uploadLogfile), new UrlMapping(path: "/find-log", handler: findLogfile), new UrlMapping(path: "/generate-json", handler: generateJson), new UrlMapping(path: "/iconsprite", handler: iconSpritePng), new UrlMapping(path: "/sitemap", specificPath: true, handler: sitemapXml), new UrlMapping(path: "/puzzles", handler: req => puzzles(req, _config.Puzzles, session)), new UrlMapping(path: "/Unfinished", handler: unfinished, skippable: true), new UrlMapping(path: "/Logfiles", handler: req => new FileSystemHandler(_config.LogfilesDir).Handle(req)), new UrlMapping(path: "/MergedPdfs", handler: req => new FileSystemHandler(_config.MergedPdfsDir).Handle(req)), // Shortcut URLs new UrlMapping(path: "/lfa", handler: req => HttpResponse.Redirect(req.Url.WithPathParent().WithPathOnly("/More/Logfile Analyzer.html"))), new UrlMapping(path: "/faq", handler: req => HttpResponse.Redirect(req.Url.WithPathParent().WithPathOnly("/More/FAQs.html"))), // Default fallback: file system handler new UrlMapping(req => new FileSystemHandler(_config.BaseDir, new FileSystemOptions { MaxAge = null }).Handle(req)) ); foreach (string directory in Directory.GetDirectories(Path.Combine(_config.BaseDir, "HTML"))) { resolver.Add(new UrlMapping(path: "/manual/" + Path.GetFileName(directory), handler: req => new FileSystemHandler(directory, new FileSystemOptions { MaxAge = null }).Handle(req))); } if (auth != null) { resolver.Add(new UrlMapping(path: "/auth", handler: req => auth.Handle(req, session.Username, user => { session.Username = user; lock (_config) { if (user == null) { _config.Sessions.Remove(session.SessionID); } else { _config.Sessions[session.SessionID] = user; } saveConfig(); } }))); } return resolver.Handle(request); })); }