From 41561261f7b88195ba21d895ab3f5aba14f3dc7c Mon Sep 17 00:00:00 2001 From: djbadders <34887832+djbadders@users.noreply.github.com> Date: Sat, 14 Dec 2019 13:13:47 +0000 Subject: [PATCH] Use new HttpClient class for most web calls --- Core/MarketAnalyzer/BaseAnalyzer.cs | 202 +++++++++------------------ Core/MarketAnalyzer/Binance.cs | 2 +- Core/MarketAnalyzer/BinanceUS.cs | 2 +- Core/MarketAnalyzer/Bittrex.cs | 6 +- Core/MarketAnalyzer/CoinMarketCap.cs | 2 +- Core/MarketAnalyzer/Poloniex.cs | 4 +- Core/ProfitTrailer/SettingsAPI.cs | 12 +- 7 files changed, 82 insertions(+), 148 deletions(-) diff --git a/Core/MarketAnalyzer/BaseAnalyzer.cs b/Core/MarketAnalyzer/BaseAnalyzer.cs index 9cc61c4..e865d53 100644 --- a/Core/MarketAnalyzer/BaseAnalyzer.cs +++ b/Core/MarketAnalyzer/BaseAnalyzer.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; -using System.Text; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; using Newtonsoft.Json; using Core.Main; using Core.Helper; @@ -13,119 +15,94 @@ namespace Core.MarketAnalyzer { public class BaseAnalyzer { - public static Dictionary GetJsonFromURL(string url, LogHelper log, string api) + public static string GetJsonStringFromURL(string url, LogHelper log, (string header, string value)[] headers = null) { - Dictionary jsonObject = null; + HttpClient webClient = null; - HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); - if (api != "") + if (webClient == null) { - request.Headers.Add("X-CMC_PRO_API_KEY", api); + webClient = new HttpClient(); + + // Setup the one time conneciton characteristics + webClient.Timeout = new TimeSpan(0, 0, 30); // 30 second call timeout + webClient.DefaultRequestHeaders.ConnectionClose = false; // Keep alives + } + else + { + webClient.DefaultRequestHeaders.Clear(); } - request.ContentType = "application/json"; - request.UserAgent = "PTMagic.Import"; - request.KeepAlive = true; - request.Timeout = 10000; + // Accept JSON and Text + webClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + webClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain")); - HttpWebResponse httpResponse = null; - string jsonString = string.Empty; + // Setup the keep alive timeout + ServicePointManager.FindServicePoint(new Uri(url)).ConnectionLeaseTimeout = 300000; // 5 mins for keep alives + + // Add any custom headers + if (headers != null) + { + foreach (var header in headers) + { + webClient.DefaultRequestHeaders.Add(header.header, header.value); + } + } try { log.DoLogInfo("Calling URL: " + url); - httpResponse = (HttpWebResponse)request.GetResponse(); + var response = webClient.GetAsync(url).Result; - using (StreamReader jsonReader = new StreamReader(httpResponse.GetResponseStream())) + string repsonseString = response.Content.ReadAsStringAsync().Result; + + if (response.IsSuccessStatusCode) { - jsonString = jsonReader.ReadToEnd(); - jsonReader.Close(); + return repsonseString; } + else + { + // Error + var message = string.Format("Error whilst calling {0} - {1}", url, repsonseString); - jsonObject = JsonConvert.DeserializeObject>(jsonString); + log.DoLogError(message); - return jsonObject; + throw new Exception(message); + } } - catch (WebException ex) + catch (TaskCanceledException tcEx) { - log.DoLogCritical(string.Format("Error whilst calling {0} \nError: {1}", url, ex.Message), ex); - - if (ex.Response != null) - { - // Error calling the service but we got a response so dump it. - string responseString = string.Empty; - var response = ((HttpWebResponse)ex.Response); - var encoding = response.CharacterSet == "" ? Encoding.UTF8 : Encoding.GetEncoding(response.CharacterSet); - - using (var stream = response.GetResponseStream()) - { - var reader = new StreamReader(stream, encoding); - responseString = reader.ReadToEnd(); - } - - log.DoLogCritical(String.Format("{0} - Response: ({1}) {2} : {3}", ex.Message, response.StatusCode, response.StatusDescription, responseString), ex); - } + // Conneciton timeout + log.DoLogError(string.Format("Timeout whilst calling {0} - {1}", url, tcEx.Message)); throw; } catch (Exception ex) { - log.DoLogCritical(ex.Message, ex); + log.DoLogError(string.Format("Error whilst calling {0} \nError: {1}", url, ex.Message)); throw; } - finally - { - // Do any necessary clean up. - if (httpResponse != null) httpResponse.Dispose(); - } } - public static Newtonsoft.Json.Linq.JObject GetSimpleJsonObjectFromURL(string url, LogHelper log, bool swallowException) + public static Dictionary GetJsonFromURL(string url, LogHelper log, (string header, string value)[] headers = null) + { + Dictionary jsonObject = null; + + string jsonString = GetJsonStringFromURL(url, log, headers); + + // Convert the response to JSON + jsonObject = JsonConvert.DeserializeObject>(jsonString); + + return jsonObject; + } + + public static Newtonsoft.Json.Linq.JObject GetSimpleJsonObjectFromURL(string url, LogHelper log, (string header, string value)[] headers = null) { Newtonsoft.Json.Linq.JObject jsonObject = null; - HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); - request.ContentType = "application/json"; - request.UserAgent = "PTMagic.Import"; - request.KeepAlive = true; + string jsonString = GetJsonStringFromURL(url, log, headers); - try - { - HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse(); - - StreamReader jsonReader = new StreamReader(httpResponse.GetResponseStream()); - string jsonString = jsonReader.ReadToEnd(); - jsonReader.Close(); - - jsonObject = JsonConvert.DeserializeObject(jsonString); - - return jsonObject; - } - catch (WebException ex) - { - if (swallowException) - { - // Do nothing, as we do not want to get this logged. Only uncritical functions uses this - } - else - { - log.DoLogCritical("Url: " + url + " Message: " + ex.Message, ex); - throw ex; - } - } - catch (Exception ex) - { - if (swallowException) - { - // Do nothing, as we do not want to get this logged. Only uncritical functions uses this - } - else - { - log.DoLogCritical("Url: " + url + " Message: " + ex.Message, ex); - throw ex; - } - } + jsonObject = JsonConvert.DeserializeObject(jsonString); return jsonObject; } @@ -134,32 +111,9 @@ namespace Core.MarketAnalyzer { List jsonObject = null; - HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); - request.ContentType = "application/json"; - request.UserAgent = "PTMagic.Import"; - request.KeepAlive = true; + string jsonString = GetJsonStringFromURL(url, log, null); - try - { - HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse(); - - StreamReader jsonReader = new StreamReader(httpResponse.GetResponseStream()); - string jsonString = jsonReader.ReadToEnd(); - jsonReader.Close(); - - jsonObject = JsonConvert.DeserializeObject>(jsonString); - - return jsonObject; - } - catch (WebException ex) - { - log.DoLogCritical(ex.Message, ex); - throw ex; - } - catch (Exception ex) - { - log.DoLogCritical(ex.Message, ex); - } + jsonObject = JsonConvert.DeserializeObject>(jsonString); return jsonObject; } @@ -168,32 +122,9 @@ namespace Core.MarketAnalyzer { Newtonsoft.Json.Linq.JArray jsonObject = null; - HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); - request.ContentType = "application/json"; - request.UserAgent = "PTMagic.Import"; - request.KeepAlive = true; + string jsonString = GetJsonStringFromURL(url, log, null); - try - { - HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse(); - - StreamReader jsonReader = new StreamReader(httpResponse.GetResponseStream()); - string jsonString = jsonReader.ReadToEnd(); - jsonReader.Close(); - - jsonObject = JsonConvert.DeserializeObject(jsonString); - - return jsonObject; - } - catch (WebException ex) - { - log.DoLogCritical(ex.Message, ex); - throw ex; - } - catch (Exception ex) - { - log.DoLogCritical(ex.Message, ex); - } + jsonObject = JsonConvert.DeserializeObject(jsonString); return jsonObject; } @@ -206,7 +137,8 @@ namespace Core.MarketAnalyzer { string baseUrl = "https://api.github.com/repos/PTMagicians/PTMagic/releases/latest"; - Newtonsoft.Json.Linq.JObject jsonObject = GetSimpleJsonObjectFromURL(baseUrl, log, true); + Newtonsoft.Json.Linq.JObject jsonObject = GetSimpleJsonObjectFromURL(baseUrl, log, new (string header, string value)[] { ("User-Agent", "PTMagic.Import") }); + if (jsonObject != null) { result = jsonObject.GetValue("tag_name").ToString(); @@ -231,7 +163,7 @@ namespace Core.MarketAnalyzer string baseUrl = "http://free.currencyconverterapi.com/api/v5/convert?q=USD_" + currency + "&compact=y&apiKey=" + FreeCurrencyAPI; log.DoLogDebug("http://free.currencyconverterapi.com - Getting latest exchange rates..."); - Newtonsoft.Json.Linq.JObject jsonObject = GetSimpleJsonObjectFromURL(baseUrl, log, false); + Newtonsoft.Json.Linq.JObject jsonObject = GetSimpleJsonObjectFromURL(baseUrl, log, null); if (jsonObject != null) { log.DoLogDebug("http://free.currencyconverterapi.com - Received latest exchange rates."); diff --git a/Core/MarketAnalyzer/Binance.cs b/Core/MarketAnalyzer/Binance.cs index 7d75e28..8eae0a7 100644 --- a/Core/MarketAnalyzer/Binance.cs +++ b/Core/MarketAnalyzer/Binance.cs @@ -26,7 +26,7 @@ namespace Core.MarketAnalyzer string baseUrl = "https://api.binance.com/api/v1/ticker/24hr?symbol=" + mainMarket + "USDT"; log.DoLogInfo("Binance - Getting main market price..."); - Newtonsoft.Json.Linq.JObject jsonObject = GetSimpleJsonObjectFromURL(baseUrl, log, false); + Newtonsoft.Json.Linq.JObject jsonObject = GetSimpleJsonObjectFromURL(baseUrl, log, null); if (jsonObject != null) { log.DoLogInfo("Binance - Market data received for " + mainMarket + "USDT"); diff --git a/Core/MarketAnalyzer/BinanceUS.cs b/Core/MarketAnalyzer/BinanceUS.cs index d13fe9f..070fe77 100644 --- a/Core/MarketAnalyzer/BinanceUS.cs +++ b/Core/MarketAnalyzer/BinanceUS.cs @@ -26,7 +26,7 @@ namespace Core.MarketAnalyzer string baseUrl = "https://api.binance.us/api/v1/ticker/24hr?symbol=" + mainMarket + "USDT"; log.DoLogInfo("BinanceUS - Getting main market price..."); - Newtonsoft.Json.Linq.JObject jsonObject = GetSimpleJsonObjectFromURL(baseUrl, log, false); + Newtonsoft.Json.Linq.JObject jsonObject = GetSimpleJsonObjectFromURL(baseUrl, log, null); if (jsonObject != null) { log.DoLogInfo("BinanceUS - Market data received for " + mainMarket + "USDT"); diff --git a/Core/MarketAnalyzer/Bittrex.cs b/Core/MarketAnalyzer/Bittrex.cs index 28771b8..c7ede44 100644 --- a/Core/MarketAnalyzer/Bittrex.cs +++ b/Core/MarketAnalyzer/Bittrex.cs @@ -24,7 +24,7 @@ namespace Core.MarketAnalyzer string baseUrl = "https://bittrex.com/api/v1.1/public/getmarketsummary?market=USDT-" + mainMarket; log.DoLogInfo("Bittrex - Getting main market price..."); - Dictionary jsonObject = GetJsonFromURL(baseUrl, log, ""); + Dictionary jsonObject = GetJsonFromURL(baseUrl, log, null); if (jsonObject.Count > 0) { if (jsonObject["success"]) @@ -55,7 +55,7 @@ namespace Core.MarketAnalyzer string baseUrl = "https://bittrex.com/api/v2.0/pub/markets/GetMarketSummaries"; log.DoLogInfo("Bittrex - Getting market data..."); - Dictionary jsonObject = GetJsonFromURL(baseUrl, log, ""); + Dictionary jsonObject = GetJsonFromURL(baseUrl, log, null); if (jsonObject.Count > 0) { if (jsonObject["success"]) @@ -150,7 +150,7 @@ namespace Core.MarketAnalyzer string baseUrl = "https://bittrex.com/Api/v2.0/pub/market/GetTicks?tickInterval=oneMin&marketName=" + marketName; log.DoLogDebug("Bittrex - Getting ticks for '" + marketName + "'..."); - Dictionary jsonObject = GetJsonFromURL(baseUrl, log, ""); + Dictionary jsonObject = GetJsonFromURL(baseUrl, log, null); if (jsonObject.Count > 0) { if (jsonObject["success"]) diff --git a/Core/MarketAnalyzer/CoinMarketCap.cs b/Core/MarketAnalyzer/CoinMarketCap.cs index 5ed2902..96aa8e6 100644 --- a/Core/MarketAnalyzer/CoinMarketCap.cs +++ b/Core/MarketAnalyzer/CoinMarketCap.cs @@ -22,7 +22,7 @@ namespace Core.MarketAnalyzer log.DoLogInfo("CoinMarketCap - Getting market data..."); - Dictionary jsonObject = GetJsonFromURL(baseUrl, log, cmcAPI); + Dictionary jsonObject = GetJsonFromURL(baseUrl, log, new (string header, string value)[] { ("X-CMC_PRO_API_KEY", cmcAPI) }); if (jsonObject.Count > 0) { diff --git a/Core/MarketAnalyzer/Poloniex.cs b/Core/MarketAnalyzer/Poloniex.cs index 67fac0c..84a5848 100644 --- a/Core/MarketAnalyzer/Poloniex.cs +++ b/Core/MarketAnalyzer/Poloniex.cs @@ -24,7 +24,7 @@ namespace Core.MarketAnalyzer string baseUrl = "https://bittrex.com/api/v1.1/public/getmarketsummary?market=USDT-" + mainMarket; log.DoLogInfo("Poloniex - Getting main market price..."); - Dictionary jsonObject = GetJsonFromURL(baseUrl, log, ""); + Dictionary jsonObject = GetJsonFromURL(baseUrl, log, null); if (jsonObject.Count > 0) { if (jsonObject["success"]) @@ -55,7 +55,7 @@ namespace Core.MarketAnalyzer string baseUrl = "https://poloniex.com/public?command=returnTicker"; log.DoLogInfo("Poloniex - Getting market data..."); - Dictionary jsonObject = GetJsonFromURL(baseUrl, log, ""); + Dictionary jsonObject = GetJsonFromURL(baseUrl, log, null); if (jsonObject.Count > 0) { log.DoLogInfo("Poloniex - Market data received for " + jsonObject.Count.ToString() + " currencies"); diff --git a/Core/ProfitTrailer/SettingsAPI.cs b/Core/ProfitTrailer/SettingsAPI.cs index dea03b0..83dd315 100644 --- a/Core/ProfitTrailer/SettingsAPI.cs +++ b/Core/ProfitTrailer/SettingsAPI.cs @@ -51,12 +51,14 @@ namespace Core.ProfitTrailer log.DoLogDebug("Built POST request for Properties"); log.DoLogInfo("Sending Properties..."); - HttpWebResponse httpResponse = (HttpWebResponse)httpWebRequest.GetResponse(); - log.DoLogInfo("Properties sent!"); - httpResponse.Close(); - log.DoLogDebug("Properties response object closed."); + using (HttpWebResponse httpResponse = (HttpWebResponse)httpWebRequest.GetResponse()) + { + log.DoLogInfo("Properties sent!"); + httpResponse.Close(); + log.DoLogDebug("Properties response object closed."); + } + transferCompleted = true; - } catch (WebException ex) {