public void UseTransactionManipulateSite() { using (HttpClient client = ApiHttpClient.Create()) { // Ensure a site with the name of the transaction test site does not exist. Sites.EnsureNoSite(client, TRANSACTION_SITE_NAME); // Create the site we will be manipulating to test transactions JObject site = Sites.CreateSite(client, TRANSACTION_SITE_NAME, 50000, Sites.TEST_SITE_PATH); Assert.NotNull(site); // Cache the value of the property we will be manipulating through a transaciton bool cachedAutoStart = site.Value <bool>("server_auto_start"); // Create a transaction string res = null; Assert.True(client.Post(TRANSACTIONS_URL, "{}", out res)); JObject transaction = JsonConvert.DeserializeObject <JObject>(res); // Create a request to manipulate the test site HttpRequestMessage req = new HttpRequestMessage(new HttpMethod("PATCH"), Utils.Self(site)); // Add the transaction header to specify that we want to utilize the transaction in our patch request req.Headers.Add(TRANSACTION_HEADER, transaction.Value <string>("id")); site["server_auto_start"] = !site.Value <bool>("server_auto_start"); req.Content = new StringContent(JsonConvert.SerializeObject(site), Encoding.UTF8, "application/json"); // Patch the test site using a transaction var response = client.SendAsync(req).Result; Assert.True(Globals.Success(response)); site = JsonConvert.DeserializeObject <JObject>(response.Content.ReadAsStringAsync().Result); // Check the value of the server auto start property of the test site after manipulating it through transaction bool transactionAutoStart = site.Value <bool>("server_auto_start"); // Value should be different than the original value that we cached Assert.True(transactionAutoStart != cachedAutoStart); // Get the site without specifying the transaction, which means it should look the same as the original. Assert.True(client.Get(Utils.Self(site), out res)); site = JsonConvert.DeserializeObject <JObject>(res); bool nonTransactionAutoStart = site.Value <bool>("server_auto_start"); // Value should be the same as original value that we cached Assert.True(nonTransactionAutoStart == cachedAutoStart); // Create a request to commit the transaction req = new HttpRequestMessage(new HttpMethod("PATCH"), Utils.Self(transaction)); // Specify the current transaction in the headers req.Headers.Add(TRANSACTION_HEADER, transaction.Value <string>("id")); req.Content = new StringContent(JsonConvert.SerializeObject(new { state = "committed" }), Encoding.UTF8, "application/json"); // Patch the transaction to commit it response = client.SendAsync(req).Result; Assert.True(Globals.Success(response)); // Get the transactions for the webserver Assert.True(client.Get(TRANSACTIONS_URL, out res)); JArray transactions = JsonConvert.DeserializeObject <JObject>(res).Value <JArray>("transactions"); // There should be no transactions after we commit ours Assert.True(transactions.Count == 0); // Get the site after committing the transaction so the server auto start should retain the manipulated value Assert.True(client.Get(Utils.Self(site), out res)); site = JsonConvert.DeserializeObject <JObject>(res); bool commitedAutoStart = site.Value <bool>("server_auto_start"); // Value should be different than the original value that we cached Assert.True(commitedAutoStart != cachedAutoStart); // Remove the test site we created Sites.EnsureNoSite(client, TRANSACTION_SITE_NAME); } }
public async Task WebSite() { const string name = SiteName + "z"; using (HttpClient client = ApiHttpClient.Create()) { JObject pool = ApplicationPools.GetAppPool(client, name); if (pool == null) { pool = ApplicationPools.CreateAppPool(client, name); } JObject site = Sites.GetSite(client, name); if (site == null) { site = Sites.CreateSite(client, name, Utils.GetAvailablePort(), SitePath, true, pool); } int port = site["bindings"].ToObject <IEnumerable <JObject> >().First().Value <int>("port"); try { using (var stresser = new SiteStresser($"http://localhost:{port}")) using (var serverMonitor = new ServerMonitor(Utils.GetLink(site, "monitoring"))) { int tries = 0; JObject snapshot = null; while (tries < 15) { snapshot = serverMonitor.Current; if (snapshot != null && serverMonitor.Current["requests"].Value <long>("per_sec") > 0 && snapshot["network"].Value <long>("total_bytes_sent") > 0) { break; } await Task.Delay(1000); tries++; } Assert.True(snapshot["requests"].Value <long>("per_sec") > 0); Assert.True(snapshot["network"].Value <long>("total_bytes_sent") > 0); Assert.True(snapshot["network"].Value <long>("total_bytes_recv") > 0); Assert.True(snapshot["network"].Value <long>("total_connection_attempts") > 0); Assert.True(snapshot["requests"].Value <long>("total") > 0); Assert.True(snapshot["memory"].Value <long>("private_working_set") > 0); Assert.True(snapshot["memory"].Value <long>("system_in_use") > 0); Assert.True(snapshot["memory"].Value <long>("installed") > 0); Assert.True(snapshot["cpu"].Value <long>("threads") > 0); Assert.True(snapshot["cpu"].Value <long>("processes") > 0); Assert.True(serverMonitor.ErrorCount == 0); } } finally { client.Delete(Utils.Self(site)); client.Delete(Utils.Self(pool)); } } }
public async Task HandleRestartIis() { using (HttpClient client = ApiHttpClient.Create()) { Sites.EnsureNoSite(client, SiteName); int port = Utils.GetAvailablePort(); JObject site = Sites.CreateSite(client, SiteName, port, SitePath); try { using (var stresser = new SiteStresser($"http://localhost:{port}")) using (var serverMonitor = new ServerMonitor()) using (var sc = new ServiceController("W3SVC")) { JObject snapshot = await serverMonitor.GetSnapshot(5000); _output.WriteLine("Validating server is running worker processes"); _output.WriteLine(snapshot.ToString(Formatting.Indented)); Assert.True(snapshot["cpu"].Value <long>("processes") > 0); _output.WriteLine("Restarting IIS"); sc.Stop(); DateTime stopTime = DateTime.Now; var timeout = TimeSpan.FromSeconds(5); while (DateTime.Now - stopTime < timeout && sc.Status != ServiceControllerStatus.Stopped) { await Task.Delay(1000); } sc.Start(); Assert.True(serverMonitor.ErrorCount == 0); int tries = 0; while (tries < 5) { snapshot = serverMonitor.Current; _output.WriteLine("checking for requests / sec counter increase after startup"); _output.WriteLine(snapshot.ToString(Formatting.Indented)); if (snapshot["requests"].Value <long>("per_sec") > 0) { break; } await Task.Delay(1000); tries++; } Assert.True(snapshot["requests"].Value <long>("per_sec") > 0); Assert.True(serverMonitor.ErrorCount == 0); } } finally { client.Delete(Utils.Self(site)); } } }
public static bool DeleteFile(HttpClient client, JObject file) { return(client.Delete(Utils.Self(file))); }
public async Task ManySites(int numberSites) { HttpClient client = null; SiteStresser[] stressers = new SiteStresser[numberSites]; ServerMonitor serverMonitor = null; var pools = new JObject[numberSites]; var sites = new JObject[numberSites]; try { client = ApiHttpClient.Create(); for (int i = 0; i < numberSites; i++) { string name = SiteName + i; var pool = ApplicationPools.GetAppPool(client, name); if (pool == null) { pool = ApplicationPools.CreateAppPool(client, name); } pools[i] = pool; } serverMonitor = new ServerMonitor(); for (int i = 0; i < numberSites; i++) { string name = SiteName + i; JObject site = Sites.GetSite(client, name); if (site == null) { site = Sites.CreateSite(client, name, Utils.GetAvailablePort(), SitePath, true, pools[i]); } sites[i] = site; int port = site["bindings"].ToObject <IEnumerable <JObject> >().First().Value <int>("port"); stressers[i] = new SiteStresser($"http://localhost:{port}"); } await Task.Delay(1000); var start = DateTime.Now; var timeout = TimeSpan.FromSeconds(20); _output.WriteLine($"Created {numberSites} sites"); _output.WriteLine($"Waiting for all site processes to start"); while (DateTime.Now - start <= timeout && (serverMonitor.Current["cpu"].Value <long>("processes") < numberSites || serverMonitor.Current["network"].Value <long>("total_bytes_sent") == 0)) { await Task.Delay(1000); } if (DateTime.Now - start > timeout) { throw new Exception("timeout"); } JObject snapshot = serverMonitor.Current; _output.WriteLine("Validating webserver monitoring data"); _output.WriteLine(snapshot.ToString(Formatting.Indented)); Assert.True(snapshot["network"].Value <long>("total_bytes_sent") > 0); Assert.True(snapshot["network"].Value <long>("total_bytes_recv") > 0); Assert.True(snapshot["network"].Value <long>("total_connection_attempts") > 0); Assert.True(snapshot["requests"].Value <long>("total") > 0); Assert.True(snapshot["memory"].Value <long>("private_working_set") > 0); Assert.True(snapshot["memory"].Value <long>("system_in_use") > 0); Assert.True(snapshot["memory"].Value <long>("installed") > 0); Assert.True(snapshot["cpu"].Value <long>("threads") > 0); Assert.True(snapshot["cpu"].Value <long>("processes") > 0); Assert.True(snapshot["cpu"].Value <long>("percent_usage") >= 0); Assert.True(snapshot["cpu"].Value <long>("threads") > 0); Assert.True(snapshot["cpu"].Value <long>("processes") > 0); Assert.True(serverMonitor.ErrorCount == 0); } finally { for (int i = 0; i < stressers.Length; i++) { if (stressers[i] != null) { stressers[i].Dispose(); } } if (serverMonitor != null) { serverMonitor.Dispose(); } for (int i = 0; i < sites.Length; i++) { if (sites[i] != null) { client.Delete(Utils.Self(sites[i])); client.Delete(Utils.Self((JObject)sites[i]["application_pool"])); } } if (client != null) { client.Dispose(); } } }
public void CreateEditDeleteLocation() { string physicalPath = Path.Combine("%temp%", Path.GetRandomFileName()); string physicalPath2 = Path.Combine("%temp%", Path.GetRandomFileName()); string expanded = null; string expanded2 = null; Assert.True(Environment.ExpandEnvironmentVariables(physicalPath) != physicalPath); Assert.True(Environment.ExpandEnvironmentVariables(physicalPath2) != physicalPath2); JObject location = null; string alias2 = "IisAdminTestAlias2"; JObject body = JObject.FromObject(new { path = physicalPath, claims = new string[] { "read", "write" } }); using (HttpClient client = ApiHttpClient.Create()) { try { location = client.Post($"{Configuration.Instance().TEST_SERVER_URL}{LOCATIONS_PATH}", body); Assert.Equal(location.Value <string>("alias"), string.Empty); Assert.Equal(location.Value <string>("path"), physicalPath); var claims = location["claims"].ToObject <IEnumerable <string> >(); Assert.True(Enumerable.SequenceEqual <string>(claims, new string[] { "read", "write" })); expanded = client.Get($"{Configuration.Instance().TEST_SERVER_URL}{FILES_PATH}")["files"] .ToObject <IEnumerable <JObject> >() .First(o => o.Value <string>("name").Equals(Path.GetFileName(physicalPath))) .Value <string>("physical_path"); // Sometime this is delayed Task.Delay(100).Wait(); Assert.True(Directory.Exists(expanded)); body = JObject.FromObject(new { alias = alias2, path = physicalPath2, claims = new string[] { "read" } }); location = client.Patch(Utils.Self(location), body); Assert.Equal(location.Value <string>("alias"), alias2); Assert.Equal(location.Value <string>("path"), physicalPath2); claims = location["claims"].ToObject <IEnumerable <string> >(); Assert.True(Enumerable.SequenceEqual <string>(claims, new string[] { "read" })); expanded2 = client.Get($"{Configuration.Instance().TEST_SERVER_URL}{FILES_PATH}")["files"] .ToObject <IEnumerable <JObject> >() .First(o => o.Value <string>("name").Equals(Path.GetFileName(physicalPath2))) .Value <string>("physical_path"); Assert.True(Directory.Exists(expanded2)); client.Delete(Utils.Self(location)); var locationsObj = client.Get($"{Configuration.Instance().TEST_SERVER_URL}{LOCATIONS_PATH}"); IEnumerable <JObject> locations = locationsObj["locations"].ToObject <IEnumerable <JObject> >(); Assert.True(!locations.Any(loc => { return(loc.Value <string>("path").Equals(physicalPath, StringComparison.OrdinalIgnoreCase) || loc.Value <string>("path").Equals(physicalPath2, StringComparison.OrdinalIgnoreCase)); })); } finally { if (expanded != null && Directory.Exists(expanded)) { Directory.Delete(expanded, false); } if (expanded2 != null && Directory.Exists(expanded2)) { Directory.Delete(expanded2, false); } if (location != null) { client.Delete(Utils.Self(location)); } } } }
public void ChangeAllProperties() { using (HttpClient client = ApiHttpClient.Create()) { EnsureNoSite(client, TEST_SITE_NAME); JObject site = CreateSite(client, TEST_SITE_NAME, TEST_PORT, Configuration.TEST_ROOT_PATH); JObject cachedSite = new JObject(site); WaitForStatus(client, ref site); Assert.True(site != null); site["server_auto_start"] = !site.Value <bool>("server_auto_start"); site["physical_path"] = Configuration.TEST_ROOT_PATH; site["enabled_protocols"] = site.Value <string>("enabled_protocols").Equals("http", StringComparison.OrdinalIgnoreCase) ? "https" : "http"; // If site status is unknown then we don't know if it will be started or stopped when it becomes available // Utilizing the defaults we assume it will go from unkown to started site["status"] = Enum.GetName(typeof(Status), DynamicHelper.To <Status>(site["status"]) == Status.Stopped ? Status.Started : Status.Stopped); JObject limits = (JObject)site["limits"]; limits["connection_timeout"] = limits.Value <long>("connection_timeout") - 1; limits["max_bandwidth"] = limits.Value <long>("max_bandwidth") - 1; limits["max_connections"] = limits.Value <long>("max_connections") - 1; limits["max_url_segments"] = limits.Value <long>("max_url_segments") - 1; JArray bindings = site.Value <JArray>("bindings"); bindings.Clear(); bindings.Add(JObject.FromObject(new { port = 63014, ip_address = "40.3.5.15", hostname = "testhostname", protocol = "http" })); bindings.Add(JObject.FromObject(new { port = 63015, ip_address = "*", hostname = "", protocol = "https", certificate = GetCertificate(client) })); string result; string body = JsonConvert.SerializeObject(site); Assert.True(client.Patch(Utils.Self(site), body, out result)); JObject newSite = JsonConvert.DeserializeObject <JObject>(result); WaitForStatus(client, ref newSite); Assert.True(Utils.JEquals <bool>(site, newSite, "server_auto_start")); Assert.True(Utils.JEquals <string>(site, newSite, "physical_path")); Assert.True(Utils.JEquals <string>(site, newSite, "enabled_protocols")); Assert.True(Utils.JEquals <string>(site, newSite, "status", StringComparison.OrdinalIgnoreCase)); Assert.True(Utils.JEquals <long>(site, newSite, "limits.connection_timeout")); Assert.True(Utils.JEquals <long>(site, newSite, "limits.max_bandwidth")); Assert.True(Utils.JEquals <long>(site, newSite, "limits.max_connections")); Assert.True(Utils.JEquals <long>(site, newSite, "limits.max_url_segments")); for (var i = 0; i < bindings.Count; i++) { var oldBinding = (JObject)bindings[i]; var newBinding = (JObject)bindings[i]; Assert.True(Utils.JEquals <string>(oldBinding, newBinding, "protocol")); Assert.True(Utils.JEquals <string>(oldBinding, newBinding, "port")); Assert.True(Utils.JEquals <string>(oldBinding, newBinding, "ip_address")); Assert.True(Utils.JEquals <string>(oldBinding, newBinding, "hostname")); if (newBinding.Value <string>("protocol").Equals("https")) { Assert.True(JToken.DeepEquals(oldBinding["certificate"], newBinding["certificate"])); } } Assert.True(DeleteSite(client, Utils.Self(site))); } }
public void BindingConflict() { string[] httpProperties = new string[] { "ip_address", "port", "hostname", "protocol", "binding_information" }; string[] httpsProperties = new string[] { "ip_address", "port", "hostname", "protocol", "binding_information", "certificate" }; string[] othersProperties = new string[] { "protocol", "binding_information" }; using (HttpClient client = ApiHttpClient.Create()) { EnsureNoSite(client, TEST_SITE_NAME); JObject site = CreateSite(client, TEST_SITE_NAME, TEST_PORT, TEST_SITE_PATH); var bindings = site.Value <JArray>("bindings"); bindings.Clear(); var conflictBindings = new object[] { new { port = 63015, ip_address = "*", hostname = "abc", protocol = "http" }, new { port = 63015, ip_address = "*", hostname = "abc", protocol = "http" } }; foreach (var b in conflictBindings) { bindings.Add(JObject.FromObject(b)); } var response = client.PatchRaw(Utils.Self(site), site); Assert.True(response.StatusCode == HttpStatusCode.Conflict); conflictBindings = new object[] { new { binding_information = "35808:*", protocol = "net.tcp" }, new { binding_information = "35808:*", protocol = "net.tcp" } }; bindings.Clear(); foreach (var b in conflictBindings) { bindings.Add(JObject.FromObject(b)); } response = client.PatchRaw(Utils.Self(site), site); Assert.True(response.StatusCode == HttpStatusCode.Conflict); Assert.True(DeleteSite(client, Utils.Self(site))); } }
public void BindingTypes() { IEnumerable <string> httpProperties = new string[] { "ip_address", "port", "hostname", "protocol", "binding_information" }; List <string> httpsProperties = new List <string> { "ip_address", "port", "hostname", "protocol", "binding_information", "certificate" }; IEnumerable <string> othersProperties = new string[] { "protocol", "binding_information" }; if (Utils.OsVersion >= new Version(6, 2)) { httpsProperties.Add("require_sni"); } using (HttpClient client = ApiHttpClient.Create()) { EnsureNoSite(client, TEST_SITE_NAME); JObject site = CreateSite(client, TEST_SITE_NAME, TEST_PORT, TEST_SITE_PATH); var bindings = site.Value <JArray>("bindings"); bindings.Clear(); int p = 63013; var goodBindings = new object[] { new { port = p++, ip_address = "*", hostname = "abc", protocol = "http" }, new { binding_information = "128.0.3.5:" + (p++) + ":def", protocol = "http" }, new { port = p++, ip_address = "*", hostname = "", protocol = "https", certificate = GetCertificate(client) }, new { binding_information = "*:" + (p++) + ":def", protocol = "http" }, new { binding_information = (p++) + ":*", protocol = "net.tcp" }, new { binding_information = "*", protocol = "net.pipe" } }; foreach (var b in goodBindings) { bindings.Add(JObject.FromObject(b)); } var res = client.Patch(Utils.Self(site), site); Assert.NotNull(res); JArray newBindings = res.Value <JArray>("bindings"); Assert.True(bindings.Count == newBindings.Count); for (var i = 0; i < bindings.Count; i++) { var binding = (JObject)bindings[i]; foreach (var prop in binding.Properties()) { Assert.True(JToken.DeepEquals(binding[prop.Name], newBindings[i][prop.Name])); } string protocol = binding.Value <string>("protocol"); switch (protocol) { case "http": Assert.True(HasExactProperties((JObject)newBindings[i], httpProperties)); break; case "https": Assert.True(HasExactProperties((JObject)newBindings[i], httpsProperties)); break; default: Assert.True(HasExactProperties((JObject)newBindings[i], othersProperties)); break; } } var badBindings = new object[] { new { port = p++, ip_address = "*", hostname = "abc" }, new { port = p++, ip_address = "", hostname = "abc", protocol = "http" }, new { protocol = "http", binding_information = $":{p++}:" }, new { protocol = "http", binding_information = $"127.0.4.3::" } }; foreach (var badBinding in badBindings) { newBindings.Clear(); newBindings.Add(JObject.FromObject(badBinding)); var response = client.PatchRaw(Utils.Self(res), res); Assert.True(response.StatusCode == HttpStatusCode.BadRequest); } Assert.True(DeleteSite(client, Utils.Self(site))); } }
public void CreatePatchRemoveProvider() { var TEST_PROVIDER_NAME = "Test Provider"; var TEST_PROVIDER_GUID = Guid.NewGuid().ToString("B"); var TEST_AREAS = new string[] { "test_area", "test_area2" }; var PATCH_PROVIDER_NAME = "Patch Provider"; var PATCH_PROVIDER_GUID = Guid.NewGuid().ToString("B"); var PATCH_AREAS = new string[] { "patch_area", "patch_area2" }; using (var client = ApiHttpClient.Create()) { var feature = GetFeature(client, null, null); var providersObj = Utils.FollowLink(client, feature, "providers"); var providers = providersObj.Value <JArray>("providers").ToObject <IEnumerable <JObject> >(); foreach (var p in providers) { if (p.Value <string>("name").Equals(TEST_PROVIDER_NAME, StringComparison.OrdinalIgnoreCase) || p.Value <string>("name").Equals(PATCH_PROVIDER_NAME, StringComparison.OrdinalIgnoreCase)) { Assert.True(client.Delete(Utils.Self(p))); break; } } var testProvider = new { name = TEST_PROVIDER_NAME, guid = TEST_PROVIDER_GUID, areas = TEST_AREAS, request_tracing = feature }; var patchProvider = new { name = PATCH_PROVIDER_NAME, guid = PATCH_PROVIDER_GUID, areas = PATCH_AREAS }; var jProvider = JObject.FromObject(testProvider); var pProvider = JObject.FromObject(patchProvider); string result; Assert.True(client.Post(Utils.GetLink(feature, "providers"), JsonConvert.SerializeObject(testProvider), out result)); JObject newProvider = null; try { newProvider = Utils.ToJ(result); CompareProviders(jProvider, newProvider); Assert.True(client.Patch(Utils.Self(newProvider), JsonConvert.SerializeObject(patchProvider), out result)); newProvider = Utils.ToJ(result); CompareProviders(pProvider, newProvider); } finally { Assert.True(client.Delete(Utils.Self(newProvider))); } } }
public void CreatePatchRemoveRule() { var TEST_RULE_PATH = "test_rule*.path"; var TEST_RULE_STATUS_CODES = new string[] { "101", "244-245", "280-301", "340" }; var TEST_RULE_MIN_TIME = 100; var TEST_RULE_EVENT_SEVERITY = "error"; var TEST_RULE_PROVIDER_NAME = "ASP"; var TEST_RULE_ALLOWED_AREAS = new Dictionary <string, bool>() { }; var PATCH_PATH = "test_patch*.path"; var PATCH_RULE_STATUS_CODES = new string[] { "104-181", "333" }; var PATCH_RULE_MIN_TIME = 103; var PATCH_RULE_EVENT_SEVERITY = "criticalerror"; var PATCH_RULE_PROVIDER_NAME = "WWW Server"; var PATCH_RULE_ALLOWED_AREAS = new Dictionary <string, bool>() { { "Security", true }, { "Compression", true }, { "Module", true } }; using (var client = ApiHttpClient.Create()) { var feature = GetFeature(client, null, null); var rulesObj = Utils.FollowLink(client, feature, "rules"); var rules = rulesObj.Value <JArray>("rules").ToObject <IEnumerable <JObject> >(); var providersObj = Utils.FollowLink(client, feature, "providers"); var providers = providersObj.Value <JArray>("providers").ToObject <IEnumerable <JObject> >(); // Ensure rule with test path doesn't already exist foreach (var r in rules) { if (r.Value <string>("path").Equals(TEST_RULE_PATH, StringComparison.OrdinalIgnoreCase) || r.Value <string>("path").Equals(PATCH_PATH, StringComparison.OrdinalIgnoreCase)) { Assert.True(client.Delete(Utils.Self(r))); break; } } var testRule = new { path = TEST_RULE_PATH, status_codes = TEST_RULE_STATUS_CODES, min_request_execution_time = TEST_RULE_MIN_TIME, event_severity = TEST_RULE_EVENT_SEVERITY, traces = new [] { new { allowed_areas = TEST_RULE_ALLOWED_AREAS, provider = providers.FirstOrDefault(p => p.Value <string>("name").Equals(TEST_RULE_PROVIDER_NAME)), verbosity = "verbose" } }, request_tracing = feature }; var patchRule = new { path = PATCH_PATH, status_codes = PATCH_RULE_STATUS_CODES, min_request_execution_time = PATCH_RULE_MIN_TIME, event_severity = PATCH_RULE_EVENT_SEVERITY, traces = new[] { new { allowed_areas = PATCH_RULE_ALLOWED_AREAS, provider = providers.FirstOrDefault(p => p.Value <string>("name").Equals(PATCH_RULE_PROVIDER_NAME)), verbosity = "verbose" } }, }; var jRule = JObject.FromObject(testRule); var pRule = JObject.FromObject(patchRule); string result; Assert.True(client.Post(Utils.GetLink(feature, "rules"), JsonConvert.SerializeObject(testRule), out result)); JObject newRule = null; try { newRule = Utils.ToJ(result); CompareRules(jRule, newRule); Assert.True(client.Patch(Utils.Self(newRule), JsonConvert.SerializeObject(patchRule), out result)); newRule = Utils.ToJ(result); CompareRules(pRule, newRule); } finally { Assert.True(client.Delete(Utils.Self(newRule))); } } }
public void ChangeAllProperties() { using (HttpClient client = ApiHttpClient.Create()) { EnsureNoPool(client, TEST_APP_POOL_NAME); string id; Assert.True(CreateAppPool(client, TEST_APP_POOL, out id)); JObject pool = GetAppPool(client, TEST_APP_POOL_NAME); JObject cachedPool = new JObject(pool); WaitForStatus(client, pool); pool["auto_start"] = !pool.Value <bool>("auto_start"); pool["enable_32bit_win64"] = !pool.Value <bool>("enable_32bit_win64"); pool["queue_length"] = pool.Value <long>("queue_length") + 1; pool["managed_runtime_version"] = "v2.0"; pool["status"] = Enum.GetName(typeof(Status), DynamicHelper.To <Status>(pool["status"]) == Status.Stopped ? Status.Started : Status.Stopped); pool["pipeline_mode"] = Enum.GetName(typeof(ManagedPipelineMode), DynamicHelper.To <ManagedPipelineMode>(pool["pipeline_mode"]) == ManagedPipelineMode.Integrated ? ManagedPipelineMode.Classic : ManagedPipelineMode.Integrated); JObject cpu = pool.Value <JObject>("cpu"); cpu["limit"] = cpu.Value <long>("limit") + 1; cpu["limit_interval"] = cpu.Value <long>("limit_interval") + 1; cpu["action"] = Enum.GetName(typeof(ProcessorAction), DynamicHelper.To <ProcessorAction>(cpu["action"]) == ProcessorAction.NoAction ? ProcessorAction.KillW3wp : ProcessorAction.NoAction); JObject pModel = pool.Value <JObject>("process_model"); pModel["idle_timeout"] = pModel.Value <long>("idle_timeout") + 1; pModel["max_processes"] = pModel.Value <long>("max_processes") + 1; pModel["ping_interval"] = pModel.Value <long>("ping_interval") + 1; pModel["ping_response_time"] = pModel.Value <long>("ping_response_time") + 1; pModel["shutdown_time_limit"] = pModel.Value <long>("shutdown_time_limit") + 1; pModel["startup_time_limit"] = pModel.Value <long>("startup_time_limit") + 1; pModel["pinging_enabled"] = !pModel.Value <bool>("pinging_enabled"); pModel["idle_timeout_action"] = Enum.GetName(typeof(IdleTimeoutAction), DynamicHelper.To <IdleTimeoutAction>(pModel["idle_timeout_action"]) == IdleTimeoutAction.Terminate ? IdleTimeoutAction.Suspend : IdleTimeoutAction.Terminate); JObject recycling = (JObject)pool["recycling"]; recycling["disable_overlapped_recycle"] = !recycling.Value <bool>("disable_overlapped_recycle"); recycling["disable_recycle_on_config_change"] = !recycling.Value <bool>("disable_recycle_on_config_change"); JObject logEvents = (JObject)pool["recycling"]["log_events"]; logEvents["time"] = !logEvents.Value <bool>("time"); logEvents["requests"] = !logEvents.Value <bool>("requests"); logEvents["schedule"] = !logEvents.Value <bool>("schedule"); logEvents["memory"] = !logEvents.Value <bool>("memory"); logEvents["isapi_unhealthy"] = !logEvents.Value <bool>("isapi_unhealthy"); logEvents["on_demand"] = !logEvents.Value <bool>("on_demand"); logEvents["config_change"] = !logEvents.Value <bool>("config_change"); logEvents["private_memory"] = !logEvents.Value <bool>("private_memory"); JObject pRestart = (JObject)pool["recycling"]["periodic_restart"]; pRestart["time_interval"] = pRestart.Value <long>("time_interval") + 1; pRestart["private_memory"] = pRestart.Value <long>("private_memory") + 1; pRestart["request_limit"] = pRestart.Value <long>("request_limit") + 1; pRestart["virtual_memory"] = pRestart.Value <long>("virtual_memory") + 1; JArray schedule = (JArray)pRestart["schedule"]; schedule.Add(new JValue(TimeSpan.FromHours(20).ToString(@"hh\:mm"))); JObject rfp = pool.Value <JObject>("rapid_fail_protection"); rfp["interval"] = rfp.Value <long>("interval") + 1; rfp["max_crashes"] = rfp.Value <long>("max_crashes") + 1; rfp["enabled"] = !rfp.Value <bool>("enabled"); rfp["auto_shutdown_exe"] = "test.exe"; rfp["auto_shutdown_params"] = "testparams"; rfp["load_balancer_capabilities"] = Enum.GetName(typeof(LoadBalancerCapabilities), DynamicHelper.To <LoadBalancerCapabilities>(rfp["idle_timeout_action"]) == LoadBalancerCapabilities.HttpLevel ? LoadBalancerCapabilities.TcpLevel : LoadBalancerCapabilities.HttpLevel); JObject processOrphaning = pool.Value <JObject>("process_orphaning"); processOrphaning["enabled"] = !processOrphaning.Value <bool>("enabled"); processOrphaning["orphan_action_exe"] = "test.exe"; processOrphaning["orphan_action_params"] = "testparams"; string result; string body = JsonConvert.SerializeObject(pool); Assert.True(client.Patch(Utils.Self(pool), body, out result)); JObject newPool = JsonConvert.DeserializeObject <JObject>(result); Assert.True(Utils.JEquals <bool>(pool, newPool, "auto_start")); Assert.True(Utils.JEquals <bool>(pool, newPool, "enable_32bit_win64")); Assert.True(Utils.JEquals <long>(pool, newPool, "queue_length")); Assert.True(Utils.JEquals <string>(pool, newPool, "pipeline_mode", StringComparison.OrdinalIgnoreCase)); Assert.True(Utils.JEquals <string>(pool, newPool, "managed_runtime_version")); Assert.True(Utils.JEquals <long>(pool, newPool, "cpu.limit")); Assert.True(Utils.JEquals <long>(pool, newPool, "cpu.limit_interval")); Assert.True(Utils.JEquals <bool>(pool, newPool, "cpu.processor_affinity_enabled")); Assert.True(Utils.JEquals <string>(pool, newPool, "cpu.action", StringComparison.OrdinalIgnoreCase)); Assert.True(Utils.JEquals <long>(pool, newPool, "process_model.idle_timeout")); Assert.True(Utils.JEquals <long>(pool, newPool, "process_model.max_processes")); Assert.True(Utils.JEquals <long>(pool, newPool, "process_model.ping_interval")); Assert.True(Utils.JEquals <long>(pool, newPool, "process_model.ping_response_time")); Assert.True(Utils.JEquals <long>(pool, newPool, "process_model.shutdown_time_limit")); Assert.True(Utils.JEquals <long>(pool, newPool, "process_model.startup_time_limit")); Assert.True(Utils.JEquals <bool>(pool, newPool, "process_model.pinging_enabled")); Assert.True(Utils.JEquals <string>(pool, newPool, "process_model.idle_timeout_action", StringComparison.OrdinalIgnoreCase)); Assert.True(Utils.JEquals <bool>(pool, newPool, "recycling.disable_overlapped_recycle")); Assert.True(Utils.JEquals <bool>(pool, newPool, "recycling.disable_recycle_on_config_change")); Assert.True(Utils.JEquals <bool>(pool, newPool, "recycling.log_events.time")); Assert.True(Utils.JEquals <bool>(pool, newPool, "recycling.log_events.requests")); Assert.True(Utils.JEquals <bool>(pool, newPool, "recycling.log_events.schedule")); Assert.True(Utils.JEquals <bool>(pool, newPool, "recycling.log_events.memory")); Assert.True(Utils.JEquals <bool>(pool, newPool, "recycling.log_events.isapi_unhealthy")); Assert.True(Utils.JEquals <bool>(pool, newPool, "recycling.log_events.on_demand")); Assert.True(Utils.JEquals <bool>(pool, newPool, "recycling.log_events.config_change")); Assert.True(Utils.JEquals <bool>(pool, newPool, "recycling.log_events.private_memory")); Assert.True(Utils.JEquals <long>(pool, newPool, "recycling.periodic_restart.time_interval")); Assert.True(Utils.JEquals <long>(pool, newPool, "recycling.periodic_restart.private_memory")); Assert.True(Utils.JEquals <long>(pool, newPool, "recycling.periodic_restart.request_limit")); Assert.True(Utils.JEquals <long>(pool, newPool, "recycling.periodic_restart.virtual_memory")); JArray scheduleOld = pool["recycling"]["periodic_restart"].Value <JArray>("schedule"); JArray scheduleNew = newPool["recycling"]["periodic_restart"].Value <JArray>("schedule"); for (int i = 0; i < scheduleOld.Count; i++) { Assert.True(scheduleOld[i].ToObject <string>().Equals(scheduleNew[i].ToObject <string>())); } Assert.True(Utils.JEquals <long>(pool, newPool, "rapid_fail_protection.interval")); Assert.True(Utils.JEquals <long>(pool, newPool, "rapid_fail_protection.max_crashes")); Assert.True(Utils.JEquals <bool>(pool, newPool, "rapid_fail_protection.enabled")); Assert.True(Utils.JEquals <string>(pool, newPool, "rapid_fail_protection.auto_shutdown_exe")); Assert.True(Utils.JEquals <string>(pool, newPool, "rapid_fail_protection.auto_shutdown_params")); Assert.True(Utils.JEquals <string>(pool, newPool, "rapid_fail_protection.load_balancer_capabilities", StringComparison.OrdinalIgnoreCase)); Assert.True(Utils.JEquals <bool>(pool, newPool, "process_orphaning.enabled")); Assert.True(Utils.JEquals <string>(pool, newPool, "process_orphaning.orphan_action_exe")); Assert.True(Utils.JEquals <string>(pool, newPool, "process_orphaning.orphan_action_params")); EnsureNoPool(client, TEST_APP_POOL_NAME); } }
public void ChangeAllProperties() { using (HttpClient client = ApiHttpClient.Create()) { // Web Server Scope JObject feature = GetLoggingFeature(client, null, null); JObject cachedFeature = new JObject(feature); string result; List <LogFormat> logFormats = new List <LogFormat>() { new LogFormat() { Name = "w3c", IsServerLevel = true }, new LogFormat() { Name = "binary", IsServerLevel = true }, new LogFormat() { Name = "w3c", IsServerLevel = false }, }; try { foreach (var target in logFormats) { JObject rollover = feature.Value <JObject>("rollover"); feature["log_per_site"] = !target.IsServerLevel; feature["log_file_format"] = target.Name; Assert.True(client.Patch(Utils.Self(feature), JsonConvert.SerializeObject(feature), out result)); JObject uFeature = JsonConvert.DeserializeObject <JObject>(result); JObject cachedSpecific = new JObject(uFeature); Assert.True(Utils.JEquals <bool>(feature, uFeature, "log_per_site")); Assert.True(Utils.JEquals <string>(feature, uFeature, "log_file_format")); feature = uFeature; try { feature["enabled"] = !feature.Value <bool>("enabled"); feature["log_file_encoding"] = feature.Value <string>("log_file_encoding") == "utf-8" ? "ansi" : "utf-8"; feature["directory"] = System.IO.Path.Combine(feature.Value <string>("directory"), "test"); rollover["period"] = rollover.Value <string>("period") == "daily" ? "weekly" : "daily"; rollover["truncate_size"] = rollover.Value <long>("truncate_size") - 1; rollover["local_time_rollover"] = !rollover.Value <bool>("local_time_rollover"); if (target.Name == "w3c" && !target.IsServerLevel) { JObject logTarget = feature.Value <JObject>("log_target"); logTarget["etw"] = !logTarget.Value <bool>("etw"); logTarget["file"] = !logTarget.Value <bool>("file"); } if (target.Name == "w3c") { JObject logFields = feature.Value <JObject>("log_fields"); IList <string> keys = logFields.Properties().Select(p => p.Name).ToList(); foreach (var key in keys) { logFields[key] = !logFields.Value <bool>(key); } } Assert.True(client.Patch(Utils.Self(feature), JsonConvert.SerializeObject(feature), out result)); uFeature = JsonConvert.DeserializeObject <JObject>(result); Assert.True(Utils.JEquals <bool>(feature, uFeature, "log_per_site")); Assert.True(Utils.JEquals <bool>(feature, uFeature, "enabled")); Assert.True(Utils.JEquals <string>(feature, uFeature, "log_file_encoding")); Assert.True(Utils.JEquals <string>(feature, uFeature, "rollover.period")); Assert.True(Utils.JEquals <long>(feature, uFeature, "rollover.truncate_size")); Assert.True(Utils.JEquals <bool>(feature, uFeature, "rollover.use_local_time")); Assert.True(JToken.DeepEquals(feature["log_target"], uFeature["log_target"])); Assert.True(JToken.DeepEquals(feature["log_fields"], uFeature["log_fields"])); feature = uFeature; } finally { Assert.True(client.Patch(Utils.Self(cachedSpecific), JsonConvert.SerializeObject(cachedSpecific), out result)); } } } finally { Assert.True(client.Patch(Utils.Self(cachedFeature), JsonConvert.SerializeObject(cachedFeature), out result)); } } }
public void CreateChangeRemoveHandler() { var handler = JObject.FromObject(new { name = "test_handler", path = "*.test", verbs = "*", type = "Microsoft.IIS.Administration.Test.Type", modules = "ManagedPipelineHandler", script_processor = "", resource_type = "unspecified", require_access = "script", allow_path_info = false, precondition = "integratedMode" }); using (var client = ApiHttpClient.Create()) { var webserverFeature = Utils.GetFeature(client, HANDLERS_URL, null, null); Assert.NotNull(webserverFeature); var h = GetHandler(client, webserverFeature, handler.Value <string>("name")); if (h != null) { Assert.True(client.Delete(Utils.Self(h))); } JObject createdHandler, patchedHandler = null; createdHandler = CreateHandlerForFeature(client, webserverFeature, handler); Assert.NotNull(createdHandler); try { AssertHandlersEquals(handler, createdHandler); string patchName = handler.Value <string>("name") + "2"; h = GetHandler(client, webserverFeature, patchName); if (h != null) { Assert.True(client.Delete(Utils.Self(h))); } createdHandler["name"] = patchName; createdHandler["path"] = createdHandler.Value <string>("path") + "2"; createdHandler["verbs"] = "GET"; createdHandler["type"] = createdHandler.Value <string>("type") + "2"; createdHandler["modules"] = ""; createdHandler["script_processor"] = "some.dll"; createdHandler["resource_type"] = "file"; createdHandler["require_access"] = "write"; createdHandler["allow_path_info"] = !createdHandler.Value <bool>("allow_path_info"); createdHandler["precondition"] = ""; patchedHandler = client.Patch(Utils.Self(createdHandler), createdHandler); Assert.NotNull(patchedHandler); AssertHandlersEquals(createdHandler, patchedHandler); Assert.True(client.Delete(Utils.Self(patchedHandler))); } finally { if (createdHandler != null) { client.Delete(Utils.Self(createdHandler)); } if (patchedHandler != null) { client.Delete(Utils.Self(patchedHandler)); } } } }
public void CopyFile() { string copyName = "TEST_FILE_NAME_COPY.txt"; string testContent = "Test content for copying files."; JObject copyInfo = null; using (HttpClient client = ApiHttpClient.Create()) using (TestSiteContainer container = new TestSiteContainer(client)) { JObject site = Sites.GetSite(client, container.SiteName); var webFile = CreateWebFile(client, site, TEST_FILE_NAME); var physicalPath = Environment.ExpandEnvironmentVariables(webFile["file_info"].Value <string>("physical_path")); File.WriteAllText(physicalPath, testContent); try { var fileInfo = Utils.FollowLink(client, webFile.Value <JObject>("file_info"), "self"); var parent = fileInfo.Value <JObject>("parent"); var copy = new { name = copyName, parent = parent, file = fileInfo }; copyInfo = client.Post(Utils.GetLink(fileInfo, "copy"), copy); Assert.NotNull(copyInfo); // // Wait for copy to finish HttpResponseMessage res = null; do { res = client.GetAsync(Utils.Self(copyInfo)).Result; } while (res.StatusCode == HttpStatusCode.OK); var copyParent = new DirectoryInfo(physicalPath).Parent.FullName; var copyPhysicalPath = Environment.ExpandEnvironmentVariables(copyInfo["file"].Value <string>("physical_path")); Assert.True(copyPhysicalPath.Equals(Path.Combine(copyParent, copyName), StringComparison.OrdinalIgnoreCase)); var copyContent = File.ReadAllText(copyPhysicalPath); Assert.Equal(copyContent, testContent); } finally { if (webFile != null && webFile["file_info"] != null) { Assert.True(client.Delete(Utils.Self(webFile.Value <JObject>("file_info")))); } if (copyInfo != null) { Assert.True(client.Delete(Utils.Self(copyInfo.Value <JObject>("file")))); } } } }
public void Sni() { if (Utils.OsVersion < new Version(6, 2)) { return; } using (HttpClient client = ApiHttpClient.Create()) { EnsureNoSite(client, TEST_SITE_NAME); JObject site = CreateSite(client, TEST_SITE_NAME, TEST_PORT, TEST_SITE_PATH); var bindings = site.Value <JArray>("bindings"); bindings.Clear(); int p = 63013; var goodBindings = new object[] { new { port = p++, ip_address = "*", hostname = "test_host_name", protocol = "https", certificate = GetCertificate(client), require_sni = true } }; foreach (var b in goodBindings) { bindings.Add(JObject.FromObject(b)); } var res = client.Patch(Utils.Self(site), site); Assert.NotNull(res); JArray newBindings = res.Value <JArray>("bindings"); Assert.True(bindings.Count == newBindings.Count); for (var i = 0; i < bindings.Count; i++) { var binding = (JObject)bindings[i]; foreach (var prop in binding.Properties()) { Assert.True(JToken.DeepEquals(binding[prop.Name], newBindings[i][prop.Name])); } string protocol = binding.Value <string>("protocol"); } var badBindings = new object[] { new { port = p++, ip_address = "*", hostname = "", protocol = "https", certificate = GetCertificate(client), require_sni = true } }; foreach (var badBinding in badBindings) { newBindings.Clear(); newBindings.Add(JObject.FromObject(badBinding)); var response = client.PatchRaw(Utils.Self(res), res); Assert.True(response.StatusCode == HttpStatusCode.BadRequest); } Assert.True(DeleteSite(client, Utils.Self(site))); } }
public void RangeUploadDownload() { using (HttpClient client = ApiHttpClient.Create()) using (TestSiteContainer container = new TestSiteContainer(client)) { JObject site = Sites.GetSite(client, container.SiteName); // Create web file var webFile = CreateWebFile(client, site, TEST_FILE_NAME); try { // // Get physical file info var fileInfo = Utils.FollowLink(client, webFile.Value <JObject>("file_info"), "self"); var chunkSize = 1024 * 1024; var totalFileSize = 1024 * 1024 * 10; HttpRequestMessage req; HttpResponseMessage res; for (var i = 0; i < totalFileSize; i += chunkSize) { req = new HttpRequestMessage(HttpMethod.Put, Utils.GetLink(fileInfo, "content")); var currentChunkSize = totalFileSize - i < chunkSize ? totalFileSize - i : chunkSize; var slice = GetFileSlice(i, currentChunkSize); req.Content = new ByteArrayContent(slice); req.Content.Headers.Add("Content-Range", $"bytes {i}-{i + currentChunkSize - 1}/{totalFileSize}"); res = client.SendAsync(req).Result; Assert.True(Globals.Success(res)); } req = new HttpRequestMessage(HttpMethod.Get, Utils.GetLink(fileInfo, "content")); res = client.SendAsync(req).Result; Assert.True(Globals.Success(res)); var resultBytes = res.Content.ReadAsByteArrayAsync().Result; Assert.True(resultBytes.SequenceEqual(GetFileSlice(0, totalFileSize))); var download = new byte[totalFileSize]; // // Range download for (var i = 0; i < totalFileSize; i += chunkSize) { req = new HttpRequestMessage(HttpMethod.Get, Utils.GetLink(fileInfo, "content")); var currentChunkSize = totalFileSize - i < chunkSize ? totalFileSize - i : chunkSize; req.Headers.Add("Range", $"bytes={i}-{i + currentChunkSize - 1}"); res = client.SendAsync(req).Result; Assert.True(Globals.Success(res)); resultBytes = res.Content.ReadAsByteArrayAsync().Result; resultBytes.CopyTo(download, i); } Assert.True(download.SequenceEqual(GetFileSlice(0, totalFileSize))); } finally { Assert.True(client.Delete(Utils.Self(webFile.Value <JObject>("file_info")))); } } }
public void WebFileRange() { var physicalPath = Path.Combine(Configuration.Instance().TEST_ROOT_PATH, "web_file_range_test"); if (Directory.Exists(physicalPath)) { Directory.Delete(physicalPath, true); Directory.CreateDirectory(physicalPath); } JObject site = null; using (HttpClient client = ApiHttpClient.Create()) { try { var dirs = new List <string>() { "dir1", "dir2", "dir3", "dir4" }; var files = new List <string>() { "file1.txt", "file2.txt", "file3.txt", "file4.txt" }; Sites.EnsureNoSite(client, FILE_TEST_SITE_NAME); site = Sites.CreateSite(_output, client, FILE_TEST_SITE_NAME, Utils.GetAvailablePort(), physicalPath); Assert.NotNull(site); foreach (var dir in dirs) { Directory.CreateDirectory(Path.Combine(physicalPath, dir)); } foreach (var file in files) { File.Create(Path.Combine(physicalPath, file)).Dispose(); } int fileCount = Directory.GetFiles(physicalPath).Count() + Directory.GetDirectories(physicalPath).Count(); JObject folder = Utils.FollowLink(client, site, "files"); HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, Utils.GetLink(folder, "files")); req.Headers.Add("Range", "files=2-5"); var res = client.SendAsync(req).Result; Assert.True(res.Content.Headers.Contains("Content-Range")); Assert.True(res.Content.Headers.GetValues("Content-Range").First().Equals($"2-5/{fileCount}")); var children = JObject.Parse(res.Content.ReadAsStringAsync().Result)["files"].ToObject <IEnumerable <JObject> >(); Assert.True(children.Count() == 4); } finally { Directory.Delete(physicalPath, true); if (site != null) { client.Delete(Utils.Self(site)); } } } }