From edcf91ca7cd1d27dca987b7701fdbb0a09831d3c Mon Sep 17 00:00:00 2001 From: JKorf Date: Mon, 5 Mar 2018 09:38:24 +0100 Subject: [PATCH] Various fixes --- Authentication/AuthenticationProvider.cs | 7 +-- CryptoExchange.Net.csproj | 2 +- Error.cs | 4 ++ ExchangeClient.cs | 63 ++++++++++++++---------- Interfaces/IRequest.cs | 10 +++- Requests/Request.cs | 30 ++++++++++- 6 files changed, 82 insertions(+), 34 deletions(-) diff --git a/Authentication/AuthenticationProvider.cs b/Authentication/AuthenticationProvider.cs index bff695b..d562c98 100644 --- a/Authentication/AuthenticationProvider.cs +++ b/Authentication/AuthenticationProvider.cs @@ -4,16 +4,17 @@ namespace CryptoExchange.Net.Authentication { public abstract class AuthenticationProvider { - protected ApiCredentials credentials; + public ApiCredentials Credentials { get; } protected AuthenticationProvider(ApiCredentials credentials) { - this.credentials = credentials; + Credentials = credentials; } public abstract string AddAuthenticationToUriString(string uri, bool signed); public abstract IRequest AddAuthenticationToRequest(IRequest request, bool signed); - + public abstract string Sign(string toSign); + protected string ByteToString(byte[] buff) { var sbinary = ""; diff --git a/CryptoExchange.Net.csproj b/CryptoExchange.Net.csproj index 3b34af9..8b6b0f0 100644 --- a/CryptoExchange.Net.csproj +++ b/CryptoExchange.Net.csproj @@ -7,7 +7,7 @@ CryptoExchange.Net JKorf - 0.0.2 + 0.0.4 false https://github.com/JKorf/CryptoExchange.Net https://github.com/JKorf/CryptoExchange.Net/blob/master/LICENSE diff --git a/Error.cs b/Error.cs index 59363fb..a136407 100644 --- a/Error.cs +++ b/Error.cs @@ -30,6 +30,10 @@ public class ServerError: Error { public ServerError(string message) : base(3, "Server error: " + message) { } + + public ServerError(int code, string message) : base(code, message) + { + } } public class WebError : Error diff --git a/ExchangeClient.cs b/ExchangeClient.cs index f519dda..80c7348 100644 --- a/ExchangeClient.cs +++ b/ExchangeClient.cs @@ -22,13 +22,13 @@ namespace CryptoExchange.Net protected Log log; protected ApiProxy apiProxy; - private AuthenticationProvider authProvider; + protected AuthenticationProvider authProvider; private List rateLimiters; - protected ExchangeClient(ExchangeOptions exchangeOptions, AuthenticationProvider authentictationProvider) + protected ExchangeClient(ExchangeOptions exchangeOptions, AuthenticationProvider authenticationProvider) { log = new Log(); - authProvider = authentictationProvider; + authProvider = authenticationProvider; Configure(exchangeOptions); } @@ -80,6 +80,25 @@ namespace CryptoExchange.Net if(signed && authProvider == null) return new CallResult(null, new NoApiCredentialsError()); + var request = ConstructRequest(uri, method, parameters, signed); + + if (apiProxy != null) + request.SetProxy(apiProxy.Host, apiProxy.Port); + + foreach (var limiter in rateLimiters) + { + var limitedBy = limiter.LimitRequest(uri.AbsolutePath); + if (limitedBy > 0) + log.Write(LogVerbosity.Debug, $"Request {uri.AbsolutePath} was limited by {limitedBy}ms by {limiter.GetType().Name}"); + } + + log.Write(LogVerbosity.Debug, $"Sending request to {request.Uri}"); + var result = await ExecuteRequest(request).ConfigureAwait(false); + return result.Error != null ? new CallResult(null, result.Error) : Deserialize(result.Data); + } + + protected virtual IRequest ConstructRequest(Uri uri, string method, Dictionary parameters, bool signed) + { var uriString = uri.ToString(); if (parameters != null) @@ -89,29 +108,17 @@ namespace CryptoExchange.Net uriString += $"{string.Join("&", parameters.Select(s => $"{s.Key}={s.Value}"))}"; } - - if(authProvider != null) + + if (authProvider != null) uriString = authProvider.AddAuthenticationToUriString(uriString, signed); var request = RequestFactory.Create(uriString); request.Method = method; - if (apiProxy != null) - request.SetProxy(apiProxy.Host, apiProxy.Port); - - if(authProvider != null) + if (authProvider != null) request = authProvider.AddAuthenticationToRequest(request, signed); - foreach (var limiter in rateLimiters) - { - var limitedBy = limiter.LimitRequest(uri.AbsolutePath); - if (limitedBy > 0) - log.Write(LogVerbosity.Debug, $"Request {uri.AbsolutePath} was limited by {limitedBy}ms by {limiter.GetType().Name}"); - } - - log.Write(LogVerbosity.Debug, $"Sending request to {uriString}"); - var result = await ExecuteRequest(request); - return result.Error != null ? new CallResult(null, result.Error) : Deserialize(result.Data); + return request; } private async Task> ExecuteRequest(IRequest request) @@ -119,7 +126,7 @@ namespace CryptoExchange.Net var returnedData = ""; try { - var response = request.GetResponse(); + var response = await request.GetResponse().ConfigureAwait(false); using (var reader = new StreamReader(response.GetResponseStream())) { returnedData = await reader.ReadToEndAsync().ConfigureAwait(false); @@ -129,11 +136,11 @@ namespace CryptoExchange.Net catch (WebException we) { var response = (HttpWebResponse)we.Response; - string responseData = null; try { var reader = new StreamReader(response.GetResponseStream()); - responseData = reader.ReadToEnd(); + var responseData = await reader.ReadToEndAsync().ConfigureAwait(false); + return new CallResult(null, ParseErrorResponse(responseData)); } catch (Exception) { @@ -142,11 +149,8 @@ namespace CryptoExchange.Net var infoMessage = "No response from server"; if (response == null) return new CallResult(null, new WebError(infoMessage)); - - if (responseData != null) - infoMessage = "Server returned error: " + responseData; - else - infoMessage = $"Status: {response.StatusCode}-{response.StatusDescription}, Message: {we.Message}"; + + infoMessage = $"Status: {response.StatusCode}-{response.StatusDescription}, Message: {we.Message}"; return new CallResult(null, new ServerError(infoMessage)); } catch (Exception e) @@ -155,6 +159,11 @@ namespace CryptoExchange.Net } } + protected virtual Error ParseErrorResponse(string error) + { + return new ServerError(error); + } + private CallResult Deserialize(string data) where T: class { try diff --git a/Interfaces/IRequest.cs b/Interfaces/IRequest.cs index f17fff3..ec5219b 100644 --- a/Interfaces/IRequest.cs +++ b/Interfaces/IRequest.cs @@ -1,5 +1,7 @@ using System; +using System.IO; using System.Net; +using System.Threading.Tasks; namespace CryptoExchange.Net.Interfaces { @@ -10,6 +12,12 @@ namespace CryptoExchange.Net.Interfaces string Method { get; set; } void SetProxy(string host, int port); - IResponse GetResponse(); + + string ContentType { get; set; } + string Accept { get; set; } + long ContentLength { get; set; } + + Task GetRequestStream(); + Task GetResponse(); } } diff --git a/Requests/Request.cs b/Requests/Request.cs index 33bb914..2085ef2 100644 --- a/Requests/Request.cs +++ b/Requests/Request.cs @@ -1,5 +1,7 @@ using System; +using System.IO; using System.Net; +using System.Threading.Tasks; using CryptoExchange.Net.Interfaces; namespace CryptoExchange.Net.Requests @@ -18,11 +20,30 @@ namespace CryptoExchange.Net.Requests get => request.Headers; set => request.Headers = value; } + public string ContentType + { + get => request.ContentType; + set => request.ContentType = value; + } + + public string Accept + { + get => ((HttpWebRequest)request).Accept; + set => ((HttpWebRequest)request).Accept = value; + } + + public long ContentLength + { + get => ((HttpWebRequest)request).ContentLength; + set => ((HttpWebRequest)request).ContentLength = value; + } + public string Method { get => request.Method; set => request.Method = value; } + public Uri Uri => request.RequestUri; public void SetProxy(string host, int port) @@ -30,9 +51,14 @@ namespace CryptoExchange.Net.Requests request.Proxy = new WebProxy(host, port); } - public IResponse GetResponse() + public async Task GetRequestStream() { - return new Response(request.GetResponse()); + return await request.GetRequestStreamAsync(); + } + + public async Task GetResponse() + { + return new Response(await request.GetResponseAsync().ConfigureAwait(false)); } } }