mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2025-06-07 16:06:15 +00:00
Various fixes
This commit is contained in:
parent
30301ab8d7
commit
edcf91ca7c
@ -4,15 +4,16 @@ namespace CryptoExchange.Net.Authentication
|
|||||||
{
|
{
|
||||||
public abstract class AuthenticationProvider
|
public abstract class AuthenticationProvider
|
||||||
{
|
{
|
||||||
protected ApiCredentials credentials;
|
public ApiCredentials Credentials { get; }
|
||||||
|
|
||||||
protected AuthenticationProvider(ApiCredentials credentials)
|
protected AuthenticationProvider(ApiCredentials credentials)
|
||||||
{
|
{
|
||||||
this.credentials = credentials;
|
Credentials = credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract string AddAuthenticationToUriString(string uri, bool signed);
|
public abstract string AddAuthenticationToUriString(string uri, bool signed);
|
||||||
public abstract IRequest AddAuthenticationToRequest(IRequest request, bool signed);
|
public abstract IRequest AddAuthenticationToRequest(IRequest request, bool signed);
|
||||||
|
public abstract string Sign(string toSign);
|
||||||
|
|
||||||
protected string ByteToString(byte[] buff)
|
protected string ByteToString(byte[] buff)
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>CryptoExchange.Net</PackageId>
|
<PackageId>CryptoExchange.Net</PackageId>
|
||||||
<Authors>JKorf</Authors>
|
<Authors>JKorf</Authors>
|
||||||
<PackageVersion>0.0.2</PackageVersion>
|
<PackageVersion>0.0.4</PackageVersion>
|
||||||
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
|
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
|
||||||
<PackageProjectUrl>https://github.com/JKorf/CryptoExchange.Net</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/JKorf/CryptoExchange.Net</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/JKorf/CryptoExchange.Net/blob/master/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/JKorf/CryptoExchange.Net/blob/master/LICENSE</PackageLicenseUrl>
|
||||||
|
4
Error.cs
4
Error.cs
@ -30,6 +30,10 @@
|
|||||||
public class ServerError: Error
|
public class ServerError: Error
|
||||||
{
|
{
|
||||||
public ServerError(string message) : base(3, "Server error: " + message) { }
|
public ServerError(string message) : base(3, "Server error: " + message) { }
|
||||||
|
|
||||||
|
public ServerError(int code, string message) : base(code, message)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class WebError : Error
|
public class WebError : Error
|
||||||
|
@ -22,13 +22,13 @@ namespace CryptoExchange.Net
|
|||||||
protected Log log;
|
protected Log log;
|
||||||
protected ApiProxy apiProxy;
|
protected ApiProxy apiProxy;
|
||||||
|
|
||||||
private AuthenticationProvider authProvider;
|
protected AuthenticationProvider authProvider;
|
||||||
private List<IRateLimiter> rateLimiters;
|
private List<IRateLimiter> rateLimiters;
|
||||||
|
|
||||||
protected ExchangeClient(ExchangeOptions exchangeOptions, AuthenticationProvider authentictationProvider)
|
protected ExchangeClient(ExchangeOptions exchangeOptions, AuthenticationProvider authenticationProvider)
|
||||||
{
|
{
|
||||||
log = new Log();
|
log = new Log();
|
||||||
authProvider = authentictationProvider;
|
authProvider = authenticationProvider;
|
||||||
Configure(exchangeOptions);
|
Configure(exchangeOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +80,25 @@ namespace CryptoExchange.Net
|
|||||||
if(signed && authProvider == null)
|
if(signed && authProvider == null)
|
||||||
return new CallResult<T>(null, new NoApiCredentialsError());
|
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();
|
var uriString = uri.ToString();
|
||||||
|
|
||||||
if (parameters != null)
|
if (parameters != null)
|
||||||
@ -96,22 +115,10 @@ namespace CryptoExchange.Net
|
|||||||
var request = RequestFactory.Create(uriString);
|
var request = RequestFactory.Create(uriString);
|
||||||
request.Method = method;
|
request.Method = method;
|
||||||
|
|
||||||
if (apiProxy != null)
|
|
||||||
request.SetProxy(apiProxy.Host, apiProxy.Port);
|
|
||||||
|
|
||||||
if (authProvider != null)
|
if (authProvider != null)
|
||||||
request = authProvider.AddAuthenticationToRequest(request, signed);
|
request = authProvider.AddAuthenticationToRequest(request, signed);
|
||||||
|
|
||||||
foreach (var limiter in rateLimiters)
|
return request;
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<CallResult<string>> ExecuteRequest(IRequest request)
|
private async Task<CallResult<string>> ExecuteRequest(IRequest request)
|
||||||
@ -119,7 +126,7 @@ namespace CryptoExchange.Net
|
|||||||
var returnedData = "";
|
var returnedData = "";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var response = request.GetResponse();
|
var response = await request.GetResponse().ConfigureAwait(false);
|
||||||
using (var reader = new StreamReader(response.GetResponseStream()))
|
using (var reader = new StreamReader(response.GetResponseStream()))
|
||||||
{
|
{
|
||||||
returnedData = await reader.ReadToEndAsync().ConfigureAwait(false);
|
returnedData = await reader.ReadToEndAsync().ConfigureAwait(false);
|
||||||
@ -129,11 +136,11 @@ namespace CryptoExchange.Net
|
|||||||
catch (WebException we)
|
catch (WebException we)
|
||||||
{
|
{
|
||||||
var response = (HttpWebResponse)we.Response;
|
var response = (HttpWebResponse)we.Response;
|
||||||
string responseData = null;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var reader = new StreamReader(response.GetResponseStream());
|
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)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
@ -143,9 +150,6 @@ namespace CryptoExchange.Net
|
|||||||
if (response == null)
|
if (response == null)
|
||||||
return new CallResult<string>(null, new WebError(infoMessage));
|
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));
|
return new CallResult<string>(null, new ServerError(infoMessage));
|
||||||
}
|
}
|
||||||
@ -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
|
private CallResult<T> Deserialize<T>(string data) where T: class
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace CryptoExchange.Net.Interfaces
|
namespace CryptoExchange.Net.Interfaces
|
||||||
{
|
{
|
||||||
@ -10,6 +12,12 @@ namespace CryptoExchange.Net.Interfaces
|
|||||||
string Method { get; set; }
|
string Method { get; set; }
|
||||||
|
|
||||||
void SetProxy(string host, int port);
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using CryptoExchange.Net.Interfaces;
|
using CryptoExchange.Net.Interfaces;
|
||||||
|
|
||||||
namespace CryptoExchange.Net.Requests
|
namespace CryptoExchange.Net.Requests
|
||||||
@ -18,11 +20,30 @@ namespace CryptoExchange.Net.Requests
|
|||||||
get => request.Headers;
|
get => request.Headers;
|
||||||
set => request.Headers = value;
|
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
|
public string Method
|
||||||
{
|
{
|
||||||
get => request.Method;
|
get => request.Method;
|
||||||
set => request.Method = value;
|
set => request.Method = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uri Uri => request.RequestUri;
|
public Uri Uri => request.RequestUri;
|
||||||
|
|
||||||
public void SetProxy(string host, int port)
|
public void SetProxy(string host, int port)
|
||||||
@ -30,9 +51,14 @@ namespace CryptoExchange.Net.Requests
|
|||||||
request.Proxy = new WebProxy(host, port);
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user