Skip to content

Commit d970200

Browse files
authored
feat: enable proxy configuration settings for http client (#119)
1 parent 04ae615 commit d970200

File tree

5 files changed

+533
-326
lines changed

5 files changed

+533
-326
lines changed

APIMatic.Core.Test/Http/CoreHttpClientConfigurationTest.cs

Lines changed: 137 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Net;
34
using System.Net.Http;
45
using APIMatic.Core.Http.Configuration;
6+
using APIMatic.Core.Proxy;
57
using NUnit.Framework;
68

79
namespace APIMatic.Core.Test.Http
@@ -18,7 +20,7 @@ public void SetupCoreHttpClient()
1820
}
1921

2022
[Test]
21-
public void Builder_BuildWithPrameters_CoreHttpClientConfiguration()
23+
public void Builder_BuildWithParameters_CoreHttpClientConfiguration()
2224
{
2325
// Arrange
2426
var timeout = 180;
@@ -27,8 +29,8 @@ public void Builder_BuildWithPrameters_CoreHttpClientConfiguration()
2729
var backoffFactor = 3;
2830
var retryInterval = 4.5;
2931
var maximumRetryWaitTime = 360;
30-
var statusCodesToRetry = new List<int>() { 408, 409 };
31-
var requestMethodsToRetry = new List<HttpMethod>() { HttpMethod.Post, HttpMethod.Get };
32+
var statusCodesToRetry = new List<int> { 408, 409 };
33+
var requestMethodsToRetry = new List<HttpMethod> { HttpMethod.Post, HttpMethod.Get };
3234

3335
// Act
3436
var config = _config.ToBuilder()
@@ -40,22 +42,22 @@ public void Builder_BuildWithPrameters_CoreHttpClientConfiguration()
4042
.MaximumRetryWaitTime(TimeSpan.FromSeconds(maximumRetryWaitTime))
4143
.StatusCodesToRetry(statusCodesToRetry)
4244
.RequestMethodsToRetry(requestMethodsToRetry)
43-
.Build();
45+
.Build();
4446

4547
// Assert
4648
Assert.NotNull(config);
47-
Assert.AreEqual(config.Timeout, TimeSpan.FromSeconds(timeout));
48-
Assert.AreEqual(config.SkipSslCertVerification, skipSslCertVerification);
49-
Assert.AreEqual(config.NumberOfRetries, numberOfRetries);
50-
Assert.AreEqual(config.BackoffFactor, backoffFactor);
51-
Assert.AreEqual(config.RetryInterval, retryInterval);
52-
Assert.AreEqual(config.MaximumRetryWaitTime, TimeSpan.FromSeconds(maximumRetryWaitTime));
53-
CollectionAssert.AreEqual(config.StatusCodesToRetry, statusCodesToRetry);
54-
CollectionAssert.AreEqual(config.RequestMethodsToRetry, requestMethodsToRetry);
49+
Assert.AreEqual(TimeSpan.FromSeconds(timeout), config.Timeout);
50+
Assert.AreEqual(skipSslCertVerification, config.SkipSslCertVerification);
51+
Assert.AreEqual(numberOfRetries, config.NumberOfRetries);
52+
Assert.AreEqual(backoffFactor, config.BackoffFactor);
53+
Assert.AreEqual(retryInterval, config.RetryInterval);
54+
Assert.AreEqual(TimeSpan.FromSeconds(maximumRetryWaitTime), config.MaximumRetryWaitTime);
55+
CollectionAssert.AreEqual(statusCodesToRetry, config.StatusCodesToRetry);
56+
CollectionAssert.AreEqual(requestMethodsToRetry, config.RequestMethodsToRetry);
5557
}
5658

