mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2025-06-07 07:56:12 +00:00
Removed SecureString usage throughout the library, removed some object allocations, removed some unused extension methods
This commit is contained in:
parent
2f64cd9f05
commit
949780a9ad
@ -51,8 +51,8 @@ namespace CryptoExchange.Net.UnitTests
|
||||
|
||||
// assert
|
||||
Assert.That(options.ReceiveWindow == TimeSpan.FromSeconds(10));
|
||||
Assert.That(options.ApiCredentials.Key.GetString() == "123");
|
||||
Assert.That(options.ApiCredentials.Secret.GetString() == "456");
|
||||
Assert.That(options.ApiCredentials.Key == "123");
|
||||
Assert.That(options.ApiCredentials.Secret == "456");
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -64,10 +64,10 @@ namespace CryptoExchange.Net.UnitTests
|
||||
options.Api2Options.ApiCredentials = new ApiCredentials("789", "101");
|
||||
|
||||
// assert
|
||||
Assert.That(options.Api1Options.ApiCredentials.Key.GetString() == "123");
|
||||
Assert.That(options.Api1Options.ApiCredentials.Secret.GetString() == "456");
|
||||
Assert.That(options.Api2Options.ApiCredentials.Key.GetString() == "789");
|
||||
Assert.That(options.Api2Options.ApiCredentials.Secret.GetString() == "101");
|
||||
Assert.That(options.Api1Options.ApiCredentials.Key == "123");
|
||||
Assert.That(options.Api1Options.ApiCredentials.Secret == "456");
|
||||
Assert.That(options.Api2Options.ApiCredentials.Key == "789");
|
||||
Assert.That(options.Api2Options.ApiCredentials.Secret == "101");
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -176,12 +176,12 @@ namespace CryptoExchange.Net.UnitTests
|
||||
|
||||
for (var i = 0; i < requests + 1; i++)
|
||||
{
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition, "https://test.com", "123".ToSecureString(), 1, RateLimitingBehaviour.Wait, default);
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition, "https://test.com", "123", 1, RateLimitingBehaviour.Wait, default);
|
||||
Assert.That(i == requests? triggered : !triggered);
|
||||
}
|
||||
triggered = false;
|
||||
await Task.Delay((int)Math.Round(perSeconds * 1000) + 10);
|
||||
var result2 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition, "https://test.com", "123".ToSecureString(), 1, RateLimitingBehaviour.Wait, default);
|
||||
var result2 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition, "https://test.com", "123", 1, RateLimitingBehaviour.Wait, default);
|
||||
Assert.That(!triggered);
|
||||
}
|
||||
|
||||
@ -201,7 +201,7 @@ namespace CryptoExchange.Net.UnitTests
|
||||
rateLimiter.RateLimitTriggered += (x) => { evnt = x; };
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition, "https://test.com", "123".ToSecureString(), 1, RateLimitingBehaviour.Wait, default);
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition, "https://test.com", "123", 1, RateLimitingBehaviour.Wait, default);
|
||||
bool expected = i == 1 ? (expectLimiting ? evnt.DelayTime > TimeSpan.Zero : evnt == null) : evnt == null;
|
||||
Assert.That(expected);
|
||||
}
|
||||
@ -222,9 +222,9 @@ namespace CryptoExchange.Net.UnitTests
|
||||
RateLimitEvent evnt = null;
|
||||
rateLimiter.RateLimitTriggered += (x) => { evnt = x; };
|
||||
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition1, "https://test.com", "123".ToSecureString(), 1, RateLimitingBehaviour.Wait, default);
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition1, "https://test.com", "123", 1, RateLimitingBehaviour.Wait, default);
|
||||
Assert.That(evnt == null);
|
||||
var result2 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition2, "https://test.com", "123".ToSecureString(), 1, RateLimitingBehaviour.Wait, default);
|
||||
var result2 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition2, "https://test.com", "123", 1, RateLimitingBehaviour.Wait, default);
|
||||
Assert.That(expectLimiting ? evnt != null : evnt == null);
|
||||
}
|
||||
|
||||
@ -243,12 +243,12 @@ namespace CryptoExchange.Net.UnitTests
|
||||
|
||||
for (var i = 0; i < requests + 1; i++)
|
||||
{
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition, "https://test.com", "123".ToSecureString(), 1, RateLimitingBehaviour.Wait, default);
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition, "https://test.com", "123", 1, RateLimitingBehaviour.Wait, default);
|
||||
Assert.That(i == requests ? triggered : !triggered);
|
||||
}
|
||||
triggered = false;
|
||||
await Task.Delay((int)Math.Round(perSeconds * 1000) + 10);
|
||||
var result2 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition, "https://test.com", "123".ToSecureString(), 1, RateLimitingBehaviour.Wait, default);
|
||||
var result2 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition, "https://test.com", "123", 1, RateLimitingBehaviour.Wait, default);
|
||||
Assert.That(!triggered);
|
||||
}
|
||||
|
||||
@ -266,7 +266,7 @@ namespace CryptoExchange.Net.UnitTests
|
||||
rateLimiter.RateLimitTriggered += (x) => { evnt = x; };
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition, "https://test.com", "123".ToSecureString(), 1, RateLimitingBehaviour.Wait, default);
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition, "https://test.com", "123", 1, RateLimitingBehaviour.Wait, default);
|
||||
bool expected = i == 1 ? (expectLimited ? evnt.DelayTime > TimeSpan.Zero : evnt == null) : evnt == null;
|
||||
Assert.That(expected);
|
||||
}
|
||||
@ -286,7 +286,7 @@ namespace CryptoExchange.Net.UnitTests
|
||||
rateLimiter.RateLimitTriggered += (x) => { evnt = x; };
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition, "https://test.com", "123".ToSecureString(), 1, RateLimitingBehaviour.Wait, default);
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition, "https://test.com", "123", 1, RateLimitingBehaviour.Wait, default);
|
||||
bool expected = i == 1 ? (expectLimited ? evnt.DelayTime > TimeSpan.Zero : evnt == null) : evnt == null;
|
||||
Assert.That(expected);
|
||||
}
|
||||
@ -309,9 +309,9 @@ namespace CryptoExchange.Net.UnitTests
|
||||
RateLimitEvent evnt = null;
|
||||
rateLimiter.RateLimitTriggered += (x) => { evnt = x; };
|
||||
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition1, "https://test.com", key1?.ToSecureString(), 1, RateLimitingBehaviour.Wait, default);
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition1, "https://test.com", key1, 1, RateLimitingBehaviour.Wait, default);
|
||||
Assert.That(evnt == null);
|
||||
var result2 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition2, "https://test.com", key2?.ToSecureString(), 1, RateLimitingBehaviour.Wait, default);
|
||||
var result2 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition2, "https://test.com", key2, 1, RateLimitingBehaviour.Wait, default);
|
||||
Assert.That(expectLimited ? evnt != null : evnt == null);
|
||||
}
|
||||
|
||||
@ -328,7 +328,7 @@ namespace CryptoExchange.Net.UnitTests
|
||||
RateLimitEvent evnt = null;
|
||||
rateLimiter.RateLimitTriggered += (x) => { evnt = x; };
|
||||
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition1, "https://test.com", "123".ToSecureString(), 1, RateLimitingBehaviour.Wait, default);
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition1, "https://test.com", "123", 1, RateLimitingBehaviour.Wait, default);
|
||||
Assert.That(evnt == null);
|
||||
var result2 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition2, "https://test.com", null, 1, RateLimitingBehaviour.Wait, default);
|
||||
Assert.That(expectLimited ? evnt != null : evnt == null);
|
||||
@ -348,9 +348,9 @@ namespace CryptoExchange.Net.UnitTests
|
||||
RateLimitEvent evnt = null;
|
||||
rateLimiter.RateLimitTriggered += (x) => { evnt = x; };
|
||||
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition1, host1, "123".ToSecureString(), 1, RateLimitingBehaviour.Wait, default);
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition1, host1, "123", 1, RateLimitingBehaviour.Wait, default);
|
||||
Assert.That(evnt == null);
|
||||
var result2 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition1, host2, "123".ToSecureString(), 1, RateLimitingBehaviour.Wait, default);
|
||||
var result2 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Request, requestDefinition1, host2, "123", 1, RateLimitingBehaviour.Wait, default);
|
||||
Assert.That(expectLimited ? evnt != null : evnt == null);
|
||||
}
|
||||
|
||||
@ -365,9 +365,9 @@ namespace CryptoExchange.Net.UnitTests
|
||||
RateLimitEvent evnt = null;
|
||||
rateLimiter.RateLimitTriggered += (x) => { evnt = x; };
|
||||
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Connection, new RequestDefinition("1", HttpMethod.Get), host1, "123".ToSecureString(), 1, RateLimitingBehaviour.Wait, default);
|
||||
var result1 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Connection, new RequestDefinition("1", HttpMethod.Get), host1, "123", 1, RateLimitingBehaviour.Wait, default);
|
||||
Assert.That(evnt == null);
|
||||
var result2 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Connection, new RequestDefinition("1", HttpMethod.Get), host2, "123".ToSecureString(), 1, RateLimitingBehaviour.Wait, default);
|
||||
var result2 = await rateLimiter.ProcessAsync(new TraceLogger(), 1, RateLimitItemType.Connection, new RequestDefinition("1", HttpMethod.Get), host2, "123", 1, RateLimitingBehaviour.Wait, default);
|
||||
Assert.That(expectLimited ? evnt != null : evnt == null);
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ namespace CryptoExchange.Net.UnitTests
|
||||
{
|
||||
}
|
||||
|
||||
public string GetKey() => _credentials.Key.GetString();
|
||||
public string GetSecret() => _credentials.Secret.GetString();
|
||||
public string GetKey() => _credentials.Key;
|
||||
public string GetSecret() => _credentials.Secret;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using CryptoExchange.Net.Converters.SystemTextJson;
|
||||
using CryptoExchange.Net.Converters.MessageParsing;
|
||||
|
||||
@ -9,48 +8,23 @@ namespace CryptoExchange.Net.Authentication
|
||||
/// <summary>
|
||||
/// Api credentials, used to sign requests accessing private endpoints
|
||||
/// </summary>
|
||||
public class ApiCredentials: IDisposable
|
||||
public class ApiCredentials
|
||||
{
|
||||
/// <summary>
|
||||
/// The api key to authenticate requests
|
||||
/// </summary>
|
||||
public SecureString? Key { get; }
|
||||
public string Key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The api secret to authenticate requests
|
||||
/// </summary>
|
||||
public SecureString? Secret { get; }
|
||||
public string Secret { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Type of the credentials
|
||||
/// </summary>
|
||||
public ApiCredentialsType CredentialType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Create Api credentials providing an api key and secret for authentication
|
||||
/// </summary>
|
||||
/// <param name="key">The api key used for identification</param>
|
||||
/// <param name="secret">The api secret used for signing</param>
|
||||
public ApiCredentials(SecureString key, SecureString secret) : this(key, secret, ApiCredentialsType.Hmac)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create Api credentials providing an api key and secret for authentication
|
||||
/// </summary>
|
||||
/// <param name="key">The api key used for identification</param>
|
||||
/// <param name="secret">The api secret used for signing</param>
|
||||
/// <param name="credentialsType">The type of credentials</param>
|
||||
public ApiCredentials(SecureString key, SecureString secret, ApiCredentialsType credentialsType)
|
||||
{
|
||||
if (key == null || secret == null)
|
||||
throw new ArgumentException("Key and secret can't be null/empty");
|
||||
|
||||
CredentialType = credentialsType;
|
||||
Key = key;
|
||||
Secret = secret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create Api credentials providing an api key and secret for authentication
|
||||
/// </summary>
|
||||
@ -72,8 +46,8 @@ namespace CryptoExchange.Net.Authentication
|
||||
throw new ArgumentException("Key and secret can't be null/empty");
|
||||
|
||||
CredentialType = credentialsType;
|
||||
Key = key.ToSecureString();
|
||||
Secret = secret.ToSecureString();
|
||||
Key = key;
|
||||
Secret = secret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -82,8 +56,7 @@ namespace CryptoExchange.Net.Authentication
|
||||
/// <returns></returns>
|
||||
public virtual ApiCredentials Copy()
|
||||
{
|
||||
// Use .GetString() to create a copy of the SecureString
|
||||
return new ApiCredentials(Key!.GetString(), Secret!.GetString(), CredentialType);
|
||||
return new ApiCredentials(Key, Secret, CredentialType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -103,19 +76,10 @@ namespace CryptoExchange.Net.Authentication
|
||||
if (key == null || secret == null)
|
||||
throw new ArgumentException("apiKey or apiSecret value not found in Json credential file");
|
||||
|
||||
Key = key.ToSecureString();
|
||||
Secret = secret.ToSecureString();
|
||||
Key = key;
|
||||
Secret = secret;
|
||||
|
||||
inputStream.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Key?.Dispose();
|
||||
Secret?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ namespace CryptoExchange.Net.Authentication
|
||||
/// <summary>
|
||||
/// Base class for authentication providers
|
||||
/// </summary>
|
||||
public abstract class AuthenticationProvider : IDisposable
|
||||
public abstract class AuthenticationProvider
|
||||
{
|
||||
internal IAuthTimeProvider TimeProvider { get; set; } = new AuthTimeProvider();
|
||||
|
||||
@ -28,6 +28,11 @@ namespace CryptoExchange.Net.Authentication
|
||||
/// </summary>
|
||||
protected byte[] _sBytes;
|
||||
|
||||
/// <summary>
|
||||
/// Get the API key of the current credentials
|
||||
/// </summary>
|
||||
public string ApiKey => _credentials.Key;
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
@ -38,7 +43,7 @@ namespace CryptoExchange.Net.Authentication
|
||||
throw new ArgumentException("ApiKey/Secret needed");
|
||||
|
||||
_credentials = credentials;
|
||||
_sBytes = Encoding.UTF8.GetBytes(credentials.Secret.GetString());
|
||||
_sBytes = Encoding.UTF8.GetBytes(credentials.Secret);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -58,9 +63,9 @@ namespace CryptoExchange.Net.Authentication
|
||||
RestApiClient apiClient,
|
||||
Uri uri,
|
||||
HttpMethod method,
|
||||
IDictionary<string, object> uriParameters,
|
||||
IDictionary<string, object> bodyParameters,
|
||||
Dictionary<string, string> headers,
|
||||
ref IDictionary<string, object>? uriParameters,
|
||||
ref IDictionary<string, object>? bodyParameters,
|
||||
ref Dictionary<string, string>? headers,
|
||||
bool auth,
|
||||
ArrayParametersSerialization arraySerialization,
|
||||
HttpMethodParameterPosition parameterPosition,
|
||||
@ -366,7 +371,7 @@ namespace CryptoExchange.Net.Authentication
|
||||
{
|
||||
#if NETSTANDARD2_1_OR_GREATER
|
||||
// Read from pem private key
|
||||
var key = _credentials.Secret!.GetString()
|
||||
var key = _credentials.Secret!
|
||||
.Replace("\n", "")
|
||||
.Replace("-----BEGIN PRIVATE KEY-----", "")
|
||||
.Replace("-----END PRIVATE KEY-----", "")
|
||||
@ -381,7 +386,7 @@ namespace CryptoExchange.Net.Authentication
|
||||
else if (_credentials.CredentialType == ApiCredentialsType.RsaXml)
|
||||
{
|
||||
// Read from xml private key format
|
||||
rsa.FromXmlString(_credentials.Secret!.GetString());
|
||||
rsa.FromXmlString(_credentials.Secret!);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -447,12 +452,6 @@ namespace CryptoExchange.Net.Authentication
|
||||
else
|
||||
return serializer.Serialize(parameters);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
_credentials?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -65,10 +65,7 @@ namespace CryptoExchange.Net.Clients
|
||||
BaseAddress = baseAddress;
|
||||
|
||||
if (apiCredentials != null)
|
||||
{
|
||||
AuthenticationProvider?.Dispose();
|
||||
AuthenticationProvider = CreateAuthenticationProvider(apiCredentials.Copy());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -85,10 +82,7 @@ namespace CryptoExchange.Net.Clients
|
||||
public void SetApiCredentials<T>(T credentials) where T : ApiCredentials
|
||||
{
|
||||
if (credentials != null)
|
||||
{
|
||||
AuthenticationProvider?.Dispose();
|
||||
AuthenticationProvider = CreateAuthenticationProvider(credentials.Copy());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -97,7 +91,6 @@ namespace CryptoExchange.Net.Clients
|
||||
public virtual void Dispose()
|
||||
{
|
||||
_disposing = true;
|
||||
AuthenticationProvider?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -196,19 +196,20 @@ namespace CryptoExchange.Net.Clients
|
||||
Dictionary<string, string>? additionalHeaders = null,
|
||||
int? weight = null) where T : class
|
||||
{
|
||||
var key = baseAddress + definition + uriParameters?.ToFormData();
|
||||
string? cacheKey = null;
|
||||
if (ShouldCache(definition))
|
||||
{
|
||||
_logger.CheckingCache(key);
|
||||
var cachedValue = _cache.Get(key, ClientOptions.CachingMaxAge);
|
||||
cacheKey = baseAddress + definition + uriParameters?.ToFormData();
|
||||
_logger.CheckingCache(cacheKey);
|
||||
var cachedValue = _cache.Get(cacheKey, ClientOptions.CachingMaxAge);
|
||||
if (cachedValue != null)
|
||||
{
|
||||
_logger.CacheHit(key);
|
||||
_logger.CacheHit(cacheKey);
|
||||
var original = (WebCallResult<T>)cachedValue;
|
||||
return original.Cached();
|
||||
}
|
||||
|
||||
_logger.CacheNotHit(key);
|
||||
_logger.CacheNotHit(cacheKey);
|
||||
}
|
||||
|
||||
int currentTry = 0;
|
||||
@ -242,7 +243,7 @@ namespace CryptoExchange.Net.Clients
|
||||
if (result.Success &&
|
||||
ShouldCache(definition))
|
||||
{
|
||||
_cache.Add(key, result);
|
||||
_cache.Add(cacheKey!, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -343,15 +344,15 @@ namespace CryptoExchange.Net.Clients
|
||||
ParameterCollection? bodyParameters,
|
||||
Dictionary<string, string>? additionalHeaders)
|
||||
{
|
||||
var uriParams = uriParameters == null ? new ParameterCollection() : CreateParameterDictionary(uriParameters);
|
||||
var bodyParams = bodyParameters == null ? new ParameterCollection() : CreateParameterDictionary(bodyParameters);
|
||||
var uriParams = uriParameters == null ? null : CreateParameterDictionary(uriParameters);
|
||||
var bodyParams = bodyParameters == null ? null : CreateParameterDictionary(bodyParameters);
|
||||
|
||||
var uri = new Uri(baseAddress.AppendPath(definition.Path));
|
||||
var arraySerialization = definition.ArraySerialization ?? ArraySerialization;
|
||||
var bodyFormat = definition.RequestBodyFormat ?? RequestBodyFormat;
|
||||
var parameterPosition = definition.ParameterPosition ?? ParameterPositions[definition.Method];
|
||||
|
||||
var headers = new Dictionary<string, string>();
|
||||
Dictionary<string, string>? headers = null;
|
||||
if (AuthenticationProvider != null)
|
||||
{
|
||||
try
|
||||
@ -360,9 +361,9 @@ namespace CryptoExchange.Net.Clients
|
||||
this,
|
||||
uri,
|
||||
definition.Method,
|
||||
uriParams,
|
||||
bodyParams,
|
||||
headers,
|
||||
ref uriParams,
|
||||
ref bodyParams,
|
||||
ref headers,
|
||||
definition.Authenticated,
|
||||
arraySerialization,
|
||||
parameterPosition,
|
||||
@ -375,14 +376,18 @@ namespace CryptoExchange.Net.Clients
|
||||
}
|
||||
}
|
||||
|
||||
// Add the auth parameters to the uri, start with a new URI to be able to sort the parameters including the auth parameters
|
||||
uri = uri.SetParameters(uriParams, arraySerialization);
|
||||
// Add the auth parameters to the uri, start with a new URI to be able to sort the parameters including the auth parameters
|
||||
if (uriParams != null)
|
||||
uri = uri.SetParameters(uriParams, arraySerialization);
|
||||
|
||||
var request = RequestFactory.Create(definition.Method, uri, requestId);
|
||||
request.Accept = Constants.JsonContentHeader;
|
||||
|
||||
foreach (var header in headers)
|
||||
request.AddHeader(header.Key, header.Value);
|
||||
if (headers != null)
|
||||
{
|
||||
foreach (var header in headers)
|
||||
request.AddHeader(header.Key, header.Value);
|
||||
}
|
||||
|
||||
if (additionalHeaders != null)
|
||||
{
|
||||
@ -403,7 +408,7 @@ namespace CryptoExchange.Net.Clients
|
||||
if (parameterPosition == HttpMethodParameterPosition.InBody)
|
||||
{
|
||||
var contentType = bodyFormat == RequestBodyFormat.Json ? Constants.JsonContentHeader : Constants.FormContentHeader;
|
||||
if (bodyParams.Count != 0)
|
||||
if (bodyParams != null && bodyParams.Count != 0)
|
||||
WriteParamBody(request, bodyParams, contentType);
|
||||
else
|
||||
request.SetContent(RequestBodyEmptyContent, contentType);
|
||||
@ -817,9 +822,9 @@ namespace CryptoExchange.Net.Clients
|
||||
this,
|
||||
uri,
|
||||
method,
|
||||
uriParameters,
|
||||
bodyParameters,
|
||||
headers,
|
||||
ref uriParameters,
|
||||
ref bodyParameters,
|
||||
ref headers,
|
||||
signed,
|
||||
arraySerialization,
|
||||
parameterPosition,
|
||||
|
@ -1,6 +1,7 @@
|
||||
using CryptoExchange.Net.Objects;
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
|
||||
namespace CryptoExchange.Net
|
||||
{
|
||||
@ -15,10 +16,6 @@ namespace CryptoExchange.Net
|
||||
/// The last used id, use NextId() to get the next id and up this
|
||||
/// </summary>
|
||||
private static int _lastId;
|
||||
/// <summary>
|
||||
/// Lock for id generating
|
||||
/// </summary>
|
||||
private static object _idLock = new();
|
||||
|
||||
/// <summary>
|
||||
/// Clamp a value between a min and max
|
||||
@ -135,24 +132,13 @@ namespace CryptoExchange.Net
|
||||
/// Generate a new unique id. The id is staticly stored so it is guarenteed to be unique
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static int NextId()
|
||||
{
|
||||
lock (_idLock)
|
||||
{
|
||||
_lastId += 1;
|
||||
return _lastId;
|
||||
}
|
||||
}
|
||||
public static int NextId() => Interlocked.Increment(ref _lastId);
|
||||
|
||||
/// <summary>
|
||||
/// Return the last unique id that was generated
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static int LastId()
|
||||
{
|
||||
lock (_idLock)
|
||||
return _lastId;
|
||||
}
|
||||
public static int LastId() => _lastId;
|
||||
|
||||
/// <summary>
|
||||
/// Generate a random string of specified length
|
||||
|
@ -113,92 +113,6 @@ namespace CryptoExchange.Net
|
||||
return formData.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the string the secure string is representing
|
||||
/// </summary>
|
||||
/// <param name="source">The source secure string</param>
|
||||
/// <returns></returns>
|
||||
public static string GetString(this SecureString source)
|
||||
{
|
||||
lock (source)
|
||||
{
|
||||
string result;
|
||||
var length = source.Length;
|
||||
var pointer = IntPtr.Zero;
|
||||
var chars = new char[length];
|
||||
|
||||
try
|
||||
{
|
||||
pointer = Marshal.SecureStringToBSTR(source);
|
||||
Marshal.Copy(pointer, chars, 0, length);
|
||||
|
||||
result = string.Join("", chars);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (pointer != IntPtr.Zero)
|
||||
{
|
||||
Marshal.ZeroFreeBSTR(pointer);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Are 2 secure strings equal
|
||||
/// </summary>
|
||||
/// <param name="ss1">Source secure string</param>
|
||||
/// <param name="ss2">Compare secure string</param>
|
||||
/// <returns>True if equal by value</returns>
|
||||
public static bool IsEqualTo(this SecureString ss1, SecureString ss2)
|
||||
{
|
||||
IntPtr bstr1 = IntPtr.Zero;
|
||||
IntPtr bstr2 = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
bstr1 = Marshal.SecureStringToBSTR(ss1);
|
||||
bstr2 = Marshal.SecureStringToBSTR(ss2);
|
||||
int length1 = Marshal.ReadInt32(bstr1, -4);
|
||||
int length2 = Marshal.ReadInt32(bstr2, -4);
|
||||
if (length1 == length2)
|
||||
{
|
||||
for (int x = 0; x < length1; ++x)
|
||||
{
|
||||
byte b1 = Marshal.ReadByte(bstr1, x);
|
||||
byte b2 = Marshal.ReadByte(bstr2, x);
|
||||
if (b1 != b2) return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (bstr2 != IntPtr.Zero) Marshal.ZeroFreeBSTR(bstr2);
|
||||
if (bstr1 != IntPtr.Zero) Marshal.ZeroFreeBSTR(bstr1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a secure string from a string
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
public static SecureString ToSecureString(this string source)
|
||||
{
|
||||
var secureString = new SecureString();
|
||||
foreach (var c in source)
|
||||
secureString.AppendChar(c);
|
||||
secureString.MakeReadOnly();
|
||||
return secureString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates an int is one of the allowed values
|
||||
/// </summary>
|
||||
@ -318,26 +232,6 @@ namespace CryptoExchange.Net
|
||||
return url.TrimEnd('/');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fill parameters in a path. Parameters are specified by '{}' and should be specified in occuring sequence
|
||||
/// </summary>
|
||||
/// <param name="path">The total path string</param>
|
||||
/// <param name="values">The values to fill</param>
|
||||
/// <returns></returns>
|
||||
public static string FillPathParameters(this string path, params string[] values)
|
||||
{
|
||||
foreach (var value in values)
|
||||
{
|
||||
var index = path.IndexOf("{}", StringComparison.Ordinal);
|
||||
if (index >= 0)
|
||||
{
|
||||
path = path.Remove(index, 2);
|
||||
path = path.Insert(index, value);
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new uri with the provided parameters as query
|
||||
/// </summary>
|
||||
|
@ -24,6 +24,6 @@ namespace CryptoExchange.Net.Interfaces
|
||||
/// <param name="requestWeight">The weight of the request</param>
|
||||
/// <param name="ct">Cancellation token to cancel waiting</param>
|
||||
/// <returns>The time in milliseconds spend waiting</returns>
|
||||
Task<CallResult<int>> LimitRequestAsync(ILogger log, string endpoint, HttpMethod method, bool signed, SecureString? apiKey, RateLimitingBehaviour limitBehaviour, int requestWeight, CancellationToken ct);
|
||||
Task<CallResult<int>> LimitRequestAsync(ILogger log, string endpoint, HttpMethod method, bool signed, string? apiKey, RateLimitingBehaviour limitBehaviour, int requestWeight, CancellationToken ct);
|
||||
}
|
||||
}
|
||||
|
@ -24,14 +24,14 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <summary>
|
||||
/// The password of the proxy
|
||||
/// </summary>
|
||||
public SecureString? Password { get; }
|
||||
public string? Password { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Create new settings for a proxy
|
||||
/// </summary>
|
||||
/// <param name="host">The proxy hostname/ip</param>
|
||||
/// <param name="port">The proxy port</param>
|
||||
public ApiProxy(string host, int port): this(host, port, null, (SecureString?)null)
|
||||
public ApiProxy(string host, int port): this(host, port, null, null)
|
||||
{
|
||||
}
|
||||
|
||||
@ -42,18 +42,7 @@ namespace CryptoExchange.Net.Objects
|
||||
/// <param name="port">The proxy port</param>
|
||||
/// <param name="login">The proxy login</param>
|
||||
/// <param name="password">The proxy password</param>
|
||||
public ApiProxy(string host, int port, string? login, string? password) : this(host, port, login, password?.ToSecureString())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create new settings for a proxy
|
||||
/// </summary>
|
||||
/// <param name="host">The proxy hostname/ip</param>
|
||||
/// <param name="port">The proxy port</param>
|
||||
/// <param name="login">The proxy login</param>
|
||||
/// <param name="password">The proxy password</param>
|
||||
public ApiProxy(string host, int port, string? login, SecureString? password)
|
||||
public ApiProxy(string host, int port, string? login, string? password)
|
||||
{
|
||||
Host = host;
|
||||
Port = port;
|
||||
|
@ -21,7 +21,7 @@ namespace CryptoExchange.Net.RateLimiting.Filters
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Passes(RateLimitItemType type, RequestDefinition definition, string host, SecureString? apiKey)
|
||||
public bool Passes(RateLimitItemType type, RequestDefinition definition, string host, string? apiKey)
|
||||
=> definition.Authenticated == _authenticated;
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ namespace CryptoExchange.Net.RateLimiting.Filters
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Passes(RateLimitItemType type, RequestDefinition definition, string host, SecureString? apiKey)
|
||||
public bool Passes(RateLimitItemType type, RequestDefinition definition, string host, string? apiKey)
|
||||
=> string.Equals(definition.Path, _path, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ namespace CryptoExchange.Net.RateLimiting.Filters
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Passes(RateLimitItemType type, RequestDefinition definition, string host, SecureString? apiKey)
|
||||
public bool Passes(RateLimitItemType type, RequestDefinition definition, string host, string? apiKey)
|
||||
=> _paths.Contains(definition.Path);
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ namespace CryptoExchange.Net.RateLimiting.Filters
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Passes(RateLimitItemType type, RequestDefinition definition, string host, SecureString? apiKey)
|
||||
public bool Passes(RateLimitItemType type, RequestDefinition definition, string host, string? apiKey)
|
||||
=> host == _host;
|
||||
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ namespace CryptoExchange.Net.RateLimiting.Filters
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Passes(RateLimitItemType type, RequestDefinition definition, string host, SecureString? apiKey)
|
||||
public bool Passes(RateLimitItemType type, RequestDefinition definition, string host, string? apiKey)
|
||||
=> type == _type;
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ namespace CryptoExchange.Net.RateLimiting.Filters
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Passes(RateLimitItemType type, RequestDefinition definition, string host, SecureString? apiKey)
|
||||
public bool Passes(RateLimitItemType type, RequestDefinition definition, string host, string? apiKey)
|
||||
=> definition.Path.StartsWith(_path, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
@ -14,26 +14,26 @@ namespace CryptoExchange.Net.RateLimiting.Guards
|
||||
/// <summary>
|
||||
/// Apply guard per host
|
||||
/// </summary>
|
||||
public static Func<RequestDefinition, string, SecureString?, string> PerHost { get; } = new Func<RequestDefinition, string, SecureString?, string>((def, host, key) => host);
|
||||
public static Func<RequestDefinition, string, string?, string> PerHost { get; } = new Func<RequestDefinition, string, string?, string>((def, host, key) => host);
|
||||
/// <summary>
|
||||
/// Apply guard per endpoint
|
||||
/// </summary>
|
||||
public static Func<RequestDefinition, string, SecureString?, string> PerEndpoint { get; } = new Func<RequestDefinition, string, SecureString?, string>((def, host, key) => def.Path + def.Method);
|
||||
public static Func<RequestDefinition, string, string?, string> PerEndpoint { get; } = new Func<RequestDefinition, string, string?, string>((def, host, key) => def.Path + def.Method);
|
||||
/// <summary>
|
||||
/// Apply guard per API key
|
||||
/// </summary>
|
||||
public static Func<RequestDefinition, string, SecureString?, string> PerApiKey { get; } = new Func<RequestDefinition, string, SecureString?, string>((def, host, key) => key!.GetString());
|
||||
public static Func<RequestDefinition, string, string?, string> PerApiKey { get; } = new Func<RequestDefinition, string, string?, string>((def, host, key) => key!);
|
||||
/// <summary>
|
||||
/// Apply guard per API key per endpoint
|
||||
/// </summary>
|
||||
public static Func<RequestDefinition, string, SecureString?, string> PerApiKeyPerEndpoint { get; } = new Func<RequestDefinition, string, SecureString?, string>((def, host, key) => key!.GetString() + def.Path + def.Method);
|
||||
public static Func<RequestDefinition, string, string?, string> PerApiKeyPerEndpoint { get; } = new Func<RequestDefinition, string, string?, string>((def, host, key) => key! + def.Path + def.Method);
|
||||
|
||||
private readonly IEnumerable<IGuardFilter> _filters;
|
||||
private readonly Dictionary<string, IWindowTracker> _trackers;
|
||||
private RateLimitWindowType _windowType;
|
||||
private double? _decayRate;
|
||||
private int? _connectionWeight;
|
||||
private readonly Func<RequestDefinition, string, SecureString?, string> _keySelector;
|
||||
private readonly Func<RequestDefinition, string, string?, string> _keySelector;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "RateLimitGuard";
|
||||
@ -60,7 +60,7 @@ namespace CryptoExchange.Net.RateLimiting.Guards
|
||||
/// <param name="windowType">Type of rate limit window</param>
|
||||
/// <param name="decayPerTimeSpan">The decay per timespan if windowType is DecayWindowTracker</param>
|
||||
/// <param name="connectionWeight">The weight of a new connection</param>
|
||||
public RateLimitGuard(Func<RequestDefinition, string, SecureString?, string> keySelector, IGuardFilter filter, int limit, TimeSpan timeSpan, RateLimitWindowType windowType, double? decayPerTimeSpan = null, int? connectionWeight = null)
|
||||
public RateLimitGuard(Func<RequestDefinition, string, string?, string> keySelector, IGuardFilter filter, int limit, TimeSpan timeSpan, RateLimitWindowType windowType, double? decayPerTimeSpan = null, int? connectionWeight = null)
|
||||
: this(keySelector, new[] { filter }, limit, timeSpan, windowType, decayPerTimeSpan, connectionWeight)
|
||||
{
|
||||
}
|
||||
@ -75,7 +75,7 @@ namespace CryptoExchange.Net.RateLimiting.Guards
|
||||
/// <param name="windowType">Type of rate limit window</param>
|
||||
/// <param name="decayPerTimeSpan">The decay per timespan if windowType is DecayWindowTracker</param>
|
||||
/// <param name="connectionWeight">The weight of a new connection</param>
|
||||
public RateLimitGuard(Func<RequestDefinition, string, SecureString?, string> keySelector, IEnumerable<IGuardFilter> filters, int limit, TimeSpan timeSpan, RateLimitWindowType windowType, double? decayPerTimeSpan = null, int? connectionWeight = null)
|
||||
public RateLimitGuard(Func<RequestDefinition, string, string?, string> keySelector, IEnumerable<IGuardFilter> filters, int limit, TimeSpan timeSpan, RateLimitWindowType windowType, double? decayPerTimeSpan = null, int? connectionWeight = null)
|
||||
{
|
||||
_filters = filters;
|
||||
_trackers = new Dictionary<string, IWindowTracker>();
|
||||
@ -88,7 +88,7 @@ namespace CryptoExchange.Net.RateLimiting.Guards
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public LimitCheck Check(RateLimitItemType type, RequestDefinition definition, string host, SecureString? apiKey, int requestWeight)
|
||||
public LimitCheck Check(RateLimitItemType type, RequestDefinition definition, string host, string? apiKey, int requestWeight)
|
||||
{
|
||||
foreach(var filter in _filters)
|
||||
{
|
||||
@ -114,7 +114,7 @@ namespace CryptoExchange.Net.RateLimiting.Guards
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RateLimitState ApplyWeight(RateLimitItemType type, RequestDefinition definition, string host, SecureString? apiKey, int requestWeight)
|
||||
public RateLimitState ApplyWeight(RateLimitItemType type, RequestDefinition definition, string host, string? apiKey, int requestWeight)
|
||||
{
|
||||
foreach (var filter in _filters)
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ namespace CryptoExchange.Net.RateLimiting.Guards
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public LimitCheck Check(RateLimitItemType type, RequestDefinition definition, string host, SecureString? apiKey, int requestWeight)
|
||||
public LimitCheck Check(RateLimitItemType type, RequestDefinition definition, string host, string? apiKey, int requestWeight)
|
||||
{
|
||||
var dif = (After + _windowBuffer) - DateTime.UtcNow;
|
||||
if (dif <= TimeSpan.Zero)
|
||||
@ -48,7 +48,7 @@ namespace CryptoExchange.Net.RateLimiting.Guards
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RateLimitState ApplyWeight(RateLimitItemType type, RequestDefinition definition, string host, SecureString? apiKey, int requestWeight)
|
||||
public RateLimitState ApplyWeight(RateLimitItemType type, RequestDefinition definition, string host, string? apiKey, int requestWeight)
|
||||
{
|
||||
return RateLimitState.NotApplied;
|
||||
}
|
||||
|
@ -15,19 +15,19 @@ namespace CryptoExchange.Net.RateLimiting.Guards
|
||||
/// <summary>
|
||||
/// Default endpoint limit
|
||||
/// </summary>
|
||||
public static Func<RequestDefinition, string, SecureString?, string> Default { get; } = new Func<RequestDefinition, string, SecureString?, string>((def, host, key) => def.Path + def.Method);
|
||||
public static Func<RequestDefinition, string, string?, string> Default { get; } = new Func<RequestDefinition, string, string?, string>((def, host, key) => def.Path + def.Method);
|
||||
|
||||
/// <summary>
|
||||
/// Endpoint limit per API key
|
||||
/// </summary>
|
||||
public static Func<RequestDefinition, string, SecureString?, string> PerApiKey { get; } = new Func<RequestDefinition, string, SecureString?, string>((def, host, key) => def.Path + def.Method);
|
||||
public static Func<RequestDefinition, string, string?, string> PerApiKey { get; } = new Func<RequestDefinition, string, string?, string>((def, host, key) => def.Path + def.Method);
|
||||
|
||||
private readonly Dictionary<string, IWindowTracker> _trackers;
|
||||
private readonly RateLimitWindowType _windowType;
|
||||
private readonly double? _decayRate;
|
||||
private readonly int _limit;
|
||||
private readonly TimeSpan _period;
|
||||
private readonly Func<RequestDefinition, string, SecureString?, string> _keySelector;
|
||||
private readonly Func<RequestDefinition, string, string?, string> _keySelector;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "EndpointLimitGuard";
|
||||
@ -43,7 +43,7 @@ namespace CryptoExchange.Net.RateLimiting.Guards
|
||||
TimeSpan period,
|
||||
RateLimitWindowType windowType,
|
||||
double? decayRate = null,
|
||||
Func<RequestDefinition, string, SecureString?, string>? keySelector = null)
|
||||
Func<RequestDefinition, string, string?, string>? keySelector = null)
|
||||
{
|
||||
_limit = limit;
|
||||
_period = period;
|
||||
@ -54,7 +54,7 @@ namespace CryptoExchange.Net.RateLimiting.Guards
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public LimitCheck Check(RateLimitItemType type, RequestDefinition definition, string host, SecureString? apiKey, int requestWeight)
|
||||
public LimitCheck Check(RateLimitItemType type, RequestDefinition definition, string host, string? apiKey, int requestWeight)
|
||||
{
|
||||
var key = _keySelector(definition, host, apiKey);
|
||||
if (!_trackers.TryGetValue(key, out var tracker))
|
||||
@ -71,7 +71,7 @@ namespace CryptoExchange.Net.RateLimiting.Guards
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public RateLimitState ApplyWeight(RateLimitItemType type, RequestDefinition definition, string host, SecureString? apiKey, int requestWeight)
|
||||
public RateLimitState ApplyWeight(RateLimitItemType type, RequestDefinition definition, string host, string? apiKey, int requestWeight)
|
||||
{
|
||||
var key = _keySelector(definition, host, apiKey);
|
||||
var tracker = _trackers[key];
|
||||
|
@ -16,6 +16,6 @@ namespace CryptoExchange.Net.RateLimiting.Interfaces
|
||||
/// <param name="host">The host address</param>
|
||||
/// <param name="apiKey">The API key</param>
|
||||
/// <returns>True if passed</returns>
|
||||
bool Passes(RateLimitItemType type, RequestDefinition definition, string host, SecureString? apiKey);
|
||||
bool Passes(RateLimitItemType type, RequestDefinition definition, string host, string? apiKey);
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ namespace CryptoExchange.Net.RateLimiting.Interfaces
|
||||
/// <param name="behaviour">Behaviour when rate limit is hit</param>
|
||||
/// <param name="ct">Cancelation token</param>
|
||||
/// <returns>Error if RateLimitingBehaviour is Fail and rate limit is hit</returns>
|
||||
Task<CallResult> ProcessAsync(ILogger logger, int itemId, RateLimitItemType type, RequestDefinition definition, string baseAddress, SecureString? apiKey, int requestWeight, RateLimitingBehaviour behaviour, CancellationToken ct);
|
||||
Task<CallResult> ProcessAsync(ILogger logger, int itemId, RateLimitItemType type, RequestDefinition definition, string baseAddress, string? apiKey, int requestWeight, RateLimitingBehaviour behaviour, CancellationToken ct);
|
||||
|
||||
/// <summary>
|
||||
/// Enforces the rate limit as defined in the request definition. When a rate limit is hit will wait for the rate limit to pass if RateLimitingBehaviour is Wait, or return an error if it is set to Fail
|
||||
@ -66,6 +66,6 @@ namespace CryptoExchange.Net.RateLimiting.Interfaces
|
||||
/// <param name="behaviour">Behaviour when rate limit is hit</param>
|
||||
/// <param name="ct">Cancelation token</param>
|
||||
/// <returns>Error if RateLimitingBehaviour is Fail and rate limit is hit</returns>
|
||||
Task<CallResult> ProcessSingleAsync(ILogger logger, int itemId, IRateLimitGuard guard, RateLimitItemType type, RequestDefinition definition, string baseAddress, SecureString? apiKey, RateLimitingBehaviour behaviour, CancellationToken ct);
|
||||
Task<CallResult> ProcessSingleAsync(ILogger logger, int itemId, IRateLimitGuard guard, RateLimitItemType type, RequestDefinition definition, string baseAddress, string? apiKey, RateLimitingBehaviour behaviour, CancellationToken ct);
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ namespace CryptoExchange.Net.RateLimiting.Interfaces
|
||||
/// <param name="apiKey">The API key</param>
|
||||
/// <param name="requestWeight">The request weight</param>
|
||||
/// <returns></returns>
|
||||
LimitCheck Check(RateLimitItemType type, RequestDefinition definition, string host, SecureString? apiKey, int requestWeight);
|
||||
LimitCheck Check(RateLimitItemType type, RequestDefinition definition, string host, string? apiKey, int requestWeight);
|
||||
|
||||
/// <summary>
|
||||
/// Apply the request to this guard with the specified weight
|
||||
@ -39,6 +39,6 @@ namespace CryptoExchange.Net.RateLimiting.Interfaces
|
||||
/// <param name="apiKey">The API key</param>
|
||||
/// <param name="requestWeight">The request weight</param>
|
||||
/// <returns></returns>
|
||||
RateLimitState ApplyWeight(RateLimitItemType type, RequestDefinition definition, string host, SecureString? apiKey, int requestWeight);
|
||||
RateLimitState ApplyWeight(RateLimitItemType type, RequestDefinition definition, string host, string? apiKey, int requestWeight);
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ namespace CryptoExchange.Net.RateLimiting
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<CallResult> ProcessAsync(ILogger logger, int itemId, RateLimitItemType type, RequestDefinition definition, string host, SecureString? apiKey, int requestWeight, RateLimitingBehaviour rateLimitingBehaviour, CancellationToken ct)
|
||||
public async Task<CallResult> ProcessAsync(ILogger logger, int itemId, RateLimitItemType type, RequestDefinition definition, string host, string? apiKey, int requestWeight, RateLimitingBehaviour rateLimitingBehaviour, CancellationToken ct)
|
||||
{
|
||||
await _semaphore.WaitAsync(ct).ConfigureAwait(false);
|
||||
_waitingCount++;
|
||||
@ -58,8 +58,8 @@ namespace CryptoExchange.Net.RateLimiting
|
||||
IRateLimitGuard guard,
|
||||
RateLimitItemType type,
|
||||
RequestDefinition definition,
|
||||
string host,
|
||||
SecureString? apiKey,
|
||||
string host,
|
||||
string? apiKey,
|
||||
RateLimitingBehaviour rateLimitingBehaviour,
|
||||
CancellationToken ct)
|
||||
{
|
||||
@ -77,7 +77,7 @@ namespace CryptoExchange.Net.RateLimiting
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<CallResult> CheckGuardsAsync(IEnumerable<IRateLimitGuard> guards, ILogger logger, int itemId, RateLimitItemType type, RequestDefinition definition, string host, SecureString? apiKey, int requestWeight, RateLimitingBehaviour rateLimitingBehaviour, CancellationToken ct)
|
||||
private async Task<CallResult> CheckGuardsAsync(IEnumerable<IRateLimitGuard> guards, ILogger logger, int itemId, RateLimitItemType type, RequestDefinition definition, string host, string? apiKey, int requestWeight, RateLimitingBehaviour rateLimitingBehaviour, CancellationToken ct)
|
||||
{
|
||||
foreach (var guard in guards)
|
||||
{
|
||||
|
@ -131,9 +131,9 @@ namespace CryptoExchange.Net.Testing
|
||||
client,
|
||||
new Uri(host.AppendPath(path)),
|
||||
method,
|
||||
uriParams,
|
||||
bodyParams,
|
||||
headers,
|
||||
ref uriParams,
|
||||
ref bodyParams,
|
||||
ref headers,
|
||||
true,
|
||||
client.ArraySerialization,
|
||||
client.ParameterPositions[method],
|
||||
|
Loading…
x
Reference in New Issue
Block a user