Example #1
0
        private static void AddIsapiHandler(string ext, string isapi, ConfigurationElementCollection handlerCollection)
        {
            ConfigurationElement element = handlerCollection.CreateElement("add");

            SetIsapiConfig(ext, isapi, element);
            handlerCollection.AddAt(0, element);
        }
Example #2
0
        private static void RegisterPhpDefaultDocument(ConfigurationSection defaultDocument)
        {
            ConfigurationElement           defaultFiles    = defaultDocument.GetChildElement("files");
            ConfigurationElementCollection filesCollection = defaultFiles.GetCollection();

            // search index.php in default documents
            bool indexPhpPresent = false;

            foreach (ConfigurationElement configurationElement in filesCollection)
            {
                string value = configurationElement.GetAttributeValue("value") as string;
                if (!string.IsNullOrEmpty(value))
                {
                    if (string.Equals(value, "index.php", StringComparison.OrdinalIgnoreCase))
                    {
                        indexPhpPresent = true;
                        break;
                    }
                }
            }

            if (!indexPhpPresent)
            {
                // add index.php
                ConfigurationElement indexPhp = filesCollection.CreateElement();
                indexPhp.SetAttributeValue("value", "index.php");
                filesCollection.AddAt(0, indexPhp);
            }
        }
Example #3
0
    private static void Main()
    {
        using (ServerManager serverManager = new ServerManager())
        {
            Configuration                  appHostConfig      = serverManager.GetApplicationHostConfiguration();
            ConfigurationSection           fastCgiSection     = appHostConfig.GetSection("system.webServer/fastCgi");
            ConfigurationElementCollection fastCgiCollection  = fastCgiSection.GetCollection();
            ConfigurationElement           applicationElement = fastCgiCollection.CreateElement("application");
            applicationElement["fullPath"] = @"c:\php\php-cgi.exe";
            fastCgiCollection.Add(applicationElement);

            Configuration                  webConfig          = serverManager.GetWebConfiguration("Contoso");
            ConfigurationSection           handlersSection    = webConfig.GetSection("system.webServer/handlers");
            ConfigurationElementCollection handlersCollection = handlersSection.GetCollection();
            ConfigurationElement           addElement         = handlersCollection.CreateElement("add");
            addElement["name"]            = @"PHP-FastCGI";
            addElement["path"]            = @"*.php";
            addElement["verb"]            = @"GET,HEAD,POST";
            addElement["modules"]         = @"FastCgiModule";
            addElement["scriptProcessor"] = @"c:\php\php-cgi.exe";
            addElement["resourceType"]    = @"Either";
            handlersCollection.AddAt(0, addElement);

            serverManager.CommitChanges();
        }
    }
Example #4
0
    private static void Main()
    {
        using (ServerManager serverManager = new ServerManager()) {
            Configuration                  config             = serverManager.GetApplicationHostConfiguration();
            ConfigurationSection           cachingSection     = config.GetSection("system.webServer/caching");
            ConfigurationElementCollection profilesCollection = cachingSection.GetCollection("profiles");

            ConfigurationElement addElement = profilesCollection.CreateElement("add");
            addElement["extension"]         = @"asp";
            addElement["policy"]            = @"CacheUntilChange";
            addElement["kernelCachePolicy"] = @"CacheUntilChange";
            profilesCollection.AddAt(0, addElement);

            serverManager.CommitChanges();
        }
    }
Example #5
0
    private static void Main()
    {
        using (ServerManager serverManager = new ServerManager()) {
            Configuration config = serverManager.GetWebConfiguration("Contoso");

            ConfigurationSection defaultDocumentSection = config.GetSection("system.webServer/defaultDocument");

            defaultDocumentSection["enabled"] = true;

            ConfigurationElementCollection filesCollection = defaultDocumentSection.GetCollection("files");
            ConfigurationElement           addElement      = filesCollection.CreateElement("add");
            addElement["value"] = @"home.html";
            filesCollection.AddAt(0, addElement);

            serverManager.CommitChanges();
        }
    }
Example #6
0
    private static void Main()
    {
        using (ServerManager serverManager = new ServerManager())
        {
            Configuration config = serverManager.GetApplicationHostConfiguration();

            ConfigurationSection           fastCgiSection     = config.GetSection("system.webServer/fastCgi");
            ConfigurationElementCollection fastCgiCollection  = fastCgiSection.GetCollection();
            ConfigurationElement           applicationElement = fastCgiCollection.CreateElement("application");
            applicationElement["fullPath"]            = @"C:\PHP\php-cgi.exe";
            applicationElement["arguments"]           = @"";
            applicationElement["maxInstances"]        = 4;
            applicationElement["idleTimeout"]         = 300;
            applicationElement["activityTimeout"]     = 30;
            applicationElement["requestTimeout"]      = 90;
            applicationElement["instanceMaxRequests"] = 10000;
            applicationElement["protocol"]            = @"NamedPipe";
            applicationElement["flushNamedPipe"]      = false;

            ConfigurationElementCollection environmentVariablesCollection = applicationElement.GetCollection("environmentVariables");
            ConfigurationElement           environmentVariableElement     = environmentVariablesCollection.CreateElement("environmentVariable");
            environmentVariableElement["name"]  = @"PHP_FCGI_MAX_REQUESTS";
            environmentVariableElement["value"] = @"10000";
            environmentVariablesCollection.Add(environmentVariableElement);
            fastCgiCollection.Add(applicationElement);

            ConfigurationSection           handlersSection    = config.GetSection("system.webServer/handlers");
            ConfigurationElementCollection handlersCollection = handlersSection.GetCollection();
            ConfigurationElement           addElement         = handlersCollection.CreateElement("add");
            addElement["name"]            = @"PHP-FastCGI";
            addElement["path"]            = @"*.php";
            addElement["verb"]            = @"GET,HEAD,POST";
            addElement["modules"]         = @"FastCgiModule";
            addElement["scriptProcessor"] = @"C:\PHP\php-cgi.exe";
            addElement["resourceType"]    = @"Either";
            addElement["requireAccess"]   = @"Script";
            handlersCollection.AddAt(0, addElement);

            serverManager.CommitChanges();
        }
    }
