示例#1
0
        public void test_duplicated_keys_are_concatenated_in_same_section()
        {
            var parser = new ConcatenateDuplicatedKeysIniDataParser();

            parser.Configuration.AllowDuplicateSections = true;

            var iniData = parser.Parse(iniFileStr);

            Assert.That(iniData["MySection"]["File"] == "a.txt;b.txt;c.txt;d.txt");
        }
示例#2
0
        public void test_duplicated_keys_are_concatenated_with_different_string()
        {
            var parser = new ConcatenateDuplicatedKeysIniDataParser();

            parser.Configuration.ConcatenateSeparator   = "+";
            parser.Configuration.AllowDuplicateSections = true;

            var inidata = parser.Parse(iniFileStr);

            Assert.That(inidata["MySection"]["File"] == "a.txt+b.txt+c.txt+d.txt");
        }
示例#3
0
        public PhpDiagDialog(IServiceProvider provider, ServerManager server)
            : base(provider)
        {
            InitializeComponent();

            var knownPhpVersions = new Dictionary <string, PhpVersion>
            {
                { "5.6", new PhpVersion("5.6", new DateTime(2018, 12, 31), new Version(11, 0)) },
                { "7.0", new PhpVersion("7.0", new DateTime(2018, 12, 3), new Version(14, 0)) },
                { "7.1", new PhpVersion("7.1", new DateTime(2019, 12, 1), new Version(14, 0)) },
                { "7.2", new PhpVersion("7.2", new DateTime(2020, 11, 30), new Version(14, 11)) }
            };

            var container = new CompositeDisposable();

            FormClosed += (sender, args) => container.Dispose();

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnGenerate, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                txtResult.Clear();
                try
                {
                    Warn("IMPORTANT: This report might contain confidential information. Mask such before sharing to others.");
                    Warn("-----");
                    Debug($"System Time: {DateTime.Now}");
                    Debug($"Processor Architecture: {Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")}");
                    Debug($"OS: {Environment.OSVersion}");
                    Debug($"Server Type: {server.Mode.AsString(EnumFormat.Description)}");
                    Debug(string.Empty);

                    var modules = new ModulesFeature((Module)provider);
                    modules.Load();
                    Debug($"Scan {modules.Items.Count} installed module(s).");
                    if (modules.Items.All(item => item.Name != "FastCgiModule"))
                    {
                        Error($"FastCGI module is not installed as part of IIS. Please refer to https://docs.microsoft.com/en-us/iis/application-frameworks/scenario-build-a-php-website-on-iis/configuring-step-1-install-iis-and-php#13-download-and-install-php-manually for more details.");
                        return;
                    }
                    else
                    {
                        Debug("FastCGI module is installed.");
                    }

                    Debug(string.Empty);
                    var handlers = new HandlersFeature((Module)provider);
                    handlers.Load();
                    var foundPhpHandler = new List <HandlersItem>();
                    Debug($"Scan {handlers.Items.Count} registered handler(s).");
                    foreach (var item in handlers.Items)
                    {
                        if (item.Modules == "FastCgiModule")
                        {
                            Debug($"* Found FastCGI handler as {{ Name: {item.Name}, Path: {item.Path}, State: {item.GetState(handlers.AccessPolicy)}, Handler: {item.TypeString}, Entry Type: {item.Flag} }}.");
                            foundPhpHandler.Add(item);
                        }
                    }

                    if (foundPhpHandler.Count == 0)
                    {
                        Error($"No FastCGI handler is registered for this web site.");
                        Error($" * To run PHP on IIS, please refer to https://docs.microsoft.com/en-us/iis/application-frameworks/scenario-build-a-php-website-on-iis/configuring-step-1-install-iis-and-php#13-download-and-install-php-manually for more details.");
                        Error($" * To run Python on IIS, please refer to https://pypi.org/project/wfastcgi/ or use HttpPlatformHandler https://docs.microsoft.com/en-us/iis/extensions/httpplatformhandler/httpplatformhandler-configuration-reference.");
                        return;
                    }

                    Debug(string.Empty);
                    var fastCgiFeature = new FastCgiFeature((Module)provider);
                    fastCgiFeature.Load();
                    Debug($"Scan {fastCgiFeature.Items.Count} registered FastCGI application(s).");
                    var foundPhp = new List <FastCgiItem>();
                    foreach (var item in fastCgiFeature.Items)
                    {
                        var combination = string.IsNullOrWhiteSpace(item.Arguments) ? item.Path : item.Path + '|' + item.Arguments;
                        foreach (var handler in foundPhpHandler)
                        {
                            if (string.Equals(combination, handler.ScriptProcessor, StringComparison.OrdinalIgnoreCase))
                            {
                                Debug($"* Found FastCGI application registered as {{ Full path: {item.Path}, Arguments: {item.Arguments} }}.");
                                foundPhp.Add(item);
                                break;
                            }
                        }
                    }

                    if (foundPhp.Count == 0)
                    {
                        Error($"No suitable FastCGI appilcation is registered on this server.");
                        Error($" * To run PHP on IIS, please refer to https://docs.microsoft.com/en-us/iis/application-frameworks/scenario-build-a-php-website-on-iis/configuring-step-1-install-iis-and-php#13-download-and-install-php-manually for more details.");
                        Error($" * To run Python on IIS, please refer to https://pypi.org/project/wfastcgi/ or use HttpPlatformHandler https://docs.microsoft.com/en-us/iis/extensions/httpplatformhandler/httpplatformhandler-configuration-reference.");
                        return;
                    }

                    Debug(Environment.NewLine);
                    Debug($"Verify web stack installation versions.");
                    foreach (var item in foundPhp)
                    {
                        var path = item.Path;
                        if (path.TrimEnd('"').EndsWith("php-cgi.exe", StringComparison.OrdinalIgnoreCase))
                        {
                            // PHP
                            var info    = FileVersionInfo.GetVersionInfo(path);
                            var version = $"{info.FileMajorPart}.{info.FileMinorPart}";
                            if (knownPhpVersions.ContainsKey(version))
                            {
                                var matched = knownPhpVersions[version];
                                if (matched.ExpiringDate <= DateTime.Now)
                                {
                                    Error($"* PHP {info.FileVersion} ({path}) is unknown or obsolete. Please refer to http://php.net/supported-versions.php for more details.");
                                }
                                else if (matched.ExpiringDate > DateTime.Now && (matched.ExpiringDate - DateTime.Now).TotalDays < 180)
                                {
                                    Warn($"* PHP {version} ({path}) will soon be obsolete. Please refer to http://php.net/supported-versions.php for more details.");
                                }
                                else
                                {
                                    Debug($"* PHP {version} ({path}) is supported.");
                                }

                                var x86     = new PeNet.PeFile(path).Is32Bit;
                                var cppFile = Path.Combine(
                                    Environment.GetFolderPath(x86 ? Environment.SpecialFolder.SystemX86 : Environment.SpecialFolder.System),
                                    $"msvcp{matched.CppVersion.Major}0.dll");
                                if (File.Exists(cppFile))
                                {
                                    var cpp = FileVersionInfo.GetVersionInfo(cppFile);
                                    if (cpp.FileMinorPart >= matched.CppVersion.Minor)
                                    {
                                        Debug($"  Visual C++ runtime is detected (expected: {matched.CppVersion}, detected: {cpp.FileVersion}).");
                                    }
                                    else
                                    {
                                        Error($"  Visual C++ runtime {matched.CppVersion} is not detected. Please install it following the tips on https://windows.php.net/download/.");
                                    }
                                }
                                else
                                {
                                    Error($"  Visual C++ {matched.CppVersion} runtime is not detected. Please install it following the tips on https://windows.php.net/download/.");
                                }
                            }
                            else
                            {
                                Error($"* PHP {info.FileVersion} ({path}) is unknown or obsolete. Please refer to http://php.net/supported-versions.php for more details.");
                            }
                        }
                        else if (path.TrimEnd('"').EndsWith("python.exe", StringComparison.OrdinalIgnoreCase))
                        {
                            // Python
                        }
                    }

                    Debug(string.Empty);
                    var systemPath = Environment.GetEnvironmentVariable("Path");
                    Debug($"Windows Path environment variable: {systemPath}.");
                    Debug(string.Empty);
                    string[] paths = systemPath.Split(new char[1] {
                        Path.PathSeparator
                    });
                    foreach (var item in foundPhp)
                    {
                        var path = item.Path;
                        if (path.TrimEnd('"').EndsWith("php-cgi.exe", StringComparison.OrdinalIgnoreCase))
                        {
                            var rootFolder = Path.GetDirectoryName(path);
                            Debug($"[{rootFolder}]");
                            if (!Directory.Exists(rootFolder))
                            {
                                Error("Invalid root folder is found. Skip.");
                                continue;
                            }

                            var config = Path.Combine(rootFolder, "php.ini");
                            if (File.Exists(config))
                            {
                                Info($"Found PHP config file {config}.");
                                var parser = new ConcatenateDuplicatedKeysIniDataParser();
                                parser.Configuration.ConcatenateSeparator = " ";
                                var data            = parser.Parse(File.ReadAllText(config));
                                var extensionFolder = data["PHP"]["extension_dir"];
                                if (extensionFolder == null)
                                {
                                    extensionFolder = "ext";
                                }

                                var fullPath = Path.Combine(rootFolder, extensionFolder);
                                Info($"PHP loadable extension folder: {fullPath}");
                                var extesionNames = data["PHP"]["extension"];
                                if (extesionNames == null)
                                {
                                    Info("No extension to verify.");
                                }
                                else
                                {
                                    var extensions = extesionNames.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                                    Info($"Found {extensions.Length} extension(s) to verify.");
                                    var noError = true;
                                    foreach (var name in extensions)
                                    {
                                        var fileName = Path.Combine(fullPath, $"php_{name}.dll");
                                        if (!File.Exists(fileName))
                                        {
                                            Error($"* Extension {name} is listed, but on disk the file cannot be found {fileName}");
                                            noError = false;
                                        }
                                    }

                                    if (noError)
                                    {
                                        Info("All extension(s) listed can be found on disk.");
                                    }
                                }
                            }
                            else
                            {
                                Warn($"Cannot find PHP config file {config}. Default settings are used.");
                            }

                            var matched = false;
                            foreach (var system in paths)
                            {
                                if (string.Equals(rootFolder, system, StringComparison.OrdinalIgnoreCase))
                                {
                                    matched = true;
                                    break;
                                }
                            }

                            if (matched)
                            {
                                Debug($"PHP installation has been added to Windows Path environment variable.");
                            }
                            else
                            {
                                Error($"PHP installation is not yet added to Windows Path environment variable. Please refer to https://docs.microsoft.com/en-us/iis/application-frameworks/scenario-build-a-php-website-on-iis/configuring-step-1-install-iis-and-php#13-download-and-install-php-manually for more details.");
                                Warn($"Restart Jexus Manager and rerun PHP Diagnostics after changing Windows Path environment variable.");
                            }

                            Debug(string.Empty);

                            // TODO: verify other configuration in php.info.
                        }
                        else if (path.TrimEnd('"').EndsWith("python.exe", StringComparison.OrdinalIgnoreCase))
                        {
                        }
                    }
                }
                catch (Exception ex)
                {
                    Debug(ex.ToString());
                    Rollbar.RollbarLocator.RollbarInstance.Error(ex);
                }
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnSave, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                var fileName = DialogHelper.ShowSaveFileDialog(null, "Text Files|*.txt|All Files|*.*");
                if (string.IsNullOrEmpty(fileName))
                {
                    return;
                }

                File.WriteAllText(fileName, txtResult.Text);
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnVerify, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                txtResult.Clear();
            }));
        }