5759
[Test]
58-
public void Builder_BuildWithInvalidPrameters_CoreHttpClientConfiguration()
60+
public void Builder_BuildWithInvalidParameters_CoreHttpClientConfiguration()
5961
{
6062
// Arrange
6163
var timeout = 0;
@@ -75,9 +77,9 @@ public void Builder_BuildWithInvalidPrameters_CoreHttpClientConfiguration()
7577
.MaximumRetryWaitTime(TimeSpan.FromSeconds(maximumRetryWaitTime))
7678
.StatusCodesToRetry(null)
7779
.RequestMethodsToRetry(null)
78-
.Build();
80+
.Build();
7981

80-
//expected default values
82+
// Expected default values
8183
var defaultTimeout = 100;
8284
var defaultNumberOfRetries = 0;
8385
var defaultBackoffFactor = 2;
@@ -87,12 +89,12 @@ public void Builder_BuildWithInvalidPrameters_CoreHttpClientConfiguration()
8789
// Assert
8890
Assert.NotNull(config);
8991
Assert.NotNull(config.HttpClientInstance);
90-
Assert.AreEqual(config.Timeout, TimeSpan.FromSeconds(defaultTimeout));
91-
Assert.AreEqual(config.SkipSslCertVerification, skipSslCertVerification);
92-
Assert.AreEqual(config.NumberOfRetries, defaultNumberOfRetries);
93-
Assert.AreEqual(config.BackoffFactor, defaultBackoffFactor);
94-
Assert.AreEqual(config.RetryInterval, defaultRetryInterval);
95-
Assert.AreEqual(config.MaximumRetryWaitTime, TimeSpan.FromSeconds(defaultMaximumRetryWaitTime));
92+
Assert.AreEqual(TimeSpan.FromSeconds(defaultTimeout), config.Timeout);
93+
Assert.AreEqual(skipSslCertVerification, config.SkipSslCertVerification);
94+
Assert.AreEqual(defaultNumberOfRetries, config.NumberOfRetries);
95+
Assert.AreEqual(defaultBackoffFactor, config.BackoffFactor);
96+
Assert.AreEqual(defaultRetryInterval, config.RetryInterval);
97+
Assert.AreEqual(TimeSpan.FromSeconds(defaultMaximumRetryWaitTime), config.MaximumRetryWaitTime);
9698
CollectionAssert.IsEmpty(config.StatusCodesToRetry);
9799
CollectionAssert.IsEmpty(config.RequestMethodsToRetry);
98100
}
@@ -104,8 +106,121 @@ public void ToString_Default_CoreHttpClientConfiguration()
104106
var actual = _config.ToString();
105107