Example #7
0
        private static void RegisterZooPhpHandlers(string siteId, string[] engineNames, Configuration appConfig)
        {
            // set up zoo php handler if php engine was enabled
            string enabledPhpEngine = string.Empty;

            foreach (string engineName in engineNames)
            {
                if (engineName.StartsWith("php", StringComparison.OrdinalIgnoreCase))
                {
                    enabledPhpEngine = engineName;
                }
            }

            if (!string.IsNullOrEmpty(enabledPhpEngine))
            {
                ConfigurationSection           handlers          = appConfig.GetSection("system.webServer/handlers", siteId);
                ConfigurationElementCollection handlerCollection = handlers.GetCollection();

                // remove native php handlers

                /*
                 *  ConfigurationElement removePhp53 = handlerCollection.CreateElement("remove");
                 *  removePhp53.SetAttributeValue("name", "PHP53_via_FastCGI");
                 *  handlerCollection.Add(removePhp53);
                 *
                 *  ConfigurationElement removePhp = handlerCollection.CreateElement("remove");
                 *  removePhp.SetAttributeValue("name", "PHP_via_FastCGI");
                 *  handlerCollection.Add(removePhp);
                 */

                // search native php handlers

                /*
                 *  List<ConfigurationElement> elementsToRemove = new List<ConfigurationElement>();
                 *  foreach (ConfigurationElement el in handlerCollection)
                 *  {
                 *      string name = el.GetAttributeValue("name") as string;
                 *      if (!string.IsNullOrEmpty(name))
                 *      {
                 *          if (string.Equals(name, "PHP_via_FastCGI", StringComparison.OrdinalIgnoreCase)
                 ||
                 ||             string.Equals(name, "PHP53_via_FastCGI", StringComparison.OrdinalIgnoreCase)
                 ||         )
                 ||         {
                 ||             elementsToRemove.Add(el);
                 ||         }
                 ||     }
                 || }
                 ||
                 || foreach (ConfigurationElement element in elementsToRemove)
                 || {
                 ||     //handlerCollection.Remove(element);
                 || }
                 */


                // check zoo handlers exists
                List <ConfigurationElement> zooPhpHandlersToRemove = new List <ConfigurationElement>();
                foreach (ConfigurationElement el in handlerCollection)
                {
                    string name = el.GetAttributeValue("name") as string;
                    if (!string.IsNullOrEmpty(name))
                    {
                        if (name.StartsWith("php.", StringComparison.OrdinalIgnoreCase))
                        {
                            string scriptProcessor = el.GetAttributeValue("scriptProcessor") as string;
                            if (!string.IsNullOrEmpty(scriptProcessor))
                            {
                                zooPhpHandlersToRemove.Add(el);
                            }
                        }
                    }
                }

                // remove existing zoo php handlers
                foreach (ConfigurationElement element in zooPhpHandlersToRemove)
                {
                    handlerCollection.Remove(element);
                }

                // add zoo php handlers
                ConfigurationElement zooPhpX86 = handlerCollection.CreateElement();
                zooPhpX86.SetAttributeValue("name", "php.pipe#x86");
                zooPhpX86.SetAttributeValue("scriptProcessor", enabledPhpEngine);
                zooPhpX86.SetAttributeValue("path", "*.php");
                zooPhpX86.SetAttributeValue("verb", "*");
                zooPhpX86.SetAttributeValue("modules", "HeliconZoo_x86");
                zooPhpX86.SetAttributeValue("preCondition", "bitness32");
                zooPhpX86.SetAttributeValue("resourceType", "Unspecified");
                zooPhpX86.SetAttributeValue("requireAccess", "Script");
                handlerCollection.AddAt(0, zooPhpX86);

                ConfigurationElement zooPhpX64 = handlerCollection.CreateElement();
                zooPhpX64.SetAttributeValue("name", "php.pipe#x64");
                zooPhpX64.SetAttributeValue("scriptProcessor", enabledPhpEngine);
                zooPhpX64.SetAttributeValue("path", "*.php");
                zooPhpX64.SetAttributeValue("verb", "*");
                zooPhpX64.SetAttributeValue("modules", "HeliconZoo_x64");
                zooPhpX64.SetAttributeValue("preCondition", "bitness64");
                zooPhpX64.SetAttributeValue("resourceType", "Unspecified");
                zooPhpX64.SetAttributeValue("requireAccess", "Script");
                handlerCollection.AddAt(1, zooPhpX64);

                // process index.php as default document
                ConfigurationSection defaultDocument = appConfig.GetSection("system.webServer/defaultDocument", siteId);
                RegisterPhpDefaultDocument(defaultDocument);
            }
        }
        public void TestIisExpressReadOnly()
        {
            var directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            Environment.SetEnvironmentVariable("JEXUS_TEST_HOME", directoryName);

            if (directoryName == null)
            {
                return;
            }

            string Current  = Path.Combine(directoryName, @"applicationHost.config");
            string Original = Path.Combine(directoryName, @"original2.config");

            TestHelper.CopySiteConfig(directoryName, "original.config");
            File.Copy(Original, Current, true);
            TestHelper.FixPhysicalPathMono(Current);

            var message =
                "The configuration object is read only, because it has been committed by a call to ServerManager.CommitChanges(). If write access is required, use ServerManager to get a new reference.";

#if IIS
            var server = new ServerManager(true, Current);
#else
            var server = new IisExpressServerManager(true, Current);
#endif
            var exception1 = Assert.Throws <InvalidOperationException>(
                () =>
            {
                TestCases.TestIisExpress(server);
            });
            Assert.Equal(message, exception1.Message);

            // site config "Website1"
            var config = server.Sites[0].Applications[0].GetWebConfiguration();

            // enable Windows authentication
            var windowsSection = config.GetSection("system.webServer/security/authentication/windowsAuthentication");
            Assert.Equal(OverrideMode.Inherit, windowsSection.OverrideMode);
            Assert.Equal(OverrideMode.Deny, windowsSection.OverrideModeEffective);
            Assert.Equal(true, windowsSection.IsLocked);
            Assert.Equal(false, windowsSection.IsLocallyStored);

            var windowsEnabled = (bool)windowsSection["enabled"];
            Assert.False(windowsEnabled);

            var compression = config.GetSection("system.webServer/urlCompression");
            Assert.Equal(OverrideMode.Inherit, compression.OverrideMode);
            Assert.Equal(OverrideMode.Allow, compression.OverrideModeEffective);
            Assert.Equal(false, compression.IsLocked);
            Assert.Equal(false, compression.IsLocallyStored);

            Assert.Equal(true, compression["doDynamicCompression"]);

            var compress = Assert.Throws <InvalidOperationException>(() => compression["doDynamicCompression"] = false);
            Assert.Equal(message, compress.Message);

            {
                // disable default document. Saved to web.config as this section can be overridden anywhere.
                ConfigurationSection defaultDocumentSection = config.GetSection("system.webServer/defaultDocument");
                Assert.Equal(true, defaultDocumentSection["enabled"]);

                ConfigurationElementCollection filesCollection = defaultDocumentSection.GetCollection("files");
                Assert.Equal(7, filesCollection.Count);

                {
                    var first = filesCollection[0];
                    Assert.Equal("home1.html", first["value"]);
                    Assert.True(first.IsLocallyStored);
                }

                var second = filesCollection[1];
                Assert.Equal("Default.htm", second["value"]);
                Assert.False(second.IsLocallyStored);

                var third = filesCollection[2];
                Assert.Equal("Default.asp", third["value"]);
                Assert.False(third.IsLocallyStored);

                var remove = Assert.Throws <FileLoadException>(() => filesCollection.RemoveAt(4));
                Assert.Equal(
                    "Filename: \r\nError: This configuration section cannot be modified because it has been opened for read only access\r\n\r\n",
                    remove.Message);

                ConfigurationElement addElement = filesCollection.CreateElement();
                var add = Assert.Throws <InvalidOperationException>(() => filesCollection.AddAt(0, addElement));
                Assert.Equal(message, add.Message);

                Assert.Equal(7, filesCollection.Count);

                {
                    var first = filesCollection[0];
                    Assert.Equal("home1.html", first["value"]);
                    // TODO: why?
                    // Assert.IsFalse(first.IsLocallyStored);
                }

                Assert.Equal(7, filesCollection.Count);

                var clear = Assert.Throws <InvalidOperationException>(() => filesCollection.Clear());
                Assert.Equal(message, clear.Message);

                var delete = Assert.Throws <InvalidOperationException>(() => filesCollection.Delete());
                Assert.Equal(message, delete.Message);
            }
        }