示例#4
0
        public PhpDiagDialog(IServiceProvider provider, ServerManager server)
            : base(provider)
        {
            InitializeComponent();

            var container = new CompositeDisposable();

            FormClosed += (sender, args) => container.Dispose();

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnGenerate, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                txtResult.Clear();
                try
                {
                    Debug($"System Time: {DateTime.Now}");
                    Debug($"Processor Architecture: {Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")}");
                    Debug($"OS: {Environment.OSVersion}");
                    Debug($"{server.Type}");
                    Debug(string.Empty);

                    var handlers = new HandlersFeature((Module)provider);
                    handlers.Load();
                    var foundPhpHandler = false;
                    Debug($"Scan {handlers.Items.Count} registered handler(s).");
                    foreach (var item in handlers.Items)
                    {
                        if (string.Equals(item.Path, "*.php", StringComparison.OrdinalIgnoreCase))
                        {
                            Debug($"* Found PHP handler as {{ Name: {item.Name}, Path: {item.Path}, State: {item.GetState(handlers.AccessPolicy)}, Handler: {item.TypeString}, Entry Type: {item.Flag} }}.");
                            foundPhpHandler = true;
                        }
                    }

                    if (!foundPhpHandler)
                    {
                        Error($"No PHP handler is registered for this web site. Please refer to https://docs.microsoft.com/en-us/iis/application-frameworks/scenario-build-a-php-website-on-iis/configuring-step-1-install-iis-and-php#13-download-and-install-php-manually for more details.");
                        return;
                    }

                    Debug(string.Empty);
                    var fastCgiFeature = new FastCgiFeature((Module)provider);
                    fastCgiFeature.Load();
                    Debug($"Scan {fastCgiFeature.Items.Count} registered FastCGI application(s).");
                    var foundPhp = new List <string>();
                    foreach (var item in fastCgiFeature.Items)
                    {
                        if (item.Path.TrimEnd('"').EndsWith("php-cgi.exe", StringComparison.OrdinalIgnoreCase))
                        {
                            Debug($"* Found PHP FastCGI application registered as {{ Full path: {item.Path}, Arguments: {item.Arguments} }}.");
                            foundPhp.Add(item.Path);
                        }
                    }

                    if (foundPhp.Count == 0)
                    {
                        Error($"No PHP FastCGI appilcation is registered on this server. Please refer to https://docs.microsoft.com/en-us/iis/application-frameworks/scenario-build-a-php-website-on-iis/configuring-step-1-install-iis-and-php#13-download-and-install-php-manually for more details.");
                        return;
                    }

                    Debug(Environment.NewLine);
                    Debug($"Verify PHP installation versions.");
                    foreach (var path in foundPhp)
                    {
                        var info = FileVersionInfo.GetVersionInfo(path);
                        if (info.FileMajorPart < 5)
                        {
                            Error($"* PHP {info.FileVersion} ({path}) is obsolete. Please refer to http://php.net/supported-versions.php for more details.");
                        }
                        else if (info.FileMajorPart == 5)
                        {
                            if (info.FileMinorPart < 6)
                            {
                                Error($"* PHP {info.FileVersion} ({path}) is obsolete. Please refer to http://php.net/supported-versions.php for more details.");
                            }
                            else if (info.FileMinorPart == 6)
                            {
                                Warn($"* PHP {info.FileVersion} ({path}) will soon be obsolete. Please refer to http://php.net/supported-versions.php for more details.");
                            }
                            else
                            {
                                Error($"* PHP {info.FileVersion} ({path}) is unknown. Please refer to http://php.net/supported-versions.php for more details.");
                            }
                        }
                        else if (info.FileMajorPart == 7)
                        {
                            if (info.FileMinorPart == 0)
                            {
                                Warn($"* PHP {info.FileVersion} ({path}) will soon be obsolete. Please refer to http://php.net/supported-versions.php for more details.");
                            }
                            else
                            {
                                Debug($"* PHP {info.FileVersion} ({path}) is supported.");
                            }
                        }
                        else
                        {
                            Error($"* PHP {info.FileVersion} ({path}) is unknown. Please refer to http://php.net/supported-versions.php for more details.");
                        }
                    }

                    Debug(string.Empty);
                    var systemPath = Environment.GetEnvironmentVariable("Path");
                    Debug($"Windows Path: {systemPath}.");
                    Debug(string.Empty);
                    string[] paths = systemPath.Split(new char[1] {
                        Path.PathSeparator
                    });
                    foreach (var path in foundPhp)
                    {
                        var rootFolder = Path.GetDirectoryName(path);
                        Debug($"[{rootFolder}]");
                        var config = Path.Combine(rootFolder, "php.ini");
                        if (File.Exists(config))
                        {
                            Info($"Found PHP config file {config}.");
                            var parser = new ConcatenateDuplicatedKeysIniDataParser();
                            parser.Configuration.ConcatenateSeparator = " ";
                            var data            = parser.Parse(File.ReadAllText(config));
                            var extensionFolder = data["PHP"]["extension_dir"];
                            if (extensionFolder == null)
                            {
                                extensionFolder = "ext";
                            }

                            var fullPath = Path.Combine(rootFolder, extensionFolder);
                            Info($"PHP loadable extension folder: {fullPath}");
                            var extesionNames = data["PHP"]["extension"];
                            if (extesionNames == null)
                            {
                                Info("No extension to verify.");
                            }
                            else
                            {
                                var extensions = extesionNames.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                                Info($"Found {extensions.Length} extension(s) to verify.");
                                var noError = true;
                                foreach (var name in extensions)
                                {
                                    var fileName = Path.Combine(fullPath, $"php_{name}.dll");
                                    if (!File.Exists(fileName))
                                    {
                                        Error($"* Extension {name} is listed, but on disk the file cannot be found {fileName}");
                                        noError = false;
                                    }
                                }

                                if (noError)
                                {
                                    Info("All extension(s) listed can be found on disk.");
                                }
                            }
                        }
                        else
                        {
                            Warn($"Cannot find PHP config file {config}. Default settings are used.");
                        }

                        var matched = false;
                        foreach (var system in paths)
                        {
                            if (string.Equals(rootFolder, system, StringComparison.OrdinalIgnoreCase))
                            {
                                matched = true;
                                break;
                            }
                        }

                        if (matched)
                        {
                            Debug($"PHP installation has been added to Windows Path environment.");
                        }
                        else
                        {
                            Error($"PHP installation is not yet added to Windows Path environment. Please refer to https://docs.microsoft.com/en-us/iis/application-frameworks/scenario-build-a-php-website-on-iis/configuring-step-1-install-iis-and-php#13-download-and-install-php-manually for more details.");
                        }

                        Debug(string.Empty);
                    }

                    // TODO: verify other configurations in php.info.
                }
                catch (Exception ex)
                {
                    Debug(ex.ToString());
                    RollbarDotNet.Rollbar.Report(ex);
                }
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnSave, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                var fileName = DialogHelper.ShowSaveFileDialog(null, "Text Files|*.txt|All Files|*.*");
                if (string.IsNullOrEmpty(fileName))
                {
                    return;
                }

                File.WriteAllText(fileName, txtResult.Text);
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnVerify, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                txtResult.Clear();
            }));
        }