1
0
mirror of https://github.com/JKorf/CryptoExchange.Net synced 2025-06-07 16:06:15 +00:00

Various fixes

This commit is contained in:
JKorf 2018-03-05 09:38:24 +01:00
parent 30301ab8d7
commit edcf91ca7c
6 changed files with 82 additions and 34 deletions

View File

@ -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 = "";

View File

@ -7,7 +7,7 @@
<PropertyGroup>
<PackageId>CryptoExchange.Net</PackageId>
<Authors>JKorf</Authors>
<PackageVersion>0.0.2</PackageVersion>
<PackageVersion>0.0.4</PackageVersion>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageProjectUrl>https://github.com/JKorf/CryptoExchange.Net</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/JKorf/CryptoExchange.Net/blob/master/LICENSE</PackageLicenseUrl>

View File

@ -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

View File

@ -22,13 +22,13 @@ namespace CryptoExchange.Net
protected Log log;
protected ApiProxy apiProxy;
private AuthenticationProvider authProvider;
protected AuthenticationProvider authProvider;
private List<IRateLimiter> 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<T>(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<T>(null, result.Error) : Deserialize<T>(result.Data);
}
protected virtual IRequest ConstructRequest(Uri uri, string method, Dictionary<string, object> 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<T>(null, result.Error) : Deserialize<T>(result.Data);
return request;
}
private async Task<CallResult<string>> 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<string>(null, ParseErrorResponse(responseData));
}
catch (Exception)
{
@ -142,11 +149,8 @@ namespace CryptoExchange.Net
var infoMessage = "No response from server";
if (response == null)
return new CallResult<string>(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<string>(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<T> Deserialize<T>(string data) where T: class
{
try

View File

@ -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<Stream> GetRequestStream();
Task<IResponse> GetResponse();
}
}

View File

@ -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<Stream> GetRequestStream()
{
return new Response(request.GetResponse());
return await request.GetRequestStreamAsync();
}
public async Task<IResponse> GetResponse()
{
return new Response(await request.GetResponseAsync().ConfigureAwait(false));
}
}
}