Example #9
0
        public static void TestIisExpressMissingWebsiteConfig(ServerManager server)
        {
            {
                var config = server.GetApplicationHostConfiguration();

                var windowsSection =
                    config.GetSection("system.webServer/security/authentication/windowsAuthentication");
                windowsSection["enabled"] = true;
                server.CommitChanges();
            }
            {
                // server config "Website1"
                var config         = server.GetApplicationHostConfiguration();
                var windowsSection = config.GetSection("system.webServer/security/authentication/windowsAuthentication",
                                                       "WebSite1");
                windowsSection["enabled"] = false;
                {
                    // disable logging. Saved in applicationHost.config, as it cannot be overridden in web.config.
                    ConfigurationSection httpLoggingSection =
                        config.GetSection("system.webServer/httpLogging", "WebSite1");
                    httpLoggingSection["dontLog"] = true;
                }

                {
                    ConfigurationSection httpLoggingSection =
                        config.GetSection("system.webServer/httpLogging", "WebSite1/test");
                    httpLoggingSection["dontLog"] = false;
                }
            }
            {
                // site config "Website1"
                var config      = server.Sites[0].Applications[0].GetWebConfiguration();
                var compression = config.GetSection("system.webServer/urlCompression");
                compression["doDynamicCompression"] = false;
                {
                    // disable default document. Saved to web.config as this section can be overridden anywhere.
                    ConfigurationSection defaultDocumentSection = config.GetSection("system.webServer/defaultDocument");
                    Assert.Equal(true, defaultDocumentSection["enabled"]);
                    defaultDocumentSection["enabled"] = false;

                    ConfigurationElementCollection filesCollection = defaultDocumentSection.GetCollection("files");
                    Assert.Equal(6, filesCollection.Count);

                    {
                        var first = filesCollection[0];
                        Assert.Equal("Default.htm", first["value"]);
                        Assert.False(first.IsLocallyStored);
                    }

                    var second = filesCollection[1];
                    Assert.Equal("Default.asp", second["value"]);
                    Assert.False(second.IsLocallyStored);

                    var third = filesCollection[2];
                    Assert.Equal("index.htm", third["value"]);
                    Assert.False(third.IsLocallyStored);

                    ConfigurationElement addElement = filesCollection.CreateElement();
                    addElement["value"] = @"home.html";
                    filesCollection.AddAt(0, addElement);

                    Assert.Equal(7, filesCollection.Count);

                    {
                        var first = filesCollection[0];
                        Assert.Equal("home.html", first["value"]);
                        // TODO: why?
                        // Assert.False(first.IsLocallyStored);
                    }

                    filesCollection.RemoveAt(4);
                    Assert.Equal(6, filesCollection.Count);

                    ConfigurationElement lastElement = filesCollection.CreateElement();
                    lastElement["value"] = @"home.html";
                    var dup = Assert.Throws <COMException>(() => filesCollection.Add(lastElement));
#if IIS
                    Assert.Equal(
                        "Filename: \r\nError: Cannot add duplicate collection entry of type 'add' with unique key attribute 'value' set to 'home.html'\r\n\r\n",
                        dup.Message);
#else
                    Assert.Equal(
                        $"Filename: \\\\?\\{config.FileContext.FileName}\r\nLine number: 0\r\nError: Cannot add duplicate collection entry of type 'add' with unique key attribute 'value' set to 'home.html'\r\n\r\n",
                        dup.Message);
#endif
                    lastElement["value"] = @"home2.html";
                    filesCollection.Add(lastElement);
                    Assert.Equal(7, filesCollection.Count);
                }

                var errorsSection    = config.GetSection("system.webServer/httpErrors");
                var errorsCollection = errorsSection.GetCollection();
                var error            = errorsCollection.CreateElement();
                error["statusCode"]             = 500;
                error["subStatusCode"]          = 55;
                error["prefixLanguageFilePath"] = string.Empty;
                error["responseMode"]           = "File";
                error["path"] = "test.htm";
                errorsCollection.Add(error);

                var staticContent = config.GetSection("system.webServer/staticContent").GetChildElement("clientCache");
                staticContent["cacheControlMode"] = "DisableCache";

                ConfigurationSection requestFilteringSection =
                    config.GetSection("system.webServer/security/requestFiltering");
                ConfigurationElement           hiddenSegmentsElement    = requestFilteringSection.GetChildElement("hiddenSegments");
                ConfigurationElementCollection hiddenSegmentsCollection = hiddenSegmentsElement.GetCollection();
                var test = hiddenSegmentsCollection.CreateElement();
                test["segment"] = "test";
                hiddenSegmentsCollection.Add(test);
                var old = hiddenSegmentsCollection[0];
                hiddenSegmentsCollection.Remove(old);

                var section = config.GetSection("system.webServer/rewrite/rules");
                ConfigurationElementCollection collection = section.GetCollection();
                collection.Clear();
                var newElement = collection.CreateElement();
                newElement["name"] = "test";
                collection.Add(newElement);
            }

            {
                // server config "Website1"
                var config = server.GetApplicationHostConfiguration();
                // enable Windows authentication
                var windowsSection = config.GetSection("system.webServer/security/authentication/windowsAuthentication",
                                                       "WebSite1");
                var windowsEnabled = (bool)windowsSection["enabled"];
            }
            {
                Configuration config = server.GetApplicationHostConfiguration();

                var anonymousSection = config.GetSection(
                    "system.webServer/security/authentication/anonymousAuthentication",
                    "WebSite2");
                ConfigurationSection windowsAuthenticationSection =
                    config.GetSection("system.webServer/security/authentication/windowsAuthentication", "WebSite2");
                windowsAuthenticationSection["enabled"] = true;

                ConfigurationElement extendedProtectionElement =
                    windowsAuthenticationSection.GetChildElement("extendedProtection");
                extendedProtectionElement["tokenChecking"] = @"Allow";
                extendedProtectionElement["flags"]         = @"None";
                ConfigurationElementCollection extendedProtectionCollection =
                    extendedProtectionElement.GetCollection();

                ConfigurationElement spnElement = extendedProtectionCollection.CreateElement("spn");
                spnElement["name"] = @"HTTP/www.contoso.com";
                extendedProtectionCollection.Add(spnElement);

                ConfigurationElement spnElement1 = extendedProtectionCollection.CreateElement("spn");
                spnElement1["name"] = @"HTTP/contoso.com";
                extendedProtectionCollection.Add(spnElement1);

                server.CommitChanges();
            }
            // remove application pool
            Assert.False(server.ApplicationPools.AllowsRemove);
            Assert.Equal(5, server.ApplicationPools.Count);
            server.ApplicationPools.RemoveAt(4);
            Assert.Equal(4, server.ApplicationPools.Count);

            // remove binding
            server.Sites[1].Bindings.RemoveAt(1);

            // remove site
            server.Sites.RemoveAt(4);

            // remove application
            var site1 = server.Sites[9];
            site1.Applications.RemoveAt(1);

            // remove virtual directory
            var application = server.Sites[2].Applications[0];
            application.VirtualDirectories.RemoveAt(1);

            server.CommitChanges();
        }
