// // Parameters: // // args - original args passed to the program // root - true means caller is in the root domain // ext_apphost - used when single app mode is used, in a recursive call to // RealMain from the single app domain // quiet - don't show messages. Used to avoid double printing of the banner // public int RealMain(string [] args, bool root, IApplicationHost ext_apphost, bool quiet) { SecurityConfiguration security = new SecurityConfiguration (); ApplicationSettings settings = new ApplicationSettings (); if (settings.IP == null || settings.IP.Length == 0) settings.IP = "0.0.0.0"; if (settings.Oport == null) settings.Oport = 8080; Options options = 0; int hash = 0; for (int i = 0; i < args.Length; i++){ string a = args [i]; int idx = (i + 1 < args.Length) ? i + 1 : i; hash ^= args [idx].GetHashCode () + i; switch (a){ case "--https": CheckAndSetOptions (a, Options.Https, ref options); security.Enabled = true; break; case "--https-client-accept": CheckAndSetOptions (a, Options.Https, ref options); security.Enabled = true; security.AcceptClientCertificates = true; security.RequireClientCertificates = false; break; case "--https-client-require": CheckAndSetOptions (a, Options.Https, ref options); security.Enabled = true; security.AcceptClientCertificates = true; security.RequireClientCertificates = true; break; case "--p12file": security.Pkcs12File = args [++i]; break; case "--cert": security.CertificateFile = args [++i]; break; case "--pkfile": security.PvkFile = args [++i]; break; case "--pkpwd": security.Password = args [++i]; break; case "--protocols": security.SetProtocol (args [++i]); break; case "--port": CheckAndSetOptions (a, Options.Port, ref options); settings.Oport = args [++i]; break; case "--random-port": CheckAndSetOptions (a, Options.RandomPort, ref options); settings.Oport = 0; break; case "--address": CheckAndSetOptions (a, Options.Address, ref options); settings.IP = args [++i]; break; case "--root": CheckAndSetOptions (a, Options.Root, ref options); settings.RootDir = args [++i]; break; case "--applications": CheckAndSetOptions (a, Options.Applications, ref options); settings.Apps = args [++i]; break; case "--appconfigfile": CheckAndSetOptions (a, Options.AppConfigFile, ref options); settings.AppConfigFile = args [++i]; break; case "--appconfigdir": CheckAndSetOptions (a, Options.AppConfigDir, ref options); settings.AppConfigDir = args [++i]; break; case "--nonstop": settings.NonStop = true; break; case "--help": ShowHelp (); return 0; case "--quiet": quiet = true; break; case "--version": ShowVersion (); return 0; case "--verbose": settings.Verbose = true; break; case "--pidfile": { string pidfile = args[++i]; if (pidfile != null && pidfile.Length > 0) { try { using (StreamWriter sw = File.CreateText (pidfile)) sw.Write (Process.GetCurrentProcess ().Id); } catch (Exception ex) { Console.Error.WriteLine ("Failed to write pidfile {0}: {1}", pidfile, ex.Message); } } break; } case "--no-hidden": MonoWorkerRequest.CheckFileAccess = false; break; default: ShowHelp (); return 1; } } IPAddress ipaddr = null; ushort port; try { port = Convert.ToUInt16 (settings.Oport); } catch (Exception) { Console.WriteLine ("The value given for the listen port is not valid: " + settings.Oport); return 1; } try { ipaddr = IPAddress.Parse (settings.IP); } catch (Exception) { Console.WriteLine ("The value given for the address is not valid: " + settings.IP); return 1; } if (settings.RootDir != null && settings.RootDir.Length != 0) { try { Environment.CurrentDirectory = settings.RootDir; } catch (Exception e) { Console.WriteLine ("Error: {0}", e.Message); return 1; } } settings.RootDir = Directory.GetCurrentDirectory (); WebSource webSource; if (security.Enabled) { try { key = security.KeyPair; webSource = new XSPWebSource (ipaddr, port, security.Protocol, security.ServerCertificate, new PrivateKeySelectionCallback (GetPrivateKey), security.AcceptClientCertificates, security.RequireClientCertificates, !root); } catch (CryptographicException ce) { Console.WriteLine (ce.Message); return 1; } } else { webSource = new XSPWebSource (ipaddr, port, !root); } ApplicationServer server = new ApplicationServer (webSource, settings.RootDir); server.Verbose = settings.Verbose; server.SingleApplication = !root; if (settings.Apps != null) server.AddApplicationsFromCommandLine (settings.Apps); if (settings.AppConfigFile != null) server.AddApplicationsFromConfigFile (settings.AppConfigFile); if (settings.AppConfigDir != null) server.AddApplicationsFromConfigDirectory (settings.AppConfigDir); if (settings.Apps == null && settings.AppConfigDir == null && settings.AppConfigFile == null) server.AddApplicationsFromCommandLine ("/:."); VPathToHost vh = server.GetSingleApp (); if (root && vh != null) { // Redo in new domain vh.CreateHost (server, webSource); Server svr = (Server) vh.AppHost.Domain.CreateInstanceAndUnwrap (GetType ().Assembly.GetName ().ToString (), GetType ().FullName); webSource.Dispose (); return svr.RealMain (args, false, vh.AppHost, quiet); } server.AppHost = ext_apphost; if (!quiet) { Console.WriteLine (Assembly.GetExecutingAssembly ().GetName ().Name); Console.WriteLine ("Listening on address: {0}", settings.IP); Console.WriteLine ("Root directory: {0}", settings.RootDir); } try { if (server.Start (!settings.NonStop, settings.Exception) == false) return 2; if (!quiet) { // MonoDevelop depends on this string. If you change it, let them know. Console.WriteLine ("Listening on port: {0} {1}", server.Port, security); } if (port == 0 && !quiet) Console.Error.WriteLine ("Random port: {0}", server.Port); if (!settings.NonStop) { if (!quiet) Console.WriteLine ("Hit Return to stop the server."); bool doSleep; while (true) { doSleep = false; try { Console.ReadLine (); break; } catch (IOException) { // This might happen on appdomain unload // until the previous threads are terminated. doSleep = true; } catch (ThreadAbortException) { doSleep = true; } if (doSleep) Thread.Sleep (500); } server.Stop (); } } catch (Exception e) { if (!(e is ThreadAbortException)) Console.WriteLine ("Error: {0}", e); else server.ShutdownSockets (); return 1; } return 0; }
/// <param name="args">Original args passed to the program.</param> /// <param name="root">If set to <c>true</c> it means the caller is in the root domain.</param> /// <param name="ext_apphost">Used when single app mode is used, in a recursive call to RealMain from the single app domain.</param> /// <param name="quiet">If set to <c>true</c> don't show messages. Used to avoid double printing of the banner.</param> internal CompatTuple<int, string, ApplicationServer> DebugMain (string [] args, bool root, IApplicationHost ext_apphost, bool quiet) { var configurationManager = new ConfigurationManager ("xsp", quiet); var security = new SecurityConfiguration (); if (!ParseOptions (configurationManager, args, security)) return new CompatTuple<int,string,ApplicationServer> (1, "Error while parsing options", null); // Show the help and exit. if (configurationManager.Help) { configurationManager.PrintHelp (); #if DEBUG Console.WriteLine ("Press any key..."); Console.ReadKey (); #endif return success; } // Show the version and exit. if (configurationManager.Version) { Version.Show (); return success; } if (!configurationManager.LoadConfigFile ()) return new CompatTuple<int,string,ApplicationServer> (1, "Error while loading the configuration file", null); configurationManager.SetupLogger (); WebSource webSource; if (security.Enabled) { try { key = security.KeyPair; webSource = new XSPWebSource (configurationManager.Address, configurationManager.RandomPort ? default(ushort) : configurationManager.Port, security.Protocol, security.ServerCertificate, GetPrivateKey, security.AcceptClientCertificates, security.RequireClientCertificates, !root); } catch (CryptographicException ce) { Logger.Write (ce); return new CompatTuple<int,string,ApplicationServer> (1, "Error while setting up https", null); } } else { webSource = new XSPWebSource (configurationManager.Address, configurationManager.Port, !root); } var server = new ApplicationServer (webSource, configurationManager.Root) { Verbose = configurationManager.Verbose, SingleApplication = !root }; if (configurationManager.Applications != null) server.AddApplicationsFromCommandLine (configurationManager.Applications); if (configurationManager.AppConfigFile != null) server.AddApplicationsFromConfigFile (configurationManager.AppConfigFile); if (configurationManager.AppConfigDir != null) server.AddApplicationsFromConfigDirectory (configurationManager.AppConfigDir); if (configurationManager.Applications == null && configurationManager.AppConfigDir == null && configurationManager.AppConfigFile == null) server.AddApplicationsFromCommandLine ("/:."); VPathToHost vh = server.GetSingleApp (); if (root && vh != null) { // Redo in new domain vh.CreateHost (server, webSource); var svr = (Server) vh.AppHost.Domain.CreateInstanceAndUnwrap (GetType ().Assembly.GetName ().ToString (), GetType ().FullName); webSource.Dispose (); return svr.DebugMain (args, false, vh.AppHost, configurationManager.Quiet); } server.AppHost = ext_apphost; if (!configurationManager.Quiet) { Logger.Write(LogLevel.Notice, Assembly.GetExecutingAssembly().GetName().Name); Logger.Write(LogLevel.Notice, "Listening on address: {0}", configurationManager.Address); Logger.Write(LogLevel.Notice, "Root directory: {0}", configurationManager.Root); } try { if (!server.Start (!configurationManager.NonStop, (int)configurationManager.Backlog)) return new CompatTuple<int,string,ApplicationServer> (2, "Error while starting server", server); if (!configurationManager.Quiet) { // MonoDevelop depends on this string. If you change it, let them know. Logger.Write(LogLevel.Notice, "Listening on port: {0} {1}", server.Port, security); } if (configurationManager.RandomPort && !configurationManager.Quiet) Logger.Write (LogLevel.Notice, "Random port: {0}", server.Port); if (!configurationManager.NonStop) { if (!configurationManager.Quiet) Console.WriteLine ("Hit Return to stop the server."); while (true) { bool doSleep; try { Console.ReadLine (); break; } catch (IOException) { // This might happen on appdomain unload // until the previous threads are terminated. doSleep = true; } catch (ThreadAbortException) { doSleep = true; } if (doSleep) Thread.Sleep (500); } server.Stop (); } } catch (Exception e) { if (!(e is ThreadAbortException)) Logger.Write (e); else server.ShutdownSockets (); return new CompatTuple<int,string,ApplicationServer> (1, "Error running server", server); } return new CompatTuple<int,string,ApplicationServer> (0, null, server); }
static bool ParseOptions (ConfigurationManager manager, string[] args, SecurityConfiguration security) { if (!manager.LoadCommandLineArgs (args)) return false; // TODO: add mutual exclusivity rules if(manager.Https) security.Enabled = true; if (manager.HttpsClientAccept) { security.Enabled = true; security.AcceptClientCertificates = true; security.RequireClientCertificates = false; } if (manager.HttpsClientRequire) { security.Enabled = true; security.AcceptClientCertificates = true; security.RequireClientCertificates = true; } if (manager.P12File != null) security.Pkcs12File = manager.P12File; if(manager.Cert != null) security.CertificateFile = manager.Cert; if (manager.PkFile != null) security.PvkFile = manager.PkFile; if (manager.PkPwd != null) security.Password = manager.PkPwd; security.Protocol = manager.Protocols; int minThreads = manager.MinThreads ?? 0; if(minThreads > 0) ThreadPool.SetMinThreads (minThreads, minThreads); if(!String.IsNullOrEmpty(manager.PidFile)) try { using (StreamWriter sw = File.CreateText (manager.PidFile)) { sw.Write (Process.GetCurrentProcess ().Id); } } catch (Exception ex) { Logger.Write (LogLevel.Error, "Failed to write pidfile {0}: {1}", manager.PidFile, ex.Message); } if(manager.NoHidden) MonoWorkerRequest.CheckFileAccess = false; return true; }
// // Parameters: // // args - original args passed to the program // root - true means caller is in the root domain // ext_apphost - used when single app mode is used, in a recursive call to // RealMain from the single app domain // quiet - don't show messages. Used to avoid double printing of the banner // public int RealMain(string [] args, bool root, IApplicationHost ext_apphost, bool quiet) { SecurityConfiguration security = new SecurityConfiguration(); ApplicationSettings settings = new ApplicationSettings(); if (settings.IP == null || settings.IP.Length == 0) { settings.IP = "0.0.0.0"; } if (settings.Oport == null) { settings.Oport = 8080; } Options options = 0; int hash = 0; int backlog = 500; for (int i = 0; i < args.Length; i++) { string a = args [i]; int idx = (i + 1 < args.Length) ? i + 1 : i; hash ^= args [idx].GetHashCode() + i; switch (a) { case "--https": CheckAndSetOptions(a, Options.Https, ref options); security.Enabled = true; break; case "--https-client-accept": CheckAndSetOptions(a, Options.Https, ref options); security.Enabled = true; security.AcceptClientCertificates = true; security.RequireClientCertificates = false; break; case "--https-client-require": CheckAndSetOptions(a, Options.Https, ref options); security.Enabled = true; security.AcceptClientCertificates = true; security.RequireClientCertificates = true; break; case "--p12file": security.Pkcs12File = args [++i]; break; case "--cert": security.CertificateFile = args [++i]; break; case "--pkfile": security.PvkFile = args [++i]; break; case "--pkpwd": security.Password = args [++i]; break; case "--protocols": security.SetProtocol(args [++i]); break; case "--port": CheckAndSetOptions(a, Options.Port, ref options); settings.Oport = args [++i]; break; case "--random-port": CheckAndSetOptions(a, Options.RandomPort, ref options); settings.Oport = 0; break; case "--address": CheckAndSetOptions(a, Options.Address, ref options); settings.IP = args [++i]; break; case "--backlog": string backlogstr = args [++i]; try { backlog = Convert.ToInt32(backlogstr); } catch (Exception) { Console.WriteLine("The value given for backlog is not valid {0}", backlogstr); return(1); } break; case "--root": CheckAndSetOptions(a, Options.Root, ref options); settings.RootDir = args [++i]; break; case "--applications": CheckAndSetOptions(a, Options.Applications, ref options); settings.Apps = args [++i]; break; case "--appconfigfile": CheckAndSetOptions(a, Options.AppConfigFile, ref options); settings.AppConfigFile = args [++i]; break; case "--appconfigdir": CheckAndSetOptions(a, Options.AppConfigDir, ref options); settings.AppConfigDir = args [++i]; break; case "--minThreads": string mtstr = args [++i]; int minThreads = 0; try { minThreads = Convert.ToInt32(mtstr); } catch (Exception) { Console.WriteLine("The value given for minThreads is not valid {0}", mtstr); return(1); } if (minThreads > 0) { ThreadPool.SetMinThreads(minThreads, minThreads); } break; case "--nonstop": settings.NonStop = true; break; case "--help": ShowHelp(); return(0); case "--quiet": quiet = true; break; case "--version": ShowVersion(); return(0); case "--verbose": settings.Verbose = true; break; case "--pidfile": { string pidfile = args[++i]; if (pidfile != null && pidfile.Length > 0) { try { using (StreamWriter sw = File.CreateText(pidfile)) sw.Write(Process.GetCurrentProcess().Id); } catch (Exception ex) { Console.Error.WriteLine("Failed to write pidfile {0}: {1}", pidfile, ex.Message); } } break; } case "--no-hidden": MonoWorkerRequest.CheckFileAccess = false; break; default: ShowHelp(); return(1); } } IPAddress ipaddr = null; ushort port; try { port = Convert.ToUInt16(settings.Oport); } catch (Exception) { Console.WriteLine("The value given for the listen port is not valid: " + settings.Oport); return(1); } try { ipaddr = IPAddress.Parse(settings.IP); } catch (Exception) { Console.WriteLine("The value given for the address is not valid: " + settings.IP); return(1); } if (settings.RootDir != null && settings.RootDir.Length != 0) { try { Environment.CurrentDirectory = settings.RootDir; } catch (Exception e) { Console.WriteLine("Error: {0}", e.Message); return(1); } } settings.RootDir = Directory.GetCurrentDirectory(); WebSource webSource; if (security.Enabled) { try { key = security.KeyPair; webSource = new XSPWebSource(ipaddr, port, security.Protocol, security.ServerCertificate, new PrivateKeySelectionCallback(GetPrivateKey), security.AcceptClientCertificates, security.RequireClientCertificates, !root); } catch (CryptographicException ce) { Console.WriteLine(ce.Message); return(1); } } else { webSource = new XSPWebSource(ipaddr, port, !root); } ApplicationServer server = new ApplicationServer(webSource, settings.RootDir); server.Verbose = settings.Verbose; server.SingleApplication = !root; if (settings.Apps != null) { server.AddApplicationsFromCommandLine(settings.Apps); } if (settings.AppConfigFile != null) { server.AddApplicationsFromConfigFile(settings.AppConfigFile); } if (settings.AppConfigDir != null) { server.AddApplicationsFromConfigDirectory(settings.AppConfigDir); } if (settings.Apps == null && settings.AppConfigDir == null && settings.AppConfigFile == null) { server.AddApplicationsFromCommandLine("/:."); } VPathToHost vh = server.GetSingleApp(); if (root && vh != null) { // Redo in new domain vh.CreateHost(server, webSource); Server svr = (Server)vh.AppHost.Domain.CreateInstanceAndUnwrap(GetType().Assembly.GetName().ToString(), GetType().FullName); webSource.Dispose(); return(svr.RealMain(args, false, vh.AppHost, quiet)); } server.AppHost = ext_apphost; if (!quiet) { Console.WriteLine(Assembly.GetExecutingAssembly().GetName().Name); Console.WriteLine("Listening on address: {0}", settings.IP); Console.WriteLine("Root directory: {0}", settings.RootDir); } try { if (server.Start(!settings.NonStop, settings.Exception, backlog) == false) { return(2); } if (!quiet) { // MonoDevelop depends on this string. If you change it, let them know. Console.WriteLine("Listening on port: {0} {1}", server.Port, security); } if (port == 0 && !quiet) { Console.Error.WriteLine("Random port: {0}", server.Port); } if (!settings.NonStop) { if (!quiet) { Console.WriteLine("Hit Return to stop the server."); } bool doSleep; while (true) { doSleep = false; try { Console.ReadLine(); break; } catch (IOException) { // This might happen on appdomain unload // until the previous threads are terminated. doSleep = true; } catch (ThreadAbortException) { doSleep = true; } if (doSleep) { Thread.Sleep(500); } } server.Stop(); } } catch (Exception e) { if (!(e is ThreadAbortException)) { Console.WriteLine("Error: {0}", e); } else { server.ShutdownSockets(); } return(1); } return(0); }
static bool ParseOptions(ConfigurationManager manager, string[] args, SecurityConfiguration security) { if (!manager.LoadCommandLineArgs(args)) { return(false); } // TODO: add mutual exclusivity rules if (manager.Https) { security.Enabled = true; } if (manager.HttpsClientAccept) { security.Enabled = true; security.AcceptClientCertificates = true; security.RequireClientCertificates = false; } if (manager.HttpsClientRequire) { security.Enabled = true; security.AcceptClientCertificates = true; security.RequireClientCertificates = true; } if (manager.P12File != null) { security.Pkcs12File = manager.P12File; } if (manager.Cert != null) { security.CertificateFile = manager.Cert; } if (manager.PkFile != null) { security.PvkFile = manager.PkFile; } if (manager.PkPwd != null) { security.Password = manager.PkPwd; } security.Protocol = manager.Protocols; int minThreads = manager.MinThreads ?? 0; if (minThreads > 0) { ThreadPool.SetMinThreads(minThreads, minThreads); } if (!String.IsNullOrEmpty(manager.PidFile)) { try { using (StreamWriter sw = File.CreateText(manager.PidFile)) { sw.Write(Process.GetCurrentProcess().Id); } } catch (Exception ex) { Logger.Write(LogLevel.Error, "Failed to write pidfile {0}: {1}", manager.PidFile, ex.Message); } } if (manager.NoHidden) { MonoWorkerRequest.CheckFileAccess = false; } return(true); }
/// <param name="args">Original args passed to the program.</param> /// <param name="root">If set to <c>true</c> it means the caller is in the root domain.</param> /// <param name="ext_apphost">Used when single app mode is used, in a recursive call to RealMain from the single app domain.</param> /// <param name="quiet">If set to <c>true</c> don't show messages. Used to avoid double printing of the banner.</param> internal CompatTuple <int, string, ApplicationServer> DebugMain(string [] args, bool root, IApplicationHost ext_apphost, bool quiet) { var configurationManager = new ConfigurationManager("xsp", quiet); var security = new SecurityConfiguration(); if (!ParseOptions(configurationManager, args, security)) { return(new CompatTuple <int, string, ApplicationServer> (1, "Error while parsing options", null)); } // Show the help and exit. if (configurationManager.Help) { configurationManager.PrintHelp(); #if DEBUG Console.WriteLine("Press any key..."); Console.ReadKey(); #endif return(success); } // Show the version and exit. if (configurationManager.Version) { Version.Show(); return(success); } if (!configurationManager.LoadConfigFile()) { return(new CompatTuple <int, string, ApplicationServer> (1, "Error while loading the configuration file", null)); } configurationManager.SetupLogger(); WebSource webSource; if (security.Enabled) { try { key = security.KeyPair; webSource = new XSPWebSource(configurationManager.Address, configurationManager.RandomPort ? default(ushort) : configurationManager.Port, security.Protocol, security.ServerCertificate, GetPrivateKey, security.AcceptClientCertificates, security.RequireClientCertificates, !root); } catch (CryptographicException ce) { Logger.Write(ce); return(new CompatTuple <int, string, ApplicationServer> (1, "Error while setting up https", null)); } } else { webSource = new XSPWebSource(configurationManager.Address, configurationManager.Port, !root); } var server = new ApplicationServer(webSource, configurationManager.Root) { Verbose = configurationManager.Verbose, SingleApplication = !root }; if (configurationManager.Applications != null) { server.AddApplicationsFromCommandLine(configurationManager.Applications); } if (configurationManager.AppConfigFile != null) { server.AddApplicationsFromConfigFile(configurationManager.AppConfigFile); } if (configurationManager.AppConfigDir != null) { server.AddApplicationsFromConfigDirectory(configurationManager.AppConfigDir); } if (configurationManager.Applications == null && configurationManager.AppConfigDir == null && configurationManager.AppConfigFile == null) { server.AddApplicationsFromCommandLine("/:."); } VPathToHost vh = server.GetSingleApp(); if (root && vh != null) { // Redo in new domain vh.CreateHost(server, webSource); var svr = (Server)vh.AppHost.Domain.CreateInstanceAndUnwrap(GetType().Assembly.GetName().ToString(), GetType().FullName); webSource.Dispose(); return(svr.DebugMain(args, false, vh.AppHost, configurationManager.Quiet)); } server.AppHost = ext_apphost; if (!configurationManager.Quiet) { Logger.Write(LogLevel.Notice, Assembly.GetExecutingAssembly().GetName().Name); Logger.Write(LogLevel.Notice, "Listening on address: {0}", configurationManager.Address); Logger.Write(LogLevel.Notice, "Root directory: {0}", configurationManager.Root); } try { if (!server.Start(!configurationManager.NonStop, (int)configurationManager.Backlog)) { return(new CompatTuple <int, string, ApplicationServer> (2, "Error while starting server", server)); } if (!configurationManager.Quiet) { // MonoDevelop depends on this string. If you change it, let them know. Logger.Write(LogLevel.Notice, "Listening on port: {0} {1}", server.Port, security); } if (configurationManager.RandomPort && !configurationManager.Quiet) { Logger.Write(LogLevel.Notice, "Random port: {0}", server.Port); } if (!configurationManager.NonStop) { if (!configurationManager.Quiet) { Console.WriteLine("Hit Return to stop the server."); } while (true) { bool doSleep; try { Console.ReadLine(); break; } catch (IOException) { // This might happen on appdomain unload // until the previous threads are terminated. doSleep = true; } catch (ThreadAbortException) { doSleep = true; } if (doSleep) { Thread.Sleep(500); } } server.Stop(); } } catch (Exception e) { if (!(e is ThreadAbortException)) { Logger.Write(e); } else { server.ShutdownSockets(); } return(new CompatTuple <int, string, ApplicationServer> (1, "Error running server", server)); } return(new CompatTuple <int, string, ApplicationServer> (0, null, server)); }