From 50f71b9e6198643daac8cc06aba46e8b1a2090e6 Mon Sep 17 00:00:00 2001 From: tuxuser <462620+tuxuser@users.noreply.github.com> Date: Sun, 26 Apr 2020 18:46:57 +0200 Subject: [PATCH 1/5] Dont use a new HttpClient instance on each SendAsync call --- StoreLib/Services/MSHttpClient.cs | 38 +++++++++++++++++++------------ 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/StoreLib/Services/MSHttpClient.cs b/StoreLib/Services/MSHttpClient.cs index a8de687..a49841b 100644 --- a/StoreLib/Services/MSHttpClient.cs +++ b/StoreLib/Services/MSHttpClient.cs @@ -10,23 +10,31 @@ namespace StoreLib.Services { public class MSHttpClient : HttpClient - {/// - /// An override of the SendAsync Function from HttpClient. This is done to automatically add the needed MS-CV tracking header to every request (along with our user-agent). - /// - /// - /// - /// + { + private readonly CorrelationVector _cv = new CorrelationVector(); + + /// + /// Instantiate MSHttpClient + /// + public MSHttpClient() + : base() + { + _cv.Init(); + base.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "StoreLib"); + } + + /// + /// An override of the SendAsync Function from HttpClient. This is done to automatically add the needed MS-CV tracking header to every request (along with our user-agent). + /// + /// + /// + /// public override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) //Overriding the SendAsync so we can easily add the CorrelationVector and User-Agent to every request. { - using (HttpClient client = new HttpClient()) - { - CorrelationVector CV = new CorrelationVector(); - CV.Init(); - request.Headers.Add("MS-CV", CV.GetValue()); - request.Headers.TryAddWithoutValidation("User-Agent", "StoreLib"); - HttpResponseMessage response = await client.SendAsync(request); - return response; - } + request.Headers.Add("MS-CV", _cv.GetValue()); + _cv.Increment(); + HttpResponseMessage response = await base.SendAsync(request); + return response; } } } From 54638048a867f4c00c7c98227b88429482e460d4 Mon Sep 17 00:00:00 2001 From: tuxuser <462620+tuxuser@users.noreply.github.com> Date: Sun, 26 Apr 2020 18:57:09 +0200 Subject: [PATCH 2/5] Use class instance of MSHttpClient --- StoreLib/Services/DisplayCatalogHandler.cs | 57 +++++++++++----------- StoreLib/Services/FE3Handler.cs | 11 ++--- 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/StoreLib/Services/DisplayCatalogHandler.cs b/StoreLib/Services/DisplayCatalogHandler.cs index e3a079c..90f03a2 100644 --- a/StoreLib/Services/DisplayCatalogHandler.cs +++ b/StoreLib/Services/DisplayCatalogHandler.cs @@ -10,6 +10,8 @@ namespace StoreLib.Services { public class DisplayCatalogHandler { + private readonly MSHttpClient _httpClient; + public DisplayCatalogModel ProductListing { get; internal set; } public Exception Error { get; internal set; } internal Uri ConstructedUri { get; set; } @@ -24,6 +26,9 @@ public class DisplayCatalogHandler public DisplayCatalogHandler(DCatEndpoint SelectedEndpoint, Locale Locale) { + //Adds needed headers for MS related requests. See MS_httpClient.cs + this._httpClient = new MSHttpClient(); + this.SelectedEndpoint = SelectedEndpoint; this.SelectedLocale = Locale; } @@ -59,14 +64,13 @@ public async Task QueryDCATAsync(string ID) this.ID = ID; this.ConstructedUri = Utilities.UriHelpers.CreateAlternateDCatUri(SelectedEndpoint, ID, IdentiferType.ProductID, SelectedLocale); Result = new DisplayCatalogResult(); //We need to clear the result incase someone queries a product, then queries a not found one, the wrong product will be returned. - MSHttpClient httpClient = new MSHttpClient(); //Adds needed headers for MS related requests. See MSHttpClient.cs HttpResponseMessage httpResponse = new HttpResponseMessage(); HttpRequestMessage httpRequestMessage; //We need to build the request URL based on the requested EndPoint;httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, ConstructedUri); httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, ConstructedUri); try { - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); } catch (TaskCanceledException) { @@ -101,14 +105,13 @@ public async Task QueryDCATAsync(string ID, IdentiferType IDType) this.ID = ID; this.ConstructedUri = Utilities.UriHelpers.CreateAlternateDCatUri(SelectedEndpoint, ID, IDType, SelectedLocale); Result = new DisplayCatalogResult(); //We need to clear the result incase someone queries a product, then queries a not found one, the wrong product will be returned. - MSHttpClient httpClient = new MSHttpClient(); //Adds needed headers for MS related requests. See MSHttpClient.cs HttpResponseMessage httpResponse = new HttpResponseMessage(); HttpRequestMessage httpRequestMessage; //We need to build the request URL based on the requested EndPoint;httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, ConstructedUri); httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, ConstructedUri); try { - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); } catch (TaskCanceledException) { @@ -143,15 +146,14 @@ public async Task QueryDCATAsync(string ID, IdentiferType IDType) this.ID = ID; this.ConstructedUri = Utilities.UriHelpers.CreateAlternateDCatUri(SelectedEndpoint, ID, IdentiferType.ProductID, SelectedLocale); Result = new DisplayCatalogResult(); //We need to clear the result incase someone queries a product, then queries a not found one, the wrong product will be returned. - MSHttpClient httpClient = new MSHttpClient(); //MSHttpClient extends System.Net.HttpClient to automaticly add a (needed) CorrelationVector to each request. HttpResponseMessage httpResponse = new HttpResponseMessage(); HttpRequestMessage httpRequestMessage; - httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authentication", AuthenticationToken); + _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authentication", AuthenticationToken); //We need to build the request URL based on the requested EndPoint; httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, ConstructedUri); try { - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); } catch (TaskCanceledException) { @@ -186,15 +188,14 @@ public async Task QueryDCATAsync(string ID, IdentiferType IDType) this.ID = ID; this.ConstructedUri = Utilities.UriHelpers.CreateAlternateDCatUri(SelectedEndpoint, ID, IDType, SelectedLocale); Result = new DisplayCatalogResult(); //We need to clear the result incase someone queries a product, then queries a not found one, the wrong product will be returned. - MSHttpClient httpClient = new MSHttpClient(); //MSHttpClient extends System.Net.HttpClient to automaticly add a (needed) CorrelationVector to each request. HttpResponseMessage httpResponse = new HttpResponseMessage(); HttpRequestMessage httpRequestMessage; - httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authentication", AuthenticationToken); + _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authentication", AuthenticationToken); //We need to build the request URL based on the requested EndPoint; httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, ConstructedUri); try { - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); } catch (TaskCanceledException) { @@ -224,46 +225,45 @@ public async Task QueryDCATAsync(string ID, IdentiferType IDType) /// Instance of DCatSearch, containing the returned products. public async Task SearchDCATAsync(string Query, DeviceFamily deviceFamily) { - MSHttpClient httpClient = new MSHttpClient(); HttpResponseMessage httpResponse = new HttpResponseMessage(); HttpRequestMessage httpRequestMessage; switch (deviceFamily) { case DeviceFamily.Desktop: httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $"{Utilities.TypeHelpers.EnumToSearchUri(SelectedEndpoint)}{Query}&productFamilyNames=apps,games&platformDependencyName=Windows.Desktop"); - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); break; case DeviceFamily.Xbox: httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $"{Utilities.TypeHelpers.EnumToSearchUri(SelectedEndpoint)}{Query}&productFamilyNames=apps,games&platformDependencyName=Windows.Xbox"); - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); break; case DeviceFamily.Universal: httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $"{Utilities.TypeHelpers.EnumToSearchUri(SelectedEndpoint)}{Query}&productFamilyNames=apps,games&platformDependencyName=Windows.Universal"); - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); break; case DeviceFamily.Mobile: httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $"{Utilities.TypeHelpers.EnumToSearchUri(SelectedEndpoint)}{Query}&productFamilyNames=apps,games&platformDependencyName=Windows.Mobile"); - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); break; case DeviceFamily.HoloLens: httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $"{Utilities.TypeHelpers.EnumToSearchUri(SelectedEndpoint)}{Query}&productFamilyNames=apps,games&platformDependencyName=Windows.Holographic"); - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); break; case DeviceFamily.IotCore: httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $"{Utilities.TypeHelpers.EnumToSearchUri(SelectedEndpoint)}{Query}&productFamilyNames=apps,games&platformDependencyName=Windows.Iot"); - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); break; case DeviceFamily.ServerCore: httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $"{Utilities.TypeHelpers.EnumToSearchUri(SelectedEndpoint)}{Query}&productFamilyNames=apps,games&platformDependencyName=Windows.Server"); - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); break; case DeviceFamily.Andromeda: httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $"{Utilities.TypeHelpers.EnumToSearchUri(SelectedEndpoint)}{Query}&productFamilyNames=apps,games&platformDependencyName=Windows.8828080"); - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); break; case DeviceFamily.WCOS: httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $"{Utilities.TypeHelpers.EnumToSearchUri(SelectedEndpoint)}{Query}&productFamilyNames=apps,games&platformDependencyName=Windows.Core"); - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); break; } if (httpResponse.IsSuccessStatusCode) @@ -304,42 +304,41 @@ public async Task> GetAddonsForProductAsync() /// public async Task SearchDCATAsync(string Query, DeviceFamily DeviceFamily, int SkipCount) { - MSHttpClient httpClient = new MSHttpClient(); HttpResponseMessage httpResponse = new HttpResponseMessage(); HttpRequestMessage httpRequestMessage; switch (DeviceFamily) { case DeviceFamily.Desktop: httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $"{Utilities.TypeHelpers.EnumToSearchUri(SelectedEndpoint)}{Query}&productFamilyNames=apps,games&platformDependencyName=Windows.Desktop"); - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); break; case DeviceFamily.Xbox: httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $"{Utilities.TypeHelpers.EnumToSearchUri(SelectedEndpoint)}{Query}&productFamilyNames=apps,games&platformDependencyName=Windows.Xbox"); - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); break; case DeviceFamily.Universal: httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $"{Utilities.TypeHelpers.EnumToSearchUri(SelectedEndpoint)}{Query}&productFamilyNames=apps,games&platformDependencyName=Windows.Universal"); - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); break; case DeviceFamily.Mobile: httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $"{Utilities.TypeHelpers.EnumToSearchUri(SelectedEndpoint)}{Query}&productFamilyNames=apps,games&platformDependencyName=Windows.Mobile"); - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); break; case DeviceFamily.HoloLens: httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $"{Utilities.TypeHelpers.EnumToSearchUri(SelectedEndpoint)}{Query}&productFamilyNames=apps,games&platformDependencyName=Windows.Holographic"); - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); break; case DeviceFamily.IotCore: httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $"{Utilities.TypeHelpers.EnumToSearchUri(SelectedEndpoint)}{Query}&productFamilyNames=apps,games&platformDependencyName=Windows.Iot"); - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); break; case DeviceFamily.ServerCore: httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $"{Utilities.TypeHelpers.EnumToSearchUri(SelectedEndpoint)}{Query}&productFamilyNames=apps,games&platformDependencyName=Windows.Server"); - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); break; case DeviceFamily.Andromeda: httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $"{Utilities.TypeHelpers.EnumToSearchUri(SelectedEndpoint)}{Query}&productFamilyNames=apps,games&platformDependencyName=Windows.8828080"); - httpResponse = await httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); + httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); break; } if (httpResponse.IsSuccessStatusCode) diff --git a/StoreLib/Services/FE3Handler.cs b/StoreLib/Services/FE3Handler.cs index f342339..89502aa 100644 --- a/StoreLib/Services/FE3Handler.cs +++ b/StoreLib/Services/FE3Handler.cs @@ -15,6 +15,8 @@ namespace StoreLib.Services { public static class FE3Handler { + private static readonly MSHttpClient _httpClient = new MSHttpClient(); + /// /// Returns raw xml containing various (Revision, Update, Package) IDs and info. /// @@ -22,13 +24,12 @@ public static class FE3Handler /// public static async Task SyncUpdatesAsync(string WuCategoryID) { - MSHttpClient httpClient = new MSHttpClient(); HttpContent httpContent = new StringContent(String.Format(GetResourceTextFile("WUIDRequest.xml"), await GetCookieAsync(), WuCategoryID), Encoding.UTF8, "application/soap+xml"); //Load in the Xml for this FE3 request and format it a cookie and the provided WuCategoryID. HttpRequestMessage httpRequest = new HttpRequestMessage(); httpRequest.RequestUri = Endpoints.FE3Delivery; httpRequest.Content = httpContent; httpRequest.Method = HttpMethod.Post; - HttpResponseMessage httpResponse = await httpClient.SendAsync(httpRequest, new System.Threading.CancellationToken()); + HttpResponseMessage httpResponse = await _httpClient.SendAsync(httpRequest, new System.Threading.CancellationToken()); string content = await httpResponse.Content.ReadAsStringAsync(); content = HttpUtility.HtmlDecode(content); return content; @@ -40,14 +41,13 @@ public static async Task SyncUpdatesAsync(string WuCategoryID) /// Cookie extracted from returned XML public static async Task GetCookieAsync() //Encrypted Cookie Data is needed for FE3 requests. It doesn't expire for a very long time but I still refresh it as the Store does. { - MSHttpClient httpClient = new MSHttpClient(); XmlDocument doc = new XmlDocument(); HttpContent httpContent = new StringContent(GetResourceTextFile("GetCookie.xml"), Encoding.UTF8, "application/soap+xml");//Loading the request xml from a file to keep things nice and tidy. HttpRequestMessage httpRequest = new HttpRequestMessage(); httpRequest.RequestUri = Endpoints.FE3Delivery; httpRequest.Content = httpContent; httpRequest.Method = HttpMethod.Post; - HttpResponseMessage httpResponse = await httpClient.SendAsync(httpRequest, new System.Threading.CancellationToken()); + HttpResponseMessage httpResponse = await _httpClient.SendAsync(httpRequest, new System.Threading.CancellationToken()); doc.LoadXml(await httpResponse.Content.ReadAsStringAsync()); XmlNodeList xmlNodeList = doc.GetElementsByTagName("EncryptedData"); string cookie = xmlNodeList[0].InnerText; @@ -84,7 +84,6 @@ public static void ProcessUpdateIDs(string Xml, out IList RevisionIDs, o /// IList of App Package Download Uris public static async Task> GetFileUrlsAsync(IList UpdateIDs, IList RevisionIDs) { - MSHttpClient httpClient = new MSHttpClient(); XmlDocument doc = new XmlDocument(); IList uris = new List(); foreach (string ID in UpdateIDs) @@ -94,7 +93,7 @@ public static async Task> GetFileUrlsAsync(IList UpdateIDs, I httpRequest.RequestUri = Endpoints.FE3DeliverySecured; httpRequest.Content = httpContent; httpRequest.Method = HttpMethod.Post; - HttpResponseMessage httpResponse = await httpClient.SendAsync(httpRequest, new System.Threading.CancellationToken()); + HttpResponseMessage httpResponse = await _httpClient.SendAsync(httpRequest, new System.Threading.CancellationToken()); doc.LoadXml(await httpResponse.Content.ReadAsStringAsync()); XmlNodeList XmlUrls = doc.GetElementsByTagName("FileLocation"); foreach (XmlNode node in XmlUrls) From 6fecda82dc0d5e680fa954950f0849bca8f7fff0 Mon Sep 17 00:00:00 2001 From: tuxuser <462620+tuxuser@users.noreply.github.com> Date: Sun, 26 Apr 2020 18:59:40 +0200 Subject: [PATCH 3/5] Set Authentication-Header on single HttpRequestMessage instead of HttpClient instance --- StoreLib/Services/DisplayCatalogHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/StoreLib/Services/DisplayCatalogHandler.cs b/StoreLib/Services/DisplayCatalogHandler.cs index 90f03a2..04c5045 100644 --- a/StoreLib/Services/DisplayCatalogHandler.cs +++ b/StoreLib/Services/DisplayCatalogHandler.cs @@ -148,9 +148,9 @@ public async Task QueryDCATAsync(string ID, IdentiferType IDType) Result = new DisplayCatalogResult(); //We need to clear the result incase someone queries a product, then queries a not found one, the wrong product will be returned. HttpResponseMessage httpResponse = new HttpResponseMessage(); HttpRequestMessage httpRequestMessage; - _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authentication", AuthenticationToken); //We need to build the request URL based on the requested EndPoint; httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, ConstructedUri); + httpRequestMessage.Headers.TryAddWithoutValidation("Authentication", AuthenticationToken); try { httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); @@ -190,9 +190,9 @@ public async Task QueryDCATAsync(string ID, IdentiferType IDType) Result = new DisplayCatalogResult(); //We need to clear the result incase someone queries a product, then queries a not found one, the wrong product will be returned. HttpResponseMessage httpResponse = new HttpResponseMessage(); HttpRequestMessage httpRequestMessage; - _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authentication", AuthenticationToken); //We need to build the request URL based on the requested EndPoint; httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, ConstructedUri); + httpRequestMessage.Headers.TryAddWithoutValidation("Authentication", AuthenticationToken); try { httpResponse = await _httpClient.SendAsync(httpRequestMessage, new System.Threading.CancellationToken()); From eba62aad0e32b0748181053f57737ee55fc35b0a Mon Sep 17 00:00:00 2001 From: tuxuser <462620+tuxuser@users.noreply.github.com> Date: Sun, 26 Apr 2020 19:01:26 +0200 Subject: [PATCH 4/5] Fix CorrelationVector.getCllSettingsAsInt --- StoreLib/Utilities/CorrelationVector.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/StoreLib/Utilities/CorrelationVector.cs b/StoreLib/Utilities/CorrelationVector.cs index f0a8651..15cebfc 100644 --- a/StoreLib/Utilities/CorrelationVector.cs +++ b/StoreLib/Utilities/CorrelationVector.cs @@ -65,8 +65,7 @@ internal void Init() protected static int getCllSettingsAsInt(Settings setting) { - int asInt = Int32.Parse(setting.ToString()); - return asInt; + return (int)setting; } private bool CanExtend() From c5f9c7fc0810db85d81a5e7b0a9adf2a95deef82 Mon Sep 17 00:00:00 2001 From: tuxuser <462620+tuxuser@users.noreply.github.com> Date: Sun, 26 Apr 2020 21:07:26 +0200 Subject: [PATCH 5/5] Workaround for non-Windows OS to fail cert validation --- StoreLib/Services/MSHttpClient.cs | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/StoreLib/Services/MSHttpClient.cs b/StoreLib/Services/MSHttpClient.cs index a49841b..db58538 100644 --- a/StoreLib/Services/MSHttpClient.cs +++ b/StoreLib/Services/MSHttpClient.cs @@ -11,13 +11,40 @@ namespace StoreLib.Services { public class MSHttpClient : HttpClient { + private static readonly bool IsWindows = System.Runtime.InteropServices.RuntimeInformation + .IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows); + private static HttpClientHandler _handler + { + get + { + HttpClientHandler handler = new HttpClientHandler(); + if (!IsWindows) + { + handler.ServerCertificateCustomValidationCallback = ServerCertificateValidationCallback; + } + return handler; + } + } + + private static bool ServerCertificateValidationCallback( + object sender, + System.Security.Cryptography.X509Certificates.X509Certificate certificate, + System.Security.Cryptography.X509Certificates.X509Chain chain, + System.Net.Security.SslPolicyErrors sslPolicyErrors + ) + { + + // TODO: Refine + return true; + } + private readonly CorrelationVector _cv = new CorrelationVector(); /// /// Instantiate MSHttpClient /// public MSHttpClient() - : base() + : base(_handler) { _cv.Init(); base.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "StoreLib");