Example #10
0
        public static void TestIisExpress(ServerManager server)
        {
            Assert.Equal(5, server.ApplicationPools.Count);
            Assert.True(server.ApplicationPools.AllowsAdd);
            Assert.False(server.ApplicationPools.AllowsClear);
            Assert.False(server.ApplicationPools.AllowsRemove);
            Assert.Equal(
                new[] { '\\', '/', '"', '|', '<', '>', ':', '*', '?', ']', '[', '+', '=', ';', ',', '@', '&' },
                ApplicationPoolCollection.InvalidApplicationPoolNameCharacters());

            Assert.Equal(12, server.Sites.Count);
            Assert.True(server.Sites.AllowsAdd);
            Assert.False(server.Sites.AllowsClear);
            Assert.False(server.Sites.AllowsRemove);
            Assert.Equal(
                new[] { '\\', '/', '?', ';', ':', '@', '&', '=', '+', '$', ',', '|', '"', '<', '>' },
                SiteCollection.InvalidSiteNameCharacters());

            var siteDefaults = server.SiteDefaults;

            //Assert.Equal("[http] :8080:localhost", server.Sites[0].Bindings[0].ToString());
            Assert.Equal("localhost on *:8080 (http)", server.Sites[0].Bindings[0].ToShortString());
            Assert.Equal("%IIS_USER_HOME%\\Logs", siteDefaults.LogFile.Directory);
            Assert.Equal(LogFormat.W3c, siteDefaults.LogFile.LogFormat);
            Assert.Equal("%IIS_USER_HOME%\\TraceLogFiles", siteDefaults.TraceFailedRequestsLogging.Directory);
            Assert.True(siteDefaults.TraceFailedRequestsLogging.Enabled);
            Assert.True(siteDefaults.LogFile.Enabled);
            Assert.Equal("Clr4IntegratedAppPool", server.ApplicationDefaults.ApplicationPoolName);

            var pool = server.ApplicationPools[0];

            var model = pool.GetChildElement("processModel");
            var item  = model["maxProcesses"];

            Assert.Equal("Clr4IntegratedAppPool", pool.Name);
            Assert.Equal("v4.0", pool.ManagedRuntimeVersion);
            Assert.Equal(1, pool.ProcessModel.MaxProcesses);
            Assert.Equal(string.Empty, pool.ProcessModel.UserName);
#if IIS
            Assert.Equal(1L, item);
#else
            Assert.Equal(1U, item);
#endif

            // TODO: why it should be int.
#if IIS
            Assert.Equal(0, pool.GetAttributeValue("managedPipelineMode"));
            pool.SetAttributeValue("managedPipelineMode", 1);
            Assert.Equal(1, pool.GetAttributeValue("managedPipelineMode"));
            pool.SetAttributeValue("managedPipelineMode", "Integrated");
            Assert.Equal(0, pool.GetAttributeValue("managedPipelineMode"));
#else
            Assert.Equal(0L, pool.GetAttributeValue("managedPipelineMode"));
            pool.SetAttributeValue("managedPipelineMode", 1);
            Assert.Equal(1L, pool.GetAttributeValue("managedPipelineMode"));
            pool.SetAttributeValue("managedPipelineMode", "Integrated");
            Assert.Equal(0L, pool.GetAttributeValue("managedPipelineMode"));

            Assert.Equal(14, pool.ApplicationCount);
#endif
            var name = Assert.Throws <COMException>(() => pool.SetAttributeValue("name", ""));
            Assert.Equal("Invalid application pool name\r\n", name.Message);

            var time = Assert.Throws <COMException>(() => pool.ProcessModel.IdleTimeout = TimeSpan.MaxValue);
            Assert.Equal("Timespan value must be between 00:00:00 and 30.00:00:00 seconds inclusive, with a granularity of 60 seconds\r\n", time.Message);

            var site = server.Sites[0];
            Assert.Equal("WebSite1", site.Name);
            Assert.Equal(14, site.Bindings.Count);
            {
                var binding = site.Bindings[0];
                Assert.Equal(IPAddress.Any, binding.EndPoint.Address);
                Assert.Equal(8080, binding.EndPoint.Port);
                Assert.Equal("localhost", binding.Host);
                Assert.Equal("*:8080:localhost", binding.ToString());
                Assert.Equal(":8080:localhost", binding.BindingInformation);
            }
            {
                var siteBinding = site.Bindings[1];
                Assert.Null(siteBinding.EndPoint);
                Assert.Equal(string.Empty, siteBinding.Host);
                Assert.False(siteBinding.IsIPPortHostBinding);
                Assert.False(siteBinding.UseDsMapper);
                Assert.Null(siteBinding.CertificateHash);
                Assert.Null(siteBinding.CertificateStoreName);
                Assert.Equal("808:* (net.tcp)", siteBinding.ToShortString());
            }
            {
                var siteBinding = site.Bindings[2];
                Assert.Null(siteBinding.EndPoint);
                Assert.Equal(string.Empty, siteBinding.Host);
                Assert.False(siteBinding.IsIPPortHostBinding);
                Assert.False(siteBinding.UseDsMapper);
                Assert.Null(siteBinding.CertificateHash);
                Assert.Null(siteBinding.CertificateStoreName);
                Assert.Equal("localhost (net.msmq)", siteBinding.ToShortString());
            }
            {
                var siteBinding = site.Bindings[3];
                Assert.Null(siteBinding.EndPoint);
                Assert.Equal(string.Empty, siteBinding.Host);
                Assert.False(siteBinding.IsIPPortHostBinding);
                Assert.False(siteBinding.UseDsMapper);
                Assert.Null(siteBinding.CertificateHash);
                Assert.Null(siteBinding.CertificateStoreName);
                Assert.Equal("localhost (msmq.formatname)", siteBinding.ToShortString());
            }
            {
                var siteBinding = site.Bindings[4];
                Assert.Null(siteBinding.EndPoint);
                Assert.Equal(string.Empty, siteBinding.Host);
                Assert.False(siteBinding.IsIPPortHostBinding);
                Assert.False(siteBinding.UseDsMapper);
                Assert.Null(siteBinding.CertificateHash);
                Assert.Null(siteBinding.CertificateStoreName);
                Assert.Equal("* (net.pipe)", siteBinding.ToShortString());
            }
            {
                var siteBinding = site.Bindings[5];
                Assert.Null(siteBinding.EndPoint);
                Assert.Equal(string.Empty, siteBinding.Host);
                Assert.False(siteBinding.IsIPPortHostBinding);
                Assert.False(siteBinding.UseDsMapper);
                Assert.Null(siteBinding.CertificateHash);
                Assert.Null(siteBinding.CertificateStoreName);
                Assert.Equal("*:21: (ftp)", siteBinding.ToShortString());
            }
            {
                var siteBinding = site.Bindings[6];
                Assert.Equal("* on *:8080 (http)", siteBinding.ToShortString());
                Assert.Equal("0.0.0.0:8080", siteBinding.EndPoint.ToString());
                Assert.Equal("*", siteBinding.Host);
            }
            {
                var siteBinding = site.Bindings[7];
                Assert.Equal("localhost on *:443 (https)", siteBinding.ToShortString());
                Assert.Equal("0.0.0.0:443", siteBinding.EndPoint.ToString());
                Assert.Equal("localhost", siteBinding.Host);
            }
            {
                var siteBinding = site.Bindings[8];
                Assert.Equal("* on *:44300 (https)", siteBinding.ToShortString());
                Assert.Equal("0.0.0.0:44300", siteBinding.EndPoint.ToString());
                Assert.Equal("*", siteBinding.Host);
            }
            {
                var siteBinding = site.Bindings[9];
                Assert.Null(siteBinding.EndPoint);
                Assert.Equal(string.Empty, siteBinding.Host);
                Assert.False(siteBinding.IsIPPortHostBinding);
                Assert.False(siteBinding.UseDsMapper);
                Assert.Null(siteBinding.CertificateHash);
                Assert.Null(siteBinding.CertificateStoreName);
                Assert.Equal("*:210:localhost (ftp)", siteBinding.ToShortString());
            }
            {
                var binding = site.Bindings[10];
                Assert.Null(binding.EndPoint);
                Assert.Equal(string.Empty, binding.Host);
                Assert.False(binding.IsIPPortHostBinding);
                Assert.False(binding.UseDsMapper);
                Assert.Null(binding.CertificateHash);
                Assert.Null(binding.CertificateStoreName);
                Assert.Equal("* (net.tcp)", binding.ToShortString());
            }
            {
                var binding = site.Bindings[11];
                Assert.Null(binding.EndPoint);
                Assert.Equal(string.Empty, binding.Host);
                Assert.False(binding.IsIPPortHostBinding);
                Assert.False(binding.UseDsMapper);
                Assert.Null(binding.CertificateHash);
                Assert.Null(binding.CertificateStoreName);
                Assert.Equal("* (net.msmq)", binding.ToShortString());
            }
            {
                var siteBinding = site.Bindings[12];
                Assert.Null(siteBinding.EndPoint);
                Assert.Equal(string.Empty, siteBinding.Host);
                Assert.False(siteBinding.IsIPPortHostBinding);
                Assert.False(siteBinding.UseDsMapper);
                Assert.Null(siteBinding.CertificateHash);
                Assert.Null(siteBinding.CertificateStoreName);
                Assert.Equal("* (msmq.formatname)", siteBinding.ToShortString());
            }
            {
                var binding = site.Bindings[13];
                Assert.Null(binding.EndPoint);
                Assert.Equal(string.Empty, binding.Host);
                Assert.False(binding.IsIPPortHostBinding);
                Assert.False(binding.UseDsMapper);
                Assert.Null(binding.CertificateHash);
                Assert.Null(binding.CertificateStoreName);
                Assert.Equal("localhost (net.pipe)", binding.ToShortString());
            }

            Assert.True(site.Bindings.AllowsAdd);
            Assert.True(site.Bindings.AllowsClear);
            Assert.False(site.Bindings.AllowsRemove);
            Assert.Equal("%IIS_USER_HOME%\\Logs", site.LogFile.Directory);

            var sslSite              = server.Sites[1];
            var sslBinding           = sslSite.Bindings[1];
            var certificateHash      = sslBinding.CertificateHash;
            var certificateStoreName = sslBinding.CertificateStoreName;
            Assert.Equal(SslFlags.Sni, sslBinding.SslFlags);

            sslSite.Bindings.RemoveAt(1);
            sslSite.Bindings.Add(":443:localhost", "https");
            sslBinding = sslSite.Bindings[1];
            Assert.Equal(SslFlags.None, sslBinding.SslFlags);

            sslSite.Bindings.RemoveAt(1);
            sslSite.Bindings.Add(":443:localhost", certificateHash, certificateStoreName, SslFlags.Sni);
            sslBinding = sslSite.Bindings[1];
            Assert.Equal(SslFlags.Sni, sslBinding.SslFlags);

            sslSite.Bindings.RemoveAt(1);
            sslSite.Bindings.Add(":443:localhost", certificateHash, certificateStoreName);
            sslBinding = sslSite.Bindings[1];
            Assert.Equal(SslFlags.None, sslBinding.SslFlags);

            {
                sslBinding = sslSite.Bindings.CreateElement();
                var exception = Assert.Throws <FileNotFoundException>(() => sslSite.Bindings.Add(sslBinding));
                Assert.Equal("Filename: \r\nError: Element is missing required attributes protocol,bindingInformation\r\n\r\n", exception.Message);
            }

            var app = site.Applications[0];
            Assert.True(site.Applications.AllowsAdd);
            Assert.False(site.Applications.AllowsClear);
            Assert.False(site.Applications.AllowsRemove);
            Assert.Equal(
                new[] { '\\', '?', ';', ':', '@', '&', '=', '+', '$', ',', '|', '"', '<', '>', '*' },
                ApplicationCollection.InvalidApplicationPathCharacters());
            Assert.Equal("Clr4IntegratedAppPool", app.ApplicationPoolName);

            Assert.Equal("/", app.Path);
            var vDir = app.VirtualDirectories[0];
            Assert.True(app.VirtualDirectories.AllowsAdd);
            Assert.False(app.VirtualDirectories.AllowsClear);
            Assert.False(app.VirtualDirectories.AllowsRemove);
            Assert.Equal(
                new[] { '\\', '?', ';', ':', '@', '&', '=', '+', '$', ',', '|', '"', '<', '>', '*' },
                VirtualDirectoryCollection.InvalidVirtualDirectoryPathCharacters());

            Assert.Equal(Helper.IsRunningOnMono() ? "%JEXUS_TEST_HOME%/WebSite1" : "%JEXUS_TEST_HOME%\\WebSite1", vDir.PhysicalPath);

            {
                var config  = server.GetApplicationHostConfiguration();
                var section = config.GetSection("system.applicationHost/log");
                var mode    = section.Attributes["centralLogFileMode"];
#if IIS
                Assert.Equal(0, mode.Value);
#else
                Assert.Equal(0L, mode.Value);
#endif
                var encoding = section.Attributes["logInUTF8"];
                Assert.Equal(true, encoding.Value);
                ConfigurationSection httpLoggingSection = config.GetSection("system.webServer/httpLogging");
                Assert.Equal(false, httpLoggingSection["dontLog"]);

                ConfigurationSection defaultDocumentSection = config.GetSection("system.webServer/defaultDocument");
                Assert.Equal(true, defaultDocumentSection["enabled"]);
                ConfigurationElementCollection filesCollection = defaultDocumentSection.GetCollection("files");
                Assert.Equal(6, filesCollection.Count);

                var errorsSection    = config.GetSection("system.webServer/httpErrors");
                var errorsCollection = errorsSection.GetCollection();
                Assert.Equal(9, errorsCollection.Count);

                var anonymousSection = config.GetSection("system.webServer/security/authentication/anonymousAuthentication");
                var anonymousEnabled = (bool)anonymousSection["enabled"];
                Assert.True(anonymousEnabled);
                var value = anonymousSection["password"];
                Assert.Equal(string.Empty, value);

                var windowsSection = config.GetSection("system.webServer/security/authentication/windowsAuthentication");
                var windowsEnabled = (bool)windowsSection["enabled"];
                Assert.False(windowsEnabled);

                windowsSection["enabled"] = true;
                server.CommitChanges();
            }

            {
                var config  = server.GetApplicationHostConfiguration();
                var asp     = config.GetSection("system.webServer/asp");
                var comPlus = asp.ChildElements["comPlus"];
                var sxsName = comPlus.GetAttribute("sxsName");
                sxsName.Delete();
                Assert.Equal("", (string)sxsName.Value);

                comPlus["sxsName"] = "test";
                server.CommitChanges();
            }

            {
                var config  = server.GetApplicationHostConfiguration();
                var asp     = config.GetSection("system.webServer/asp");
                var comPlus = asp.ChildElements["comPlus"];
                var sxsName = (string)comPlus["sxsName"];
                Assert.Equal("test", sxsName);

                var exception = Assert.Throws <COMException>(() => comPlus["sxsName"] = string.Empty);
                Assert.Equal("String must not be empty\r\n", exception.Message);
                server.CommitChanges();
            }

            {
                var config  = server.GetApplicationHostConfiguration();
                var asp     = config.GetSection("system.webServer/asp");
                var comPlus = asp.ChildElements["comPlus"];
                var sxsName = (string)comPlus["sxsName"];
                Assert.Equal("test", sxsName);

                comPlus.GetAttribute("sxsName").Delete();
                server.CommitChanges();

                sxsName = (string)comPlus.GetAttribute("sxsName").Value;
                Assert.Equal("", sxsName);
            }

            {
                var config    = server.GetApplicationHostConfiguration();
                var locations = config.GetLocationPaths();
                Assert.Equal(3, locations.Length);

                var exception =
                    Assert.Throws <FileNotFoundException>(
                        () =>
                        config.GetSection(
                            "system.webServer/security/authentication/anonymousAuthentication",
                            "Default Web Site"));
                Assert.Equal(
                    "Filename: \r\nError: Unrecognized configuration path 'MACHINE/WEBROOT/APPHOST/Default Web Site'\r\n\r\n",
                    exception.Message);
                Assert.Null(exception.FileName);

                var anonymousSection = config.GetSection(
                    "system.webServer/security/authentication/anonymousAuthentication",
                    "WebSite2");
                var anonymousEnabled = (bool)anonymousSection["enabled"];
                Assert.True(anonymousEnabled);
                Assert.Equal("test", anonymousSection["userName"]);

                // Assert.Equal("123456", anonymousSection["password"]);
            }

            {
                // server config "Website1"
                var config = server.GetApplicationHostConfiguration();

                // enable Windows authentication
                var windowsSection = config.GetSection("system.webServer/security/authentication/windowsAuthentication", "WebSite1");
                Assert.Equal(OverrideMode.Inherit, windowsSection.OverrideMode);
                Assert.Equal(OverrideMode.Deny, windowsSection.OverrideModeEffective);
                Assert.Equal(false, windowsSection.IsLocked);
                Assert.True(windowsSection.IsLocallyStored);

                var windowsEnabled = (bool)windowsSection["enabled"];
                Assert.True(windowsEnabled);
                windowsSection["enabled"] = false;
                Assert.Equal(false, windowsSection["enabled"]);

                {
                    // disable logging. Saved in applicationHost.config, as it cannot be overridden in web.config.
                    ConfigurationSection httpLoggingSection = config.GetSection("system.webServer/httpLogging", "WebSite1");
                    Assert.Equal(false, httpLoggingSection["dontLog"]);
                    httpLoggingSection["dontLog"] = true;
                }

                {
                    ConfigurationSection httpLoggingSection = config.GetSection("system.webServer/httpLogging", "WebSite1/test");
                    // TODO:
                    // Assert.Equal(true, httpLoggingSection["dontLog"]);
                    httpLoggingSection["dontLog"] = false;
                }
            }

            var siteName = Assert.Throws <COMException>(() => server.Sites[0].Name = "");
            Assert.Equal("Invalid site name\r\n", siteName.Message);

            var limit = Assert.Throws <COMException>(() => server.Sites[0].Limits.MaxBandwidth = 12);
            Assert.Equal("Integer value must not be between 0 and 1023 inclusive\r\n", limit.Message);

            var appPath = Assert.Throws <COMException>(() => server.Sites[0].Applications[0].Path = "");
            Assert.Equal("Invalid application path\r\n", appPath.Message);

            var vDirPath =
                Assert.Throws <COMException>(() => server.Sites[0].Applications[0].VirtualDirectories[0].Path = "");
            Assert.Equal("Invalid virtual directory path\r\n", vDirPath.Message);

            {
                // site config "Website1"
                var config = server.Sites[0].Applications[0].GetWebConfiguration();

                // enable Windows authentication
                var windowsSection = config.GetSection("system.webServer/security/authentication/windowsAuthentication");
                Assert.Equal(OverrideMode.Inherit, windowsSection.OverrideMode);
                Assert.Equal(OverrideMode.Deny, windowsSection.OverrideModeEffective);
                Assert.True(windowsSection.IsLocked);
                Assert.Equal(false, windowsSection.IsLocallyStored);

                var windowsEnabled = (bool)windowsSection["enabled"];
                Assert.True(windowsEnabled);
                var exception = Assert.Throws <FileLoadException>(() => windowsSection["enabled"] = false);
                Assert.Equal(
                    "This configuration section cannot be used at this path. This happens when the section is locked at a parent level. Locking is either by default (overrideModeDefault=\"Deny\"), or set explicitly by a location tag with overrideMode=\"Deny\" or the legacy allowOverride=\"false\".\r\n",
                    exception.Message);
                Assert.Null(exception.FileName);

                var compression = config.GetSection("system.webServer/urlCompression");
                Assert.Equal(OverrideMode.Inherit, compression.OverrideMode);
                Assert.Equal(OverrideMode.Allow, compression.OverrideModeEffective);
                Assert.Equal(false, compression.IsLocked);
                Assert.Equal(false, compression.IsLocallyStored);

                Assert.Equal(true, compression["doDynamicCompression"]);

                compression["doDynamicCompression"] = false;

                {
                    // disable default document. Saved to web.config as this section can be overridden anywhere.
                    ConfigurationSection defaultDocumentSection = config.GetSection("system.webServer/defaultDocument");
                    Assert.Equal(true, defaultDocumentSection["enabled"]);
                    defaultDocumentSection["enabled"] = false;

                    ConfigurationElementCollection filesCollection = defaultDocumentSection.GetCollection("files");
                    Assert.Equal(7, filesCollection.Count);

                    {
                        var first = filesCollection[0];
                        Assert.Equal("home1.html", first["value"]);
                        Assert.True(first.IsLocallyStored);
                    }

                    var second = filesCollection[1];
                    Assert.Equal("Default.htm", second["value"]);
                    Assert.False(second.IsLocallyStored);

                    var third = filesCollection[2];
                    Assert.Equal("Default.asp", third["value"]);
                    Assert.False(third.IsLocallyStored);

                    ConfigurationElement addElement = filesCollection.CreateElement();
                    addElement["value"] = @"home.html";
                    filesCollection.AddAt(0, addElement);

                    Assert.Equal(8, filesCollection.Count);

                    {
                        var first = filesCollection[0];
                        Assert.Equal("home.html", first["value"]);
                        // TODO: why?
                        // Assert.False(first.IsLocallyStored);
                    }

                    filesCollection.RemoveAt(4);
                    Assert.Equal(7, filesCollection.Count);

                    ConfigurationElement lastElement = filesCollection.CreateElement();
                    lastElement["value"] = @"home1.html";
                    lastElement["value"] = @"home2.html";
                    filesCollection.Add(lastElement);
                    Assert.Equal(8, filesCollection.Count);
                }

                //{
                //    var last = filesCollection[8];
                //    Assert.Equal("home2.html", last["value"]);
                //    // TODO: why?
                //    Assert.False(last.IsLocallyStored);
                //}

                {
                    // disable logging. Saved in applicationHost.config, as it cannot be overridden in web.config.
                    ConfigurationSection httpLoggingSection = config.GetSection("system.webServer/httpLogging");
                    Assert.Equal(false, httpLoggingSection["dontLog"]);
                    Assert.Throws <FileLoadException>(() => httpLoggingSection["dontLog"] = true);
                }
                {
                    ConfigurationSection httpLoggingSection = config.GetSection(
                        "system.webServer/httpLogging",
                        "WebSite1/test");
                    // TODO:
                    //Assert.Equal(true, httpLoggingSection["dontLog"]);
                    Assert.Throws <FileLoadException>(() => httpLoggingSection["dontLog"] = false);
                }

                var errorsSection = config.GetSection("system.webServer/httpErrors");
                Assert.Equal(OverrideMode.Inherit, errorsSection.OverrideMode);
                Assert.Equal(OverrideMode.Allow, errorsSection.OverrideModeEffective);
                Assert.Equal(false, errorsSection.IsLocked);
                Assert.Equal(false, errorsSection.IsLocallyStored);

                var errorsCollection = errorsSection.GetCollection();
                Assert.Equal(9, errorsCollection.Count);

                var error = errorsCollection.CreateElement();
                var cast  = Assert.Throws <InvalidCastException>(() => error.SetAttributeValue("statusCode", "500"));
#if IIS
                Assert.Equal(Helper.IsRunningOnMono() ? "Cannot cast from source type to destination type." : "Specified cast is not valid.", cast.Message);
#else
                Assert.Equal(Helper.IsRunningOnMono() ? "Cannot cast from source type to destination type." : "Cannot convert 500 of System.String to uint.", cast.Message);
#endif

                var ex2 = Assert.Throws <COMException>(() => error["statusCode"] = 90000);
                Assert.Equal("Integer value must be between 400 and 999 inclusive\r\n", ex2.Message);

                error["statusCode"]             = 500;
                error["subStatusCode"]          = 55;
                error["prefixLanguageFilePath"] = string.Empty;

                error["responseMode"] = 0;
                error["responseMode"] = ResponseMode.Test;
#if IIS
                Assert.Equal(1, error["responseMode"]);
#else
                Assert.Equal(1L, error["responseMode"]);
#endif

                error["responseMode"] = "File";
                var ex1 = Assert.Throws <FileNotFoundException>(() => errorsCollection.Add(error));
                Assert.Equal("Filename: \r\nError: Element is missing required attributes path\r\n\r\n", ex1.Message);
                Assert.Null(ex1.FileName);

                var ex = Assert.Throws <COMException>(() => error["path"] = "");
                Assert.Equal("String must not be empty\r\n", ex.Message);

                error["path"] = "test.htm";
                errorsCollection.Add(error);

                var staticContent = config.GetSection("system.webServer/staticContent").GetChildElement("clientCache");
                staticContent["cacheControlMode"] = "DisableCache";

                ConfigurationSection requestFilteringSection =
                    config.GetSection("system.webServer/security/requestFiltering");
                ConfigurationElement           hiddenSegmentsElement    = requestFilteringSection.GetChildElement("hiddenSegments");
                ConfigurationElementCollection hiddenSegmentsCollection = hiddenSegmentsElement.GetCollection();
                Assert.Equal(8, hiddenSegmentsCollection.Count);

                var test = hiddenSegmentsCollection.CreateElement();
                test["segment"] = "test";
                hiddenSegmentsCollection.Add(test);

                var old = hiddenSegmentsCollection[0];
                hiddenSegmentsCollection.Remove(old);

                var section = config.GetSection("system.webServer/rewrite/rules");
                ConfigurationElementCollection collection = section.GetCollection();
                //collection.Clear();
                ////collection.Delete();

                //collection = section.GetCollection();
                //Assert.Equal(0, collection.Count);

                var newElement = collection.CreateElement();
                newElement["name"] = "test";
                collection.Add(newElement);
                Assert.Equal(2, collection.Count);

                collection.Clear();
                Assert.Empty(collection);

                newElement         = collection.CreateElement();
                newElement["name"] = "test";
                collection.Add(newElement);
                Assert.Single(collection);
            }

            {
                // server config "Website1"
                var config = server.GetApplicationHostConfiguration();

                // enable Windows authentication
                var windowsSection = config.GetSection("system.webServer/security/authentication/windowsAuthentication", "WebSite1");
                Assert.Equal(OverrideMode.Inherit, windowsSection.OverrideMode);
                Assert.Equal(OverrideMode.Deny, windowsSection.OverrideModeEffective);
                Assert.Equal(false, windowsSection.IsLocked);
                Assert.True(windowsSection.IsLocallyStored);

                var windowsEnabled = (bool)windowsSection["enabled"];
                Assert.False(windowsEnabled);
            }

            {
                Configuration config = server.GetApplicationHostConfiguration();

                var anonymousSection = config.GetSection(
                    "system.webServer/security/authentication/anonymousAuthentication",
                    "WebSite2");

                // anonymousSection["userName"] = "******";
                // anonymousSection["password"] = "******";
                ConfigurationSection windowsAuthenticationSection =
                    config.GetSection("system.webServer/security/authentication/windowsAuthentication", "WebSite2");
                windowsAuthenticationSection["enabled"] = true;

                ConfigurationElement extendedProtectionElement =
                    windowsAuthenticationSection.GetChildElement("extendedProtection");
                extendedProtectionElement["tokenChecking"] = @"Allow";
                extendedProtectionElement["flags"]         = @"None";

                var exception = Assert.Throws <COMException>(() => extendedProtectionElement["tokenChecking"] = @"NotExist");
                Assert.Equal("Enum must be one of None, Allow, Require\r\n", exception.Message);

                exception = Assert.Throws <COMException>(() => extendedProtectionElement["flags"] = @"NotExist");
                Assert.Equal("Flags must be some combination of None, Proxy, NoServiceNameCheck, AllowDotlessSpn, ProxyCohosting\r\n", exception.Message);

                ConfigurationElementCollection extendedProtectionCollection = extendedProtectionElement.GetCollection();

                ConfigurationElement spnElement = extendedProtectionCollection.CreateElement("spn");
                spnElement["name"] = @"HTTP/www.contoso.com";
                extendedProtectionCollection.Add(spnElement);

                ConfigurationElement spnElement1 = extendedProtectionCollection.CreateElement("spn");
                spnElement1["name"] = @"HTTP/contoso.com";
                extendedProtectionCollection.Add(spnElement1);

                server.CommitChanges();

                ConfigurationSection           rulesSection    = config.GetSection("system.webServer/rewrite/rules");
                ConfigurationElementCollection rulesCollection = rulesSection.GetCollection();
                Assert.Single(rulesCollection);

                ConfigurationElement ruleElement = rulesCollection[0];
                Assert.Equal("lextudio2", ruleElement["name"]);
#if IIS
                Assert.Equal(0, ruleElement["patternSyntax"]);
#else
                Assert.Equal(0L, ruleElement["patternSyntax"]);
#endif
                Assert.Equal(true, ruleElement["stopProcessing"]);

                ConfigurationElement matchElement = ruleElement.GetChildElement("match");
                Assert.Equal(@"(.*)", matchElement["url"]);

                ConfigurationElement actionElement = ruleElement.GetChildElement("action");
#if IIS
                Assert.Equal(1, actionElement["type"]);
#else
                Assert.Equal(1L, actionElement["type"]);
#endif
                Assert.Equal("/www/{R:0}", actionElement["url"]);
            }

            // remove application pool
            Assert.False(server.ApplicationPools.AllowsRemove);
            Assert.Equal(5, server.ApplicationPools.Count);
            server.ApplicationPools.RemoveAt(4);
            Assert.Equal(4, server.ApplicationPools.Count);

            // remove binding
            server.Sites[1].Bindings.RemoveAt(1);

            // remove site
            server.Sites.RemoveAt(4);

            // remove application
            var site1 = server.Sites[9];
            site1.Applications.RemoveAt(1);

            // remove virtual directory
            var application = server.Sites[2].Applications[0];
            application.VirtualDirectories.RemoveAt(1);

            server.CommitChanges();
        }
        private bool ConfigureHandler(ServerManager mgr, string siteName, string virtualPath, string physicalPath, string isapiFileName, ModeType mode)
        {
            Site ste = mgr.Sites[siteName];

            if (ste == null)
            {
                if (mode == ModeType.Undeploy)
                {
                    base.Log.LogWarning("Cannot find IIS site '" + siteName + "'.");
                    return(true);
                }
                else
                {
                    base.Log.LogError("Cannot find IIS site '" + siteName + "'.");
                    return(false);
                }
            }

            Application app = ste.Applications[virtualPath];

            if (app == null)
            {
                if (mode == ModeType.Undeploy)
                {
                    base.Log.LogWarning("Cannot find IIS application '" + virtualPath + "'.");
                    return(true);
                }
                else
                {
                    base.Log.LogError("Cannot find IIS application '" + virtualPath + "'.");
                    return(false);
                }
            }

            Configuration config = app.GetWebConfiguration();

            ConfigurationSection           handlersSection    = config.GetSection("system.webServer/handlers");
            ConfigurationElementCollection handlersCollection = handlersSection.GetCollection();

            ConfigurationElement addElement =
                handlersCollection.FirstOrDefault(elem => string.Compare(elem.Attributes["scriptProcessor"].Value.ToString(), physicalPath, true) == 0);

            if (mode == ModeType.Deploy)
            {
                base.Log.LogMessage("Adding handler mapping '{0}'...", physicalPath);
                if (addElement == null)
                {
                    addElement                    = handlersCollection.CreateElement("add");
                    addElement["name"]            = isapiFileName;
                    addElement["path"]            = isapiFileName;
                    addElement["verb"]            = "*";
                    addElement["modules"]         = "IsapiModule";
                    addElement["scriptProcessor"] = physicalPath;
                    handlersCollection.Clear();
                    handlersCollection.AddAt(0, addElement);
                }
                else
                {
                    addElement["name"]            = isapiFileName;
                    addElement["path"]            = isapiFileName;
                    addElement["verb"]            = "*";
                    addElement["modules"]         = "IsapiModule";
                    addElement["scriptProcessor"] = physicalPath;
                }
                mgr.CommitChanges();
                base.Log.LogMessage("Added handler mapping '{0}'.", physicalPath);
            }
            else if (mode == ModeType.Undeploy && addElement != null)
            {
                base.Log.LogMessage("Removing handler mapping '{0}'...", physicalPath);
                handlersCollection.Remove(addElement);
                mgr.CommitChanges();
                base.Log.LogMessage("Removed handler mapping '{0}'...", physicalPath);
            }

            return(true);
        }