예제 #1
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);
        }
예제 #2
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));
        }