mirror of
				https://github.com/JKorf/CryptoExchange.Net
				synced 2025-10-28 17:07:44 +00:00 
			
		
		
		
	Added option to send additional headers for each request or for individual requests, added HttpMethod parameter position configuration to rest client
This commit is contained in:
		
							parent
							
								
									f5df46a8a5
								
							
						
					
					
						commit
						d1a2856a08
					
				| @ -10,6 +10,8 @@ using System.Linq; | |||||||
| using CryptoExchange.Net.Interfaces; | using CryptoExchange.Net.Interfaces; | ||||||
| using CryptoExchange.Net.RateLimiter; | using CryptoExchange.Net.RateLimiter; | ||||||
| using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||||
|  | using System.Net.Http; | ||||||
|  | using System.Threading.Tasks; | ||||||
| 
 | 
 | ||||||
| namespace CryptoExchange.Net.UnitTests | namespace CryptoExchange.Net.UnitTests | ||||||
| { | { | ||||||
| @ -22,7 +24,7 @@ namespace CryptoExchange.Net.UnitTests | |||||||
|             // arrange |             // arrange | ||||||
|             var client = new TestRestClient(); |             var client = new TestRestClient(); | ||||||
|             var expected = new TestObject() { DecimalData = 1.23M, IntData = 10, StringData = "Some data" }; |             var expected = new TestObject() { DecimalData = 1.23M, IntData = 10, StringData = "Some data" }; | ||||||
|             client.SetResponse(JsonConvert.SerializeObject(expected)); |             client.SetResponse(JsonConvert.SerializeObject(expected), out _); | ||||||
| 
 | 
 | ||||||
|             // act |             // act | ||||||
|             var result = client.Request<TestObject>().Result; |             var result = client.Request<TestObject>().Result; | ||||||
| @ -37,7 +39,7 @@ namespace CryptoExchange.Net.UnitTests | |||||||
|         { |         { | ||||||
|             // arrange |             // arrange | ||||||
|             var client = new TestRestClient(); |             var client = new TestRestClient(); | ||||||
|             client.SetResponse("{\"property\": 123"); |             client.SetResponse("{\"property\": 123", out _); | ||||||
| 
 | 
 | ||||||
|             // act |             // act | ||||||
|             var result = client.Request<TestObject>().Result; |             var result = client.Request<TestObject>().Result; | ||||||
| @ -119,6 +121,46 @@ namespace CryptoExchange.Net.UnitTests | |||||||
|             Assert.IsTrue(client.RequestTimeout == TimeSpan.FromMinutes(1)); |             Assert.IsTrue(client.RequestTimeout == TimeSpan.FromMinutes(1)); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         [TestCase("GET", HttpMethodParameterPosition.InUri)] // No need to test InBody for GET since thats not valid | ||||||
|  |         [TestCase("POST", HttpMethodParameterPosition.InBody)] | ||||||
|  |         [TestCase("POST", HttpMethodParameterPosition.InUri)] | ||||||
|  |         [TestCase("DELETE", HttpMethodParameterPosition.InBody)] | ||||||
|  |         [TestCase("DELETE", HttpMethodParameterPosition.InUri)] | ||||||
|  |         [TestCase("PUT", HttpMethodParameterPosition.InUri)] | ||||||
|  |         [TestCase("PUT", HttpMethodParameterPosition.InBody)] | ||||||
|  |         public async Task Setting_Should_ResultInOptionsSet(string method, HttpMethodParameterPosition pos) | ||||||
|  |         { | ||||||
|  |             // arrange | ||||||
|  |             // act | ||||||
|  |             var client = new TestRestClient(new RestClientOptions("") | ||||||
|  |             { | ||||||
|  |                 BaseAddress = "http://test.address.com", | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |             client.SetParameterPosition(new HttpMethod(method), pos); | ||||||
|  | 
 | ||||||
|  |             client.SetResponse("{}", out var request); | ||||||
|  | 
 | ||||||
|  |             await client.RequestWithParams<TestObject>(new HttpMethod(method), new Dictionary<string, object> | ||||||
|  |             { | ||||||
|  |                 { "TestParam1", "Value1" }, | ||||||
|  |                 { "TestParam2", 2 }, | ||||||
|  |             }, | ||||||
|  |             new Dictionary<string, string> | ||||||
|  |             { | ||||||
|  |                 { "TestHeader", "123" } | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |             // assert | ||||||
|  |             Assert.AreEqual(request.Method, new HttpMethod(method)); | ||||||
|  |             Assert.AreEqual(request.Content?.Contains("TestParam1") == true, pos == HttpMethodParameterPosition.InBody); | ||||||
|  |             Assert.AreEqual(request.Uri.ToString().Contains("TestParam1"), pos == HttpMethodParameterPosition.InUri); | ||||||
|  |             Assert.AreEqual(request.Content?.Contains("TestParam2") == true, pos == HttpMethodParameterPosition.InBody); | ||||||
|  |             Assert.AreEqual(request.Uri.ToString().Contains("TestParam2"), pos == HttpMethodParameterPosition.InUri); | ||||||
|  |             Assert.AreEqual(request.GetHeaders().First().Key, "TestHeader"); | ||||||
|  |             Assert.IsTrue(request.GetHeaders().First().Value.Contains("123")); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         [TestCase] |         [TestCase] | ||||||
|         public void SettingRateLimitingBehaviourToFail_Should_FailLimitedRequests() |         public void SettingRateLimitingBehaviourToFail_Should_FailLimitedRequests() | ||||||
|         { |         { | ||||||
| @ -128,12 +170,12 @@ namespace CryptoExchange.Net.UnitTests | |||||||
|                 RateLimiters = new List<IRateLimiter> { new RateLimiterTotal(1, TimeSpan.FromSeconds(1)) }, |                 RateLimiters = new List<IRateLimiter> { new RateLimiterTotal(1, TimeSpan.FromSeconds(1)) }, | ||||||
|                 RateLimitingBehaviour = RateLimitingBehaviour.Fail |                 RateLimitingBehaviour = RateLimitingBehaviour.Fail | ||||||
|             }); |             }); | ||||||
|             client.SetResponse("{\"property\": 123}"); |             client.SetResponse("{\"property\": 123}", out _); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|             // act |             // act | ||||||
|             var result1 = client.Request<TestObject>().Result; |             var result1 = client.Request<TestObject>().Result; | ||||||
|             client.SetResponse("{\"property\": 123}"); |             client.SetResponse("{\"property\": 123}", out _); | ||||||
|             var result2 = client.Request<TestObject>().Result; |             var result2 = client.Request<TestObject>().Result; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -151,13 +193,13 @@ namespace CryptoExchange.Net.UnitTests | |||||||
|                 RateLimiters = new List<IRateLimiter> { new RateLimiterTotal(1, TimeSpan.FromSeconds(1)) }, |                 RateLimiters = new List<IRateLimiter> { new RateLimiterTotal(1, TimeSpan.FromSeconds(1)) }, | ||||||
|                 RateLimitingBehaviour = RateLimitingBehaviour.Wait |                 RateLimitingBehaviour = RateLimitingBehaviour.Wait | ||||||
|             }); |             }); | ||||||
|             client.SetResponse("{\"property\": 123}"); |             client.SetResponse("{\"property\": 123}", out _); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|             // act |             // act | ||||||
|             var sw = Stopwatch.StartNew(); |             var sw = Stopwatch.StartNew(); | ||||||
|             var result1 = client.Request<TestObject>().Result; |             var result1 = client.Request<TestObject>().Result; | ||||||
|             client.SetResponse("{\"property\": 123}"); // reset response stream |             client.SetResponse("{\"property\": 123}", out _); // reset response stream | ||||||
|             var result2 = client.Request<TestObject>().Result; |             var result2 = client.Request<TestObject>().Result; | ||||||
|             sw.Stop(); |             sw.Stop(); | ||||||
| 
 | 
 | ||||||
| @ -178,17 +220,17 @@ namespace CryptoExchange.Net.UnitTests | |||||||
|                 LogLevel = LogLevel.Debug, |                 LogLevel = LogLevel.Debug, | ||||||
|                 ApiCredentials = new ApiCredentials("TestKey", "TestSecret") |                 ApiCredentials = new ApiCredentials("TestKey", "TestSecret") | ||||||
|             }); |             }); | ||||||
|             client.SetResponse("{\"property\": 123}"); |             client.SetResponse("{\"property\": 123}", out _); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|             // act |             // act | ||||||
|             var sw = Stopwatch.StartNew(); |             var sw = Stopwatch.StartNew(); | ||||||
|             var result1 = client.Request<TestObject>().Result; |             var result1 = client.Request<TestObject>().Result; | ||||||
|             client.SetKey("TestKey2", "TestSecret2"); // set to different key |             client.SetKey("TestKey2", "TestSecret2"); // set to different key | ||||||
|             client.SetResponse("{\"property\": 123}"); // reset response stream |             client.SetResponse("{\"property\": 123}", out _); // reset response stream | ||||||
|             var result2 = client.Request<TestObject>().Result; |             var result2 = client.Request<TestObject>().Result; | ||||||
|             client.SetKey("TestKey", "TestSecret"); // set back to original key, should delay |             client.SetKey("TestKey", "TestSecret"); // set back to original key, should delay | ||||||
|             client.SetResponse("{\"property\": 123}"); // reset response stream |             client.SetResponse("{\"property\": 123}", out _); // reset response stream | ||||||
|             var result3 = client.Request<TestObject>().Result; |             var result3 = client.Request<TestObject>().Result; | ||||||
|             sw.Stop(); |             sw.Stop(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -38,12 +38,12 @@ namespace CryptoExchange.Net.UnitTests | |||||||
|         { |         { | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public override Dictionary<string, string> AddAuthenticationToHeaders(string uri, HttpMethod method, Dictionary<string, object> parameters, bool signed, PostParameters postParameters, ArrayParametersSerialization arraySerialization) |         public override Dictionary<string, string> AddAuthenticationToHeaders(string uri, HttpMethod method, Dictionary<string, object> parameters, bool signed, HttpMethodParameterPosition postParameters, ArrayParametersSerialization arraySerialization) | ||||||
|         { |         { | ||||||
|             return base.AddAuthenticationToHeaders(uri, method, parameters, signed, postParameters, arraySerialization); |             return base.AddAuthenticationToHeaders(uri, method, parameters, signed, postParameters, arraySerialization); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public override Dictionary<string, object> AddAuthenticationToParameters(string uri, HttpMethod method, Dictionary<string, object> parameters, bool signed, PostParameters postParameters, ArrayParametersSerialization arraySerialization) |         public override Dictionary<string, object> AddAuthenticationToParameters(string uri, HttpMethod method, Dictionary<string, object> parameters, bool signed, HttpMethodParameterPosition postParameters, ArrayParametersSerialization arraySerialization) | ||||||
|         { |         { | ||||||
|             return base.AddAuthenticationToParameters(uri, method, parameters, signed, postParameters, arraySerialization); |             return base.AddAuthenticationToParameters(uri, method, parameters, signed, postParameters, arraySerialization); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ using System.Text; | |||||||
| using System.Threading; | using System.Threading; | ||||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||||
| using CryptoExchange.Net.Authentication; | using CryptoExchange.Net.Authentication; | ||||||
|  | using System.Collections.Generic; | ||||||
| 
 | 
 | ||||||
| namespace CryptoExchange.Net.UnitTests.TestImplementations | namespace CryptoExchange.Net.UnitTests.TestImplementations | ||||||
| { | { | ||||||
| @ -26,12 +27,17 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations | |||||||
|             RequestFactory = new Mock<IRequestFactory>().Object; |             RequestFactory = new Mock<IRequestFactory>().Object; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         public void SetParameterPosition(HttpMethod method, HttpMethodParameterPosition position) | ||||||
|  |         { | ||||||
|  |             ParameterPositions[method] = position; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         public void SetKey(string key, string secret) |         public void SetKey(string key, string secret) | ||||||
|         { |         { | ||||||
|             SetAuthenticationProvider(new UnitTests.TestAuthProvider(new ApiCredentials(key, secret))); |             SetAuthenticationProvider(new UnitTests.TestAuthProvider(new ApiCredentials(key, secret))); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public void SetResponse(string responseData, Stream requestStream = null) |         public void SetResponse(string responseData, out IRequest requestObj) | ||||||
|         { |         { | ||||||
|             var expectedBytes = Encoding.UTF8.GetBytes(responseData); |             var expectedBytes = Encoding.UTF8.GetBytes(responseData); | ||||||
|             var responseStream = new MemoryStream(); |             var responseStream = new MemoryStream(); | ||||||
| @ -42,13 +48,23 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations | |||||||
|             response.Setup(c => c.IsSuccessStatusCode).Returns(true); |             response.Setup(c => c.IsSuccessStatusCode).Returns(true); | ||||||
|             response.Setup(c => c.GetResponseStreamAsync()).Returns(Task.FromResult((Stream)responseStream)); |             response.Setup(c => c.GetResponseStreamAsync()).Returns(Task.FromResult((Stream)responseStream)); | ||||||
|              |              | ||||||
|  |             var headers = new Dictionary<string, IEnumerable<string>>(); | ||||||
|             var request = new Mock<IRequest>(); |             var request = new Mock<IRequest>(); | ||||||
|             request.Setup(c => c.Uri).Returns(new Uri("http://www.test.com")); |             request.Setup(c => c.Uri).Returns(new Uri("http://www.test.com")); | ||||||
|             request.Setup(c => c.GetResponseAsync(It.IsAny<CancellationToken>())).Returns(Task.FromResult(response.Object)); |             request.Setup(c => c.GetResponseAsync(It.IsAny<CancellationToken>())).Returns(Task.FromResult(response.Object)); | ||||||
|  |             request.Setup(c => c.SetContent(It.IsAny<string>(), It.IsAny<string>())).Callback(new Action<string, string>((content, type) => { request.Setup(r => r.Content).Returns(content); })); | ||||||
|  |             request.Setup(c => c.AddHeader(It.IsAny<string>(), It.IsAny<string>())).Callback<string, string>((key, val) => headers.Add(key, new List<string> { val })); | ||||||
|  |             request.Setup(c => c.GetHeaders()).Returns(() => headers); | ||||||
| 
 | 
 | ||||||
|             var factory = Mock.Get(RequestFactory); |             var factory = Mock.Get(RequestFactory); | ||||||
|             factory.Setup(c => c.Create(It.IsAny<HttpMethod>(), It.IsAny<string>(), It.IsAny<int>())) |             factory.Setup(c => c.Create(It.IsAny<HttpMethod>(), It.IsAny<string>(), It.IsAny<int>())) | ||||||
|  |                 .Callback<HttpMethod, string, int>((method, uri, id) =>  | ||||||
|  |                 {  | ||||||
|  |                     request.Setup(a => a.Uri).Returns(new Uri(uri)); | ||||||
|  |                     request.Setup(a => a.Method).Returns(method);  | ||||||
|  |                 }) | ||||||
|                 .Returns(request.Object); |                 .Returns(request.Object); | ||||||
|  |             requestObj = request.Object; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public void SetErrorWithoutResponse(HttpStatusCode code, string message) |         public void SetErrorWithoutResponse(HttpStatusCode code, string message) | ||||||
| @ -75,12 +91,16 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations | |||||||
|             response.Setup(c => c.IsSuccessStatusCode).Returns(false); |             response.Setup(c => c.IsSuccessStatusCode).Returns(false); | ||||||
|             response.Setup(c => c.GetResponseStreamAsync()).Returns(Task.FromResult((Stream)responseStream)); |             response.Setup(c => c.GetResponseStreamAsync()).Returns(Task.FromResult((Stream)responseStream)); | ||||||
| 
 | 
 | ||||||
|  |             var headers = new Dictionary<string, IEnumerable<string>>(); | ||||||
|             var request = new Mock<IRequest>(); |             var request = new Mock<IRequest>(); | ||||||
|             request.Setup(c => c.Uri).Returns(new Uri("http://www.test.com")); |             request.Setup(c => c.Uri).Returns(new Uri("http://www.test.com")); | ||||||
|             request.Setup(c => c.GetResponseAsync(It.IsAny<CancellationToken>())).Returns(Task.FromResult(response.Object)); |             request.Setup(c => c.GetResponseAsync(It.IsAny<CancellationToken>())).Returns(Task.FromResult(response.Object)); | ||||||
|  |             request.Setup(c => c.AddHeader(It.IsAny<string>(), It.IsAny<string>())).Callback<string, string>((key, val) => headers.Add(key, new List<string> { val })); | ||||||
|  |             request.Setup(c => c.GetHeaders()).Returns(headers); | ||||||
| 
 | 
 | ||||||
|             var factory = Mock.Get(RequestFactory); |             var factory = Mock.Get(RequestFactory); | ||||||
|             factory.Setup(c => c.Create(It.IsAny<HttpMethod>(), It.IsAny<string>(), It.IsAny<int>())) |             factory.Setup(c => c.Create(It.IsAny<HttpMethod>(), It.IsAny<string>(), It.IsAny<int>())) | ||||||
|  |                 .Callback<HttpMethod, string, int>((method, uri, id) => request.Setup(a => a.Uri).Returns(new Uri(uri))) | ||||||
|                 .Returns(request.Object); |                 .Returns(request.Object); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -88,6 +108,11 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations | |||||||
|         { |         { | ||||||
|             return await SendRequestAsync<T>(new Uri("http://www.test.com"), HttpMethod.Get, ct); |             return await SendRequestAsync<T>(new Uri("http://www.test.com"), HttpMethod.Get, ct); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         public async Task<CallResult<T>> RequestWithParams<T>(HttpMethod method, Dictionary<string, object> parameters, Dictionary<string, string> headers) where T : class | ||||||
|  |         { | ||||||
|  |             return await SendRequestAsync<T>(new Uri("http://www.test.com"), method, default, parameters, additionalHeaders: headers); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public class TestAuthProvider : AuthenticationProvider |     public class TestAuthProvider : AuthenticationProvider | ||||||
|  | |||||||
| @ -30,11 +30,11 @@ namespace CryptoExchange.Net.Authentication | |||||||
|         /// <param name="method">The HTTP method of the request</param> |         /// <param name="method">The HTTP method of the request</param> | ||||||
|         /// <param name="parameters">The provided parameters for the request</param> |         /// <param name="parameters">The provided parameters for the request</param> | ||||||
|         /// <param name="signed">Wether or not the request needs to be signed. If not typically the parameters list can just be returned</param> |         /// <param name="signed">Wether or not the request needs to be signed. If not typically the parameters list can just be returned</param> | ||||||
|         /// <param name="postParameterPosition">Where post parameters are placed, in the URI or in the request body</param> |         /// <param name="parameterPosition">Where parameters are placed, in the URI or in the request body</param> | ||||||
|         /// <param name="arraySerialization">How array parameters are serialized</param> |         /// <param name="arraySerialization">How array parameters are serialized</param> | ||||||
|         /// <returns>Should return the original parameter list including any authentication parameters needed</returns> |         /// <returns>Should return the original parameter list including any authentication parameters needed</returns> | ||||||
|         public virtual Dictionary<string, object> AddAuthenticationToParameters(string uri, HttpMethod method, Dictionary<string, object> parameters, bool signed, |         public virtual Dictionary<string, object> AddAuthenticationToParameters(string uri, HttpMethod method, Dictionary<string, object> parameters, bool signed, | ||||||
|             PostParameters postParameterPosition, ArrayParametersSerialization arraySerialization) |             HttpMethodParameterPosition parameterPosition, ArrayParametersSerialization arraySerialization) | ||||||
|         { |         { | ||||||
|             return parameters; |             return parameters; | ||||||
|         } |         } | ||||||
| @ -46,11 +46,11 @@ namespace CryptoExchange.Net.Authentication | |||||||
|         /// <param name="method">The HTTP method of the request</param> |         /// <param name="method">The HTTP method of the request</param> | ||||||
|         /// <param name="parameters">The provided parameters for the request</param> |         /// <param name="parameters">The provided parameters for the request</param> | ||||||
|         /// <param name="signed">Wether or not the request needs to be signed. If not typically the parameters list can just be returned</param> |         /// <param name="signed">Wether or not the request needs to be signed. If not typically the parameters list can just be returned</param> | ||||||
|         /// <param name="postParameterPosition">Where post parameters are placed, in the URI or in the request body</param> |         /// <param name="parameterPosition">Where post parameters are placed, in the URI or in the request body</param> | ||||||
|         /// <param name="arraySerialization">How array parameters are serialized</param> |         /// <param name="arraySerialization">How array parameters are serialized</param> | ||||||
|         /// <returns>Should return a dictionary containing any header key/value pairs needed for authenticating the request</returns> |         /// <returns>Should return a dictionary containing any header key/value pairs needed for authenticating the request</returns> | ||||||
|         public virtual Dictionary<string, string> AddAuthenticationToHeaders(string uri, HttpMethod method, Dictionary<string, object> parameters, bool signed, |         public virtual Dictionary<string, string> AddAuthenticationToHeaders(string uri, HttpMethod method, Dictionary<string, object> parameters, bool signed, | ||||||
|             PostParameters postParameterPosition, ArrayParametersSerialization arraySerialization) |             HttpMethodParameterPosition parameterPosition, ArrayParametersSerialization arraySerialization) | ||||||
|         { |         { | ||||||
|             return new Dictionary<string, string>(); |             return new Dictionary<string, string>(); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -97,7 +97,7 @@ | |||||||
|             </summary> |             </summary> | ||||||
|             <param name="credentials"></param> |             <param name="credentials"></param> | ||||||
|         </member> |         </member> | ||||||
|         <member name="M:CryptoExchange.Net.Authentication.AuthenticationProvider.AddAuthenticationToParameters(System.String,System.Net.Http.HttpMethod,System.Collections.Generic.Dictionary{System.String,System.Object},System.Boolean,CryptoExchange.Net.Objects.PostParameters,CryptoExchange.Net.Objects.ArrayParametersSerialization)"> |         <member name="M:CryptoExchange.Net.Authentication.AuthenticationProvider.AddAuthenticationToParameters(System.String,System.Net.Http.HttpMethod,System.Collections.Generic.Dictionary{System.String,System.Object},System.Boolean,CryptoExchange.Net.Objects.HttpMethodParameterPosition,CryptoExchange.Net.Objects.ArrayParametersSerialization)"> | ||||||
|             <summary> |             <summary> | ||||||
|             Add authentication to the parameter list based on the provided credentials |             Add authentication to the parameter list based on the provided credentials | ||||||
|             </summary> |             </summary> | ||||||
| @ -105,11 +105,11 @@ | |||||||
|             <param name="method">The HTTP method of the request</param> |             <param name="method">The HTTP method of the request</param> | ||||||
|             <param name="parameters">The provided parameters for the request</param> |             <param name="parameters">The provided parameters for the request</param> | ||||||
|             <param name="signed">Wether or not the request needs to be signed. If not typically the parameters list can just be returned</param> |             <param name="signed">Wether or not the request needs to be signed. If not typically the parameters list can just be returned</param> | ||||||
|             <param name="postParameterPosition">Where post parameters are placed, in the URI or in the request body</param> |             <param name="parameterPosition">Where parameters are placed, in the URI or in the request body</param> | ||||||
|             <param name="arraySerialization">How array parameters are serialized</param> |             <param name="arraySerialization">How array parameters are serialized</param> | ||||||
|             <returns>Should return the original parameter list including any authentication parameters needed</returns> |             <returns>Should return the original parameter list including any authentication parameters needed</returns> | ||||||
|         </member> |         </member> | ||||||
|         <member name="M:CryptoExchange.Net.Authentication.AuthenticationProvider.AddAuthenticationToHeaders(System.String,System.Net.Http.HttpMethod,System.Collections.Generic.Dictionary{System.String,System.Object},System.Boolean,CryptoExchange.Net.Objects.PostParameters,CryptoExchange.Net.Objects.ArrayParametersSerialization)"> |         <member name="M:CryptoExchange.Net.Authentication.AuthenticationProvider.AddAuthenticationToHeaders(System.String,System.Net.Http.HttpMethod,System.Collections.Generic.Dictionary{System.String,System.Object},System.Boolean,CryptoExchange.Net.Objects.HttpMethodParameterPosition,CryptoExchange.Net.Objects.ArrayParametersSerialization)"> | ||||||
|             <summary> |             <summary> | ||||||
|             Add authentication to the header dictionary based on the provided credentials |             Add authentication to the header dictionary based on the provided credentials | ||||||
|             </summary> |             </summary> | ||||||
| @ -117,7 +117,7 @@ | |||||||
|             <param name="method">The HTTP method of the request</param> |             <param name="method">The HTTP method of the request</param> | ||||||
|             <param name="parameters">The provided parameters for the request</param> |             <param name="parameters">The provided parameters for the request</param> | ||||||
|             <param name="signed">Wether or not the request needs to be signed. If not typically the parameters list can just be returned</param> |             <param name="signed">Wether or not the request needs to be signed. If not typically the parameters list can just be returned</param> | ||||||
|             <param name="postParameterPosition">Where post parameters are placed, in the URI or in the request body</param> |             <param name="parameterPosition">Where post parameters are placed, in the URI or in the request body</param> | ||||||
|             <param name="arraySerialization">How array parameters are serialized</param> |             <param name="arraySerialization">How array parameters are serialized</param> | ||||||
|             <returns>Should return a dictionary containing any header key/value pairs needed for authenticating the request</returns> |             <returns>Should return a dictionary containing any header key/value pairs needed for authenticating the request</returns> | ||||||
|         </member> |         </member> | ||||||
| @ -1163,6 +1163,12 @@ | |||||||
|             <param name="key"></param> |             <param name="key"></param> | ||||||
|             <param name="value"></param> |             <param name="value"></param> | ||||||
|         </member> |         </member> | ||||||
|  |         <member name="M:CryptoExchange.Net.Interfaces.IRequest.GetHeaders"> | ||||||
|  |             <summary> | ||||||
|  |             Get all headers | ||||||
|  |             </summary> | ||||||
|  |             <returns></returns> | ||||||
|  |         </member> | ||||||
|         <member name="M:CryptoExchange.Net.Interfaces.IRequest.GetResponseAsync(System.Threading.CancellationToken)"> |         <member name="M:CryptoExchange.Net.Interfaces.IRequest.GetResponseAsync(System.Threading.CancellationToken)"> | ||||||
|             <summary> |             <summary> | ||||||
|             Get the response |             Get the response | ||||||
| @ -1934,19 +1940,19 @@ | |||||||
|             Wait till the request can be send |             Wait till the request can be send | ||||||
|             </summary> |             </summary> | ||||||
|         </member> |         </member> | ||||||
|         <member name="T:CryptoExchange.Net.Objects.PostParameters"> |         <member name="T:CryptoExchange.Net.Objects.HttpMethodParameterPosition"> | ||||||
|             <summary> |             <summary> | ||||||
|             Where the parameters for a post request should be added |             Where the parameters for a HttpMethod should be added in a request | ||||||
|             </summary> |             </summary> | ||||||
|         </member> |         </member> | ||||||
|         <member name="F:CryptoExchange.Net.Objects.PostParameters.InBody"> |         <member name="F:CryptoExchange.Net.Objects.HttpMethodParameterPosition.InBody"> | ||||||
|             <summary> |             <summary> | ||||||
|             Post parameters in body |             Parameters in body | ||||||
|             </summary> |             </summary> | ||||||
|         </member> |         </member> | ||||||
|         <member name="F:CryptoExchange.Net.Objects.PostParameters.InUri"> |         <member name="F:CryptoExchange.Net.Objects.HttpMethodParameterPosition.InUri"> | ||||||
|             <summary> |             <summary> | ||||||
|             Post parameters in url |             Parameters in url | ||||||
|             </summary> |             </summary> | ||||||
|         </member> |         </member> | ||||||
|         <member name="T:CryptoExchange.Net.Objects.RequestBodyFormat"> |         <member name="T:CryptoExchange.Net.Objects.RequestBodyFormat"> | ||||||
| @ -2802,6 +2808,9 @@ | |||||||
|         <member name="M:CryptoExchange.Net.Requests.Request.AddHeader(System.String,System.String)"> |         <member name="M:CryptoExchange.Net.Requests.Request.AddHeader(System.String,System.String)"> | ||||||
|             <inheritdoc /> |             <inheritdoc /> | ||||||
|         </member> |         </member> | ||||||
|  |         <member name="M:CryptoExchange.Net.Requests.Request.GetHeaders"> | ||||||
|  |             <inheritdoc /> | ||||||
|  |         </member> | ||||||
|         <member name="M:CryptoExchange.Net.Requests.Request.SetContent(System.Byte[])"> |         <member name="M:CryptoExchange.Net.Requests.Request.SetContent(System.Byte[])"> | ||||||
|             <inheritdoc /> |             <inheritdoc /> | ||||||
|         </member> |         </member> | ||||||
| @ -2855,9 +2864,9 @@ | |||||||
|             The factory for creating requests. Used for unit testing |             The factory for creating requests. Used for unit testing | ||||||
|             </summary> |             </summary> | ||||||
|         </member> |         </member> | ||||||
|         <member name="F:CryptoExchange.Net.RestClient.postParametersPosition"> |         <member name="P:CryptoExchange.Net.RestClient.ParameterPositions"> | ||||||
|             <summary> |             <summary> | ||||||
|             Where to place post parameters by default |             Where to put the parameters for requests with different Http methods | ||||||
|             </summary> |             </summary> | ||||||
|         </member> |         </member> | ||||||
|         <member name="F:CryptoExchange.Net.RestClient.requestBodyFormat"> |         <member name="F:CryptoExchange.Net.RestClient.requestBodyFormat"> | ||||||
| @ -2900,6 +2909,11 @@ | |||||||
|             Total requests made by this client |             Total requests made by this client | ||||||
|             </summary> |             </summary> | ||||||
|         </member> |         </member> | ||||||
|  |         <member name="P:CryptoExchange.Net.RestClient.StandardRequestHeaders"> | ||||||
|  |             <summary> | ||||||
|  |             Request headers to be sent with each request | ||||||
|  |             </summary> | ||||||
|  |         </member> | ||||||
|         <member name="M:CryptoExchange.Net.RestClient.#ctor(System.String,CryptoExchange.Net.Objects.RestClientOptions,CryptoExchange.Net.Authentication.AuthenticationProvider)"> |         <member name="M:CryptoExchange.Net.RestClient.#ctor(System.String,CryptoExchange.Net.Objects.RestClientOptions,CryptoExchange.Net.Authentication.AuthenticationProvider)"> | ||||||
|             <summary> |             <summary> | ||||||
|             ctor |             ctor | ||||||
| @ -2931,7 +2945,7 @@ | |||||||
|             </summary> |             </summary> | ||||||
|             <returns>The roundtrip time of the ping request</returns> |             <returns>The roundtrip time of the ping request</returns> | ||||||
|         </member> |         </member> | ||||||
|         <member name="M:CryptoExchange.Net.RestClient.SendRequestAsync``1(System.Uri,System.Net.Http.HttpMethod,System.Threading.CancellationToken,System.Collections.Generic.Dictionary{System.String,System.Object},System.Boolean,System.Boolean,System.Nullable{CryptoExchange.Net.Objects.PostParameters},System.Nullable{CryptoExchange.Net.Objects.ArrayParametersSerialization},System.Int32,Newtonsoft.Json.JsonSerializer)"> |         <member name="M:CryptoExchange.Net.RestClient.SendRequestAsync``1(System.Uri,System.Net.Http.HttpMethod,System.Threading.CancellationToken,System.Collections.Generic.Dictionary{System.String,System.Object},System.Boolean,System.Boolean,System.Nullable{CryptoExchange.Net.Objects.HttpMethodParameterPosition},System.Nullable{CryptoExchange.Net.Objects.ArrayParametersSerialization},System.Int32,Newtonsoft.Json.JsonSerializer,System.Collections.Generic.Dictionary{System.String,System.String})"> | ||||||
|             <summary> |             <summary> | ||||||
|             Execute a request to the uri and deserialize the response into the provided type parameter |             Execute a request to the uri and deserialize the response into the provided type parameter | ||||||
|             </summary> |             </summary> | ||||||
| @ -2942,10 +2956,11 @@ | |||||||
|             <param name="parameters">The parameters of the request</param> |             <param name="parameters">The parameters of the request</param> | ||||||
|             <param name="signed">Whether or not the request should be authenticated</param> |             <param name="signed">Whether or not the request should be authenticated</param> | ||||||
|             <param name="checkResult">Whether or not the resulting object should be checked for missing properties in the mapping (only outputs if log verbosity is Debug)</param>  |             <param name="checkResult">Whether or not the resulting object should be checked for missing properties in the mapping (only outputs if log verbosity is Debug)</param>  | ||||||
|             <param name="postPosition">Where the post parameters should be placed, overwrites the value set in the client</param> |             <param name="parameterPosition">Where the parameters should be placed, overwrites the value set in the client</param> | ||||||
|             <param name="arraySerialization">How array parameters should be serialized, overwrites the value set in the client</param> |             <param name="arraySerialization">How array parameters should be serialized, overwrites the value set in the client</param> | ||||||
|             <param name="credits">Credits used for the request</param> |             <param name="credits">Credits used for the request</param> | ||||||
|             <param name="deserializer">The JsonSerializer to use for deserialization</param> |             <param name="deserializer">The JsonSerializer to use for deserialization</param> | ||||||
|  |             <param name="additionalHeaders">Additional headers to send with the request</param> | ||||||
|             <returns></returns> |             <returns></returns> | ||||||
|         </member> |         </member> | ||||||
|         <member name="M:CryptoExchange.Net.RestClient.GetResponseAsync``1(CryptoExchange.Net.Interfaces.IRequest,Newtonsoft.Json.JsonSerializer,System.Threading.CancellationToken)"> |         <member name="M:CryptoExchange.Net.RestClient.GetResponseAsync``1(CryptoExchange.Net.Interfaces.IRequest,Newtonsoft.Json.JsonSerializer,System.Threading.CancellationToken)"> | ||||||
| @ -2966,7 +2981,7 @@ | |||||||
|             <param name="data">Received data</param> |             <param name="data">Received data</param> | ||||||
|             <returns>Null if not an error, Error otherwise</returns> |             <returns>Null if not an error, Error otherwise</returns> | ||||||
|         </member> |         </member> | ||||||
|         <member name="M:CryptoExchange.Net.RestClient.ConstructRequest(System.Uri,System.Net.Http.HttpMethod,System.Collections.Generic.Dictionary{System.String,System.Object},System.Boolean,CryptoExchange.Net.Objects.PostParameters,CryptoExchange.Net.Objects.ArrayParametersSerialization,System.Int32)"> |         <member name="M:CryptoExchange.Net.RestClient.ConstructRequest(System.Uri,System.Net.Http.HttpMethod,System.Collections.Generic.Dictionary{System.String,System.Object},System.Boolean,CryptoExchange.Net.Objects.HttpMethodParameterPosition,CryptoExchange.Net.Objects.ArrayParametersSerialization,System.Int32,System.Collections.Generic.Dictionary{System.String,System.String})"> | ||||||
|             <summary> |             <summary> | ||||||
|             Creates a request object |             Creates a request object | ||||||
|             </summary> |             </summary> | ||||||
| @ -2974,9 +2989,10 @@ | |||||||
|             <param name="method">The method of the request</param> |             <param name="method">The method of the request</param> | ||||||
|             <param name="parameters">The parameters of the request</param> |             <param name="parameters">The parameters of the request</param> | ||||||
|             <param name="signed">Whether or not the request should be authenticated</param> |             <param name="signed">Whether or not the request should be authenticated</param> | ||||||
|             <param name="postPosition">Where the post parameters should be placed</param> |             <param name="parameterPosition">Where the parameters should be placed</param> | ||||||
|             <param name="arraySerialization">How array parameters should be serialized</param> |             <param name="arraySerialization">How array parameters should be serialized</param> | ||||||
|             <param name="requestId">Unique id of a request</param> |             <param name="requestId">Unique id of a request</param> | ||||||
|  |             <param name="additionalHeaders">Additional headers to send with the request</param> | ||||||
|             <returns></returns> |             <returns></returns> | ||||||
|         </member> |         </member> | ||||||
|         <member name="M:CryptoExchange.Net.RestClient.WriteParamBody(CryptoExchange.Net.Interfaces.IRequest,System.Collections.Generic.Dictionary{System.String,System.Object},System.String)"> |         <member name="M:CryptoExchange.Net.RestClient.WriteParamBody(CryptoExchange.Net.Interfaces.IRequest,System.Collections.Generic.Dictionary{System.String,System.Object},System.String)"> | ||||||
| @ -3924,148 +3940,5 @@ | |||||||
|         <member name="M:CryptoExchange.Net.Sockets.WebsocketFactory.CreateWebsocket(CryptoExchange.Net.Logging.Log,System.String,System.Collections.Generic.IDictionary{System.String,System.String},System.Collections.Generic.IDictionary{System.String,System.String})"> |         <member name="M:CryptoExchange.Net.Sockets.WebsocketFactory.CreateWebsocket(CryptoExchange.Net.Logging.Log,System.String,System.Collections.Generic.IDictionary{System.String,System.String},System.Collections.Generic.IDictionary{System.String,System.String})"> | ||||||
|             <inheritdoc /> |             <inheritdoc /> | ||||||
|         </member> |         </member> | ||||||
|         <member name="T:System.Diagnostics.CodeAnalysis.AllowNullAttribute"> |  | ||||||
|             <summary> |  | ||||||
|                 Specifies that <see langword="null"/> is allowed as an input even if the |  | ||||||
|                 corresponding type disallows it. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="M:System.Diagnostics.CodeAnalysis.AllowNullAttribute.#ctor"> |  | ||||||
|             <summary> |  | ||||||
|                 Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.AllowNullAttribute"/> class. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="T:System.Diagnostics.CodeAnalysis.DisallowNullAttribute"> |  | ||||||
|             <summary> |  | ||||||
|                 Specifies that <see langword="null"/> is disallowed as an input even if the |  | ||||||
|                 corresponding type allows it. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="M:System.Diagnostics.CodeAnalysis.DisallowNullAttribute.#ctor"> |  | ||||||
|             <summary> |  | ||||||
|                 Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.DisallowNullAttribute"/> class. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="T:System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute"> |  | ||||||
|             <summary> |  | ||||||
|                 Specifies that a method that will never return under any circumstance. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="M:System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute.#ctor"> |  | ||||||
|             <summary> |  | ||||||
|                 Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute"/> class. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="T:System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute"> |  | ||||||
|             <summary> |  | ||||||
|                 Specifies that the method will not return if the associated <see cref="T:System.Boolean"/> |  | ||||||
|                 parameter is passed the specified value. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="P:System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute.ParameterValue"> |  | ||||||
|             <summary> |  | ||||||
|                 Gets the condition parameter value. |  | ||||||
|                 Code after the method is considered unreachable by diagnostics if the argument |  | ||||||
|                 to the associated parameter matches this value. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="M:System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute.#ctor(System.Boolean)"> |  | ||||||
|             <summary> |  | ||||||
|                 Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute"/> |  | ||||||
|                 class with the specified parameter value. |  | ||||||
|             </summary> |  | ||||||
|             <param name="parameterValue"> |  | ||||||
|                 The condition parameter value. |  | ||||||
|                 Code after the method is considered unreachable by diagnostics if the argument |  | ||||||
|                 to the associated parameter matches this value. |  | ||||||
|             </param> |  | ||||||
|         </member> |  | ||||||
|         <member name="T:System.Diagnostics.CodeAnalysis.MaybeNullAttribute"> |  | ||||||
|             <summary> |  | ||||||
|                 Specifies that an output may be <see langword="null"/> even if the |  | ||||||
|                 corresponding type disallows it. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="M:System.Diagnostics.CodeAnalysis.MaybeNullAttribute.#ctor"> |  | ||||||
|             <summary> |  | ||||||
|                 Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.MaybeNullAttribute"/> class. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="T:System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute"> |  | ||||||
|             <summary> |  | ||||||
|                 Specifies that when a method returns <see cref="P:System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute.ReturnValue"/>,  |  | ||||||
|                 the parameter may be <see langword="null"/> even if the corresponding type disallows it. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="P:System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute.ReturnValue"> |  | ||||||
|             <summary> |  | ||||||
|                 Gets the return value condition. |  | ||||||
|                 If the method returns this value, the associated parameter may be <see langword="null"/>. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="M:System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute.#ctor(System.Boolean)"> |  | ||||||
|             <summary> |  | ||||||
|                  Initializes the attribute with the specified return value condition. |  | ||||||
|             </summary> |  | ||||||
|             <param name="returnValue"> |  | ||||||
|                 The return value condition. |  | ||||||
|                 If the method returns this value, the associated parameter may be <see langword="null"/>. |  | ||||||
|             </param> |  | ||||||
|         </member> |  | ||||||
|         <member name="T:System.Diagnostics.CodeAnalysis.NotNullAttribute"> |  | ||||||
|             <summary> |  | ||||||
|                 Specifies that an output is not <see langword="null"/> even if the |  | ||||||
|                 corresponding type allows it. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="M:System.Diagnostics.CodeAnalysis.NotNullAttribute.#ctor"> |  | ||||||
|             <summary> |  | ||||||
|                 Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.NotNullAttribute"/> class. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="T:System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute"> |  | ||||||
|             <summary> |  | ||||||
|                 Specifies that the output will be non-<see langword="null"/> if the |  | ||||||
|                 named parameter is non-<see langword="null"/>. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="P:System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute.ParameterName"> |  | ||||||
|             <summary> |  | ||||||
|                 Gets the associated parameter name. |  | ||||||
|                 The output will be non-<see langword="null"/> if the argument to the |  | ||||||
|                 parameter specified is non-<see langword="null"/>. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="M:System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute.#ctor(System.String)"> |  | ||||||
|             <summary> |  | ||||||
|                 Initializes the attribute with the associated parameter name. |  | ||||||
|             </summary> |  | ||||||
|             <param name="parameterName"> |  | ||||||
|                 The associated parameter name. |  | ||||||
|                 The output will be non-<see langword="null"/> if the argument to the |  | ||||||
|                 parameter specified is non-<see langword="null"/>. |  | ||||||
|             </param> |  | ||||||
|         </member> |  | ||||||
|         <member name="T:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute"> |  | ||||||
|             <summary> |  | ||||||
|                 Specifies that when a method returns <see cref="P:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute.ReturnValue"/>, |  | ||||||
|                 the parameter will not be <see langword="null"/> even if the corresponding type allows it. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="P:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute.ReturnValue"> |  | ||||||
|             <summary> |  | ||||||
|                 Gets the return value condition. |  | ||||||
|                 If the method returns this value, the associated parameter will not be <see langword="null"/>. |  | ||||||
|             </summary> |  | ||||||
|         </member> |  | ||||||
|         <member name="M:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute.#ctor(System.Boolean)"> |  | ||||||
|             <summary> |  | ||||||
|                 Initializes the attribute with the specified return value condition. |  | ||||||
|             </summary> |  | ||||||
|             <param name="returnValue"> |  | ||||||
|                 The return value condition. |  | ||||||
|                 If the method returns this value, the associated parameter will not be <see langword="null"/>. |  | ||||||
|             </param> |  | ||||||
|         </member> |  | ||||||
|     </members> |     </members> | ||||||
| </doc> | </doc> | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| using System; | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
| using System.Net.Http; | using System.Net.Http; | ||||||
| using System.Threading; | using System.Threading; | ||||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||||
| @ -48,6 +49,13 @@ namespace CryptoExchange.Net.Interfaces | |||||||
|         /// <param name="key"></param> |         /// <param name="key"></param> | ||||||
|         /// <param name="value"></param> |         /// <param name="value"></param> | ||||||
|         void AddHeader(string key, string value); |         void AddHeader(string key, string value); | ||||||
|  | 
 | ||||||
|  |         /// <summary> | ||||||
|  |         /// Get all headers | ||||||
|  |         /// </summary> | ||||||
|  |         /// <returns></returns> | ||||||
|  |         Dictionary<string, IEnumerable<string>> GetHeaders(); | ||||||
|  | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Get the response |         /// Get the response | ||||||
|         /// </summary> |         /// </summary> | ||||||
|  | |||||||
| @ -16,16 +16,16 @@ | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     /// Where the parameters for a post request should be added |     /// Where the parameters for a HttpMethod should be added in a request | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     public enum PostParameters |     public enum HttpMethodParameterPosition | ||||||
|     { |     { | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Post parameters in body |         /// Parameters in body | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         InBody, |         InBody, | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Post parameters in url |         /// Parameters in url | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         InUri |         InUri | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -1,4 +1,6 @@ | |||||||
| using System; | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Linq; | ||||||
| using System.Net.Http; | using System.Net.Http; | ||||||
| using System.Net.Http.Headers; | using System.Net.Http.Headers; | ||||||
| using System.Text; | using System.Text; | ||||||
| @ -63,6 +65,12 @@ namespace CryptoExchange.Net.Requests | |||||||
|             request.Headers.Add(key, value); |             request.Headers.Add(key, value); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         /// <inheritdoc /> | ||||||
|  |         public Dictionary<string, IEnumerable<string>> GetHeaders() | ||||||
|  |         { | ||||||
|  |             return request.Headers.ToDictionary(h => h.Key, h => h.Value); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         /// <inheritdoc /> |         /// <inheritdoc /> | ||||||
|         public void SetContent(byte[] data) |         public void SetContent(byte[] data) | ||||||
|         { |         { | ||||||
|  | |||||||
| @ -32,9 +32,15 @@ namespace CryptoExchange.Net | |||||||
|         public IRequestFactory RequestFactory { get; set; } = new RequestFactory(); |         public IRequestFactory RequestFactory { get; set; } = new RequestFactory(); | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Where to place post parameters by default |         /// Where to put the parameters for requests with different Http methods | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         protected PostParameters postParametersPosition = PostParameters.InBody; |         protected Dictionary<HttpMethod, HttpMethodParameterPosition> ParameterPositions { get; set; } = new Dictionary<HttpMethod, HttpMethodParameterPosition> | ||||||
|  |         {  | ||||||
|  |             { HttpMethod.Get, HttpMethodParameterPosition.InUri }, | ||||||
|  |             { HttpMethod.Post, HttpMethodParameterPosition.InBody }, | ||||||
|  |             { HttpMethod.Delete, HttpMethodParameterPosition.InBody }, | ||||||
|  |             { HttpMethod.Put, HttpMethodParameterPosition.InBody } | ||||||
|  |         }; | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Request body content type |         /// Request body content type | ||||||
| @ -73,6 +79,11 @@ namespace CryptoExchange.Net | |||||||
|         /// </summary> |         /// </summary> | ||||||
|         public int TotalRequestsMade { get; private set; } |         public int TotalRequestsMade { get; private set; } | ||||||
| 
 | 
 | ||||||
|  |         /// <summary> | ||||||
|  |         /// Request headers to be sent with each request | ||||||
|  |         /// </summary> | ||||||
|  |         protected Dictionary<string, string>? StandardRequestHeaders { get; set; } | ||||||
|  | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// ctor |         /// ctor | ||||||
|         /// </summary> |         /// </summary> | ||||||
| @ -167,16 +178,25 @@ namespace CryptoExchange.Net | |||||||
|         /// <param name="parameters">The parameters of the request</param> |         /// <param name="parameters">The parameters of the request</param> | ||||||
|         /// <param name="signed">Whether or not the request should be authenticated</param> |         /// <param name="signed">Whether or not the request should be authenticated</param> | ||||||
|         /// <param name="checkResult">Whether or not the resulting object should be checked for missing properties in the mapping (only outputs if log verbosity is Debug)</param>  |         /// <param name="checkResult">Whether or not the resulting object should be checked for missing properties in the mapping (only outputs if log verbosity is Debug)</param>  | ||||||
|         /// <param name="postPosition">Where the post parameters should be placed, overwrites the value set in the client</param> |         /// <param name="parameterPosition">Where the parameters should be placed, overwrites the value set in the client</param> | ||||||
|         /// <param name="arraySerialization">How array parameters should be serialized, overwrites the value set in the client</param> |         /// <param name="arraySerialization">How array parameters should be serialized, overwrites the value set in the client</param> | ||||||
|         /// <param name="credits">Credits used for the request</param> |         /// <param name="credits">Credits used for the request</param> | ||||||
|         /// <param name="deserializer">The JsonSerializer to use for deserialization</param> |         /// <param name="deserializer">The JsonSerializer to use for deserialization</param> | ||||||
|  |         /// <param name="additionalHeaders">Additional headers to send with the request</param> | ||||||
|         /// <returns></returns> |         /// <returns></returns> | ||||||
|         [return: NotNull] |         [return: NotNull] | ||||||
|         protected virtual async Task<WebCallResult<T>> SendRequestAsync<T>(Uri uri, HttpMethod method, CancellationToken cancellationToken, |         protected virtual async Task<WebCallResult<T>> SendRequestAsync<T>( | ||||||
|             Dictionary<string, object>? parameters = null, bool signed = false, bool checkResult = true,  |             Uri uri,  | ||||||
|             PostParameters? postPosition = null, ArrayParametersSerialization? arraySerialization = null, int credits = 1, |             HttpMethod method,  | ||||||
|             JsonSerializer? deserializer = null) where T : class |             CancellationToken cancellationToken, | ||||||
|  |             Dictionary<string, object>? parameters = null,  | ||||||
|  |             bool signed = false,  | ||||||
|  |             bool checkResult = true, | ||||||
|  |             HttpMethodParameterPosition? parameterPosition = null, | ||||||
|  |             ArrayParametersSerialization? arraySerialization = null,  | ||||||
|  |             int credits = 1, | ||||||
|  |             JsonSerializer? deserializer = null, | ||||||
|  |             Dictionary<string, string>? additionalHeaders = null) where T : class | ||||||
|         { |         { | ||||||
|             var requestId = NextId(); |             var requestId = NextId(); | ||||||
|             log.Write(LogLevel.Debug, $"[{requestId}] Creating request for " + uri); |             log.Write(LogLevel.Debug, $"[{requestId}] Creating request for " + uri); | ||||||
| @ -186,7 +206,8 @@ namespace CryptoExchange.Net | |||||||
|                 return new WebCallResult<T>(null, null, null, new NoApiCredentialsError()); |                 return new WebCallResult<T>(null, null, null, new NoApiCredentialsError()); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             var request = ConstructRequest(uri, method, parameters, signed, postPosition ?? postParametersPosition, arraySerialization ?? this.arraySerialization, requestId); |             var paramsPosition = parameterPosition ?? ParameterPositions[method]; | ||||||
|  |             var request = ConstructRequest(uri, method, parameters, signed, paramsPosition, arraySerialization ?? this.arraySerialization, requestId, additionalHeaders); | ||||||
|             foreach (var limiter in RateLimiters) |             foreach (var limiter in RateLimiters) | ||||||
|             { |             { | ||||||
|                 var limitResult = limiter.LimitRequest(this, uri.AbsolutePath, RateLimitBehaviour, credits); |                 var limitResult = limiter.LimitRequest(this, uri.AbsolutePath, RateLimitBehaviour, credits); | ||||||
| @ -201,9 +222,16 @@ namespace CryptoExchange.Net | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             string? paramString = null; |             string? paramString = null; | ||||||
|             if (method == HttpMethod.Post) |             if (parameterPosition == HttpMethodParameterPosition.InBody) | ||||||
|                 paramString = " with request body " + request.Content; |                 paramString = " with request body " + request.Content; | ||||||
| 
 | 
 | ||||||
|  |             if (log.Level == LogLevel.Trace) | ||||||
|  |             { | ||||||
|  |                 var headers = request.GetHeaders(); | ||||||
|  |                 if (headers.Any()) | ||||||
|  |                     paramString = " with headers " + string.Join(", ", headers.Select(h => h.Key + $"=[{string.Join(",", h.Value)}]")); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             log.Write(LogLevel.Debug, $"[{requestId}] Sending {method}{(signed ? " signed" : "")} request to {request.Uri}{paramString ?? " "}{(apiProxy == null ? "" : $" via proxy {apiProxy.Host}")}"); |             log.Write(LogLevel.Debug, $"[{requestId}] Sending {method}{(signed ? " signed" : "")} request to {request.Uri}{paramString ?? " "}{(apiProxy == null ? "" : $" via proxy {apiProxy.Host}")}"); | ||||||
|             return await GetResponseAsync<T>(request, deserializer, cancellationToken).ConfigureAwait(false); |             return await GetResponseAsync<T>(request, deserializer, cancellationToken).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
| @ -320,20 +348,29 @@ namespace CryptoExchange.Net | |||||||
|         /// <param name="method">The method of the request</param> |         /// <param name="method">The method of the request</param> | ||||||
|         /// <param name="parameters">The parameters of the request</param> |         /// <param name="parameters">The parameters of the request</param> | ||||||
|         /// <param name="signed">Whether or not the request should be authenticated</param> |         /// <param name="signed">Whether or not the request should be authenticated</param> | ||||||
|         /// <param name="postPosition">Where the post parameters should be placed</param> |         /// <param name="parameterPosition">Where the parameters should be placed</param> | ||||||
|         /// <param name="arraySerialization">How array parameters should be serialized</param> |         /// <param name="arraySerialization">How array parameters should be serialized</param> | ||||||
|         /// <param name="requestId">Unique id of a request</param> |         /// <param name="requestId">Unique id of a request</param> | ||||||
|  |         /// <param name="additionalHeaders">Additional headers to send with the request</param> | ||||||
|         /// <returns></returns> |         /// <returns></returns> | ||||||
|         protected virtual IRequest ConstructRequest(Uri uri, HttpMethod method, Dictionary<string, object>? parameters, bool signed, PostParameters postPosition, ArrayParametersSerialization arraySerialization, int requestId) |         protected virtual IRequest ConstructRequest( | ||||||
|  |             Uri uri, | ||||||
|  |             HttpMethod method, | ||||||
|  |             Dictionary<string, object>? parameters, | ||||||
|  |             bool signed, | ||||||
|  |             HttpMethodParameterPosition parameterPosition, | ||||||
|  |             ArrayParametersSerialization arraySerialization, | ||||||
|  |             int requestId, | ||||||
|  |             Dictionary<string, string>? additionalHeaders) | ||||||
|         { |         { | ||||||
|             if (parameters == null) |             if (parameters == null) | ||||||
|                 parameters = new Dictionary<string, object>(); |                 parameters = new Dictionary<string, object>(); | ||||||
| 
 | 
 | ||||||
|             var uriString = uri.ToString(); |             var uriString = uri.ToString(); | ||||||
|             if (authProvider != null) |             if (authProvider != null) | ||||||
|                 parameters = authProvider.AddAuthenticationToParameters(uriString, method, parameters, signed, postPosition, arraySerialization); |                 parameters = authProvider.AddAuthenticationToParameters(uriString, method, parameters, signed, parameterPosition, arraySerialization); | ||||||
| 
 | 
 | ||||||
|             if ((method == HttpMethod.Get || method == HttpMethod.Delete || postPosition == PostParameters.InUri) && parameters?.Any() == true) |             if (parameterPosition == HttpMethodParameterPosition.InUri && parameters?.Any() == true) | ||||||
|                 uriString += "?" + parameters.CreateParamString(true, arraySerialization); |                 uriString += "?" + parameters.CreateParamString(true, arraySerialization); | ||||||
| 
 | 
 | ||||||
|             var contentType = requestBodyFormat == RequestBodyFormat.Json ? Constants.JsonContentHeader : Constants.FormContentHeader; |             var contentType = requestBodyFormat == RequestBodyFormat.Json ? Constants.JsonContentHeader : Constants.FormContentHeader; | ||||||
| @ -342,12 +379,26 @@ namespace CryptoExchange.Net | |||||||
| 
 | 
 | ||||||
|             var headers = new Dictionary<string, string>(); |             var headers = new Dictionary<string, string>(); | ||||||
|             if (authProvider != null) |             if (authProvider != null) | ||||||
|                 headers = authProvider.AddAuthenticationToHeaders(uriString, method, parameters!, signed, postPosition, arraySerialization); |                 headers = authProvider.AddAuthenticationToHeaders(uriString, method, parameters!, signed, parameterPosition, arraySerialization); | ||||||
| 
 | 
 | ||||||
|             foreach (var header in headers) |             foreach (var header in headers) | ||||||
|                 request.AddHeader(header.Key, header.Value); |                 request.AddHeader(header.Key, header.Value); | ||||||
| 
 | 
 | ||||||
|             if ((method == HttpMethod.Post || method == HttpMethod.Put) && postPosition != PostParameters.InUri) |             if (additionalHeaders != null)  | ||||||
|  |             {  | ||||||
|  |                 foreach (var header in additionalHeaders) | ||||||
|  |                     request.AddHeader(header.Key, header.Value); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(StandardRequestHeaders != null) | ||||||
|  |             { | ||||||
|  |                 foreach (var header in StandardRequestHeaders) | ||||||
|  |                     // Only add it if it isn't overwritten | ||||||
|  |                     if(additionalHeaders?.ContainsKey(header.Key) != true) | ||||||
|  |                         request.AddHeader(header.Key, header.Value); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (parameterPosition == HttpMethodParameterPosition.InBody) | ||||||
|             { |             { | ||||||
|                 if (parameters?.Any() == true) |                 if (parameters?.Any() == true) | ||||||
|                     WriteParamBody(request, parameters, contentType); |                     WriteParamBody(request, parameters, contentType); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user