106108
// Assert
107-
var expected = "HttpClientConfiguration: 00:01:40 , False , 0 , 2 , 1 , 00:02:00 , System.Collections.Immutable.ImmutableList`1[System.Int32] , System.Collections.Immutable.ImmutableList`1[System.Net.Http.HttpMethod] , System.Net.Http.HttpClient , True ";
109+
var expected = "HttpClientConfiguration: 00:01:40 , False , 0 , 2 , 1 , 00:02:00 , System.Collections.Immutable.ImmutableList`1[System.Int32] , System.Collections.Immutable.ImmutableList`1[System.Net.Http.HttpMethod] , , System.Net.Http.HttpClient , True ";
108110
Assert.AreEqual(expected, actual);
109111
}
112+
113+
[Test]
114+
public void ToString_WithProxy_CoreHttpClientConfiguration()
115+
{
116+
// Arrange
117+
var proxyConfig = new CoreProxyConfiguration(
118+
address: "proxy.example.com",
119+
port: 8080,
120+
user: "admin",
121+
pass: "secret",
122+
tunnel: true
123+
);
124+
125+
var config = new CoreHttpClientConfiguration.Builder()
126+
.ProxyConfiguration(proxyConfig)
127+
.HttpClientInstance(new HttpClient())
128+
.Build();
129+
130+
// Act
131+
var actual = config.ToString();
132+
133+
// Assert
134+
var expected = "HttpClientConfiguration: 00:01:40 , False , 0 , 2 , 1 , 00:02:00 , " +
135+
"System.Collections.Immutable.ImmutableList`1[System.Int32] , " +
136+
"System.Collections.Immutable.ImmutableList`1[System.Net.Http.HttpMethod] , " +
137+
"CoreProxyConfiguration: Address=proxy.example.com, Port=8080, User=admin, Pass=****, Tunnel=True , " +
138+
"System.Net.Http.HttpClient , True ";
139+
140+
Assert.AreEqual(expected, actual);
141+
}
142+
143+
144+
[Test]
145+
public void GetInitializedHttpClientInstance_ShouldUseProxyWithoutSsl()
146+
{
147+
// Arrange
148+
var proxyConfig = new Proxy.CoreProxyConfiguration(
149+
address: "localhost",
150+
port: 8080,
151+
user: "user",
152+
pass: "pass",
153+
tunnel: true);
154+
155+
// Act
156+
var handler = new CoreHttpClientConfiguration.Builder()
157+
.ProxyConfiguration(proxyConfig)
158+
.GetHandler();
159+
160+
// Assert
161+
var webProxy = handler.Proxy as WebProxy;
162+
Assert.IsNotNull(webProxy);
163+
Assert.AreEqual("http://localhost:8080/", webProxy.Address.ToString());
164+
Assert.AreEqual("user", ((NetworkCredential)webProxy.Credentials).UserName);
165+
Assert.AreEqual("pass", ((NetworkCredential)webProxy.Credentials).Password);
166+
Assert.IsTrue(handler.UseProxy);
167+
Assert.IsFalse(handler.UseDefaultCredentials, "Tunnel mode should disable default credentials");
168+
Assert.IsTrue(handler.PreAuthenticate);
169+
170+
}
171+
172+
[Test]
173+
public void GetInitializedHttpClientInstance_ShouldUseProxyWithSkipSslVerification()
174+
{
175+
// Arrange
176+
var proxyConfig = new Proxy.CoreProxyConfiguration(
177+
address: "proxy.example.com",
178+
port: 8080,
179+
user: "user",
180+
pass: "pass",
181+
tunnel: false);
182+
183+
// Act
184+
var handler = new CoreHttpClientConfiguration.Builder()
185+
.SkipSslCertVerification(true) // Enable skipping SSL cert validation
186+
.ProxyConfiguration(proxyConfig) // Set proxy config
187+
.GetHandler();
188+
189+
// Assert Proxy
190+
var webProxy = handler.Proxy as WebProxy;
191+
Assert.IsNotNull(webProxy);
192+
Assert.AreEqual("http://proxy.example.com:8080/", webProxy.Address.ToString());
193+
194+
var credentials = webProxy.Credentials as NetworkCredential;
195+
Assert.IsNotNull(credentials);
196+
Assert.AreEqual("user", credentials.UserName);
197+
Assert.AreEqual("pass", credentials.Password);
198+
Assert.IsFalse(handler.PreAuthenticate);
199+
Assert.IsTrue(handler.UseProxy);
200+
Assert.IsNotNull(handler.ServerCertificateCustomValidationCallback);
201+
202+
bool validationResult = handler.ServerCertificateCustomValidationCallback(
203+
null, null, null, System.Net.Security.SslPolicyErrors.None);
204+
205+
Assert.IsTrue(validationResult, "SSL certificate validation callback should return true to skip validation");
206+
}
207+
208+
209+
[Test]
210+
public void GetInitializedHttpClientInstance_ShouldNotUseProxyOrSkipSsl()
211+
{
212+
// Act
213+
var handler = new CoreHttpClientConfiguration.Builder()
214+
.SkipSslCertVerification(false)
215+
.GetHandler();
216+
217+
Assert.IsNull(handler.Proxy, "Proxy should be null when not configured");
218+
219+
Assert.IsNull(handler.ServerCertificateCustomValidationCallback, "No custom SSL callback should be set");
220+
}
221+
222+
223+
224+
110225
}
111226
}

APIMatic.Core/GlobalConfiguration.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public class GlobalConfiguration
2323
private readonly Dictionary<Enum, string> _serverUrls;
2424
private readonly Enum _defaultServer;
2525
private readonly Parameter.Builder _parameters;
26-
26+
2727
internal SdkLoggingConfiguration SdkLoggingConfiguration { get; private set; }
2828

2929
internal Dictionary<string, AuthManager> AuthManagers { get; private set; }

0 commit comments

Comments
 (0)