Skip to content

Commit cf9291e

Browse files
committed
add proxy support, make httpClient instance variable [#15]
1 parent bb49ae6 commit cf9291e

File tree

3 files changed

+68
-20
lines changed

3 files changed

+68
-20
lines changed

BunqSdk/Context/ApiContext.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ public class ApiContext
6363
[JsonProperty(PropertyName = "session_context")]
6464
public SessionContext SessionContext { get; private set; }
6565

66+
[JsonProperty(PropertyName = "proxy")]
67+
public string Proxy { get; private set; }
68+
6669
[JsonConstructor]
6770
private ApiContext()
6871
{
@@ -71,21 +74,23 @@ private ApiContext()
7174
/// <summary>
7275
/// Create and initialize an API Context with current IP as permitted.
7376
/// </summary>
74-
public static ApiContext Create(ApiEnvironmentType environmentType, string apiKey, string deviceDescription)
77+
public static ApiContext Create(ApiEnvironmentType environmentType, string apiKey, string deviceDescription,
78+
string proxy=null)
7579
{
76-
return Create(environmentType, apiKey, deviceDescription, new List<string>());
80+
return Create(environmentType, apiKey, deviceDescription, new List<string>(), proxy);
7781
}
7882

7983
/// <summary>
8084
/// Create and initialize an API Context.
8185
/// </summary>
8286
public static ApiContext Create(ApiEnvironmentType environmentType, string apiKey, string deviceDescription,
83-
IList<string> permittedIps)
87+
IList<string> permittedIps, string proxy=null)
8488
{
8589
var apiContext = new ApiContext
8690
{
8791
ApiKey = apiKey,
8892
EnvironmentType = environmentType,
93+
Proxy = proxy,
8994
};
9095
apiContext.Initialize(deviceDescription, permittedIps);
9196

BunqSdk/Http/ApiClient.cs

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,42 @@ public class ApiClient
4949
/// </summary>
5050
private const string DELIMITER_HEADER_VALUE = ",";
5151

52-
private static HttpClient client;
52+
private readonly HttpClient client;
5353

5454
private readonly ApiContext apiContext;
5555

5656
public ApiClient(ApiContext apiContext)
5757
{
5858
this.apiContext = apiContext;
59+
client = CreateHttpClient();
5960
}
6061

62+
private HttpClient CreateHttpClient()
63+
{
64+
return new HttpClient(CreateHttpClientHandler())
65+
{
66+
BaseAddress = new Uri(apiContext.GetBaseUri())
67+
};
68+
}
69+
70+
private HttpClientHandler CreateHttpClientHandler()
71+
{
72+
// TODO: Add HTTP Public Key Pinning. It is needed to prevent possible man-in-the-middle attacks using
73+
// the fake (or mis-issued) certificates.
74+
// More info: https://timtaubert.de/blog/2014/10/http-public-key-pinning-explained/
75+
// Simply put, we reduce the amount of certificates which are accepted in bunq API responses.
76+
var handler = new HttpClientHandler();
77+
78+
if (apiContext.Proxy != null)
79+
{
80+
handler.Proxy = new BunqProxy(apiContext.Proxy);
81+
handler.UseProxy = true;
82+
}
83+
84+
return handler;
85+
}
86+
87+
6188
/// <summary>
6289
/// Executes a POST request and returns the resulting HTTP response message.
6390
/// </summary>
@@ -90,7 +117,6 @@ private BunqResponseRaw SendRequest(HttpRequestMessage requestMessage,
90117
SetDefaultHeaders(requestMessage);
91118
SetHeaders(requestMessage, customHeaders);
92119
SetSessionHeaders(requestMessage);
93-
InitializeHttpClientIfNeeded(apiContext);
94120
var responseMessage = client.SendAsync(requestMessage).Result;
95121
AssertResponseSuccess(responseMessage);
96122
ValidateResponse(responseMessage);
@@ -194,21 +220,6 @@ private string GenerateSignature(HttpRequestMessage requestMessage)
194220
return SecurityUtils.GenerateSignature(requestMessage, apiContext.InstallationContext.KeyPairClient);
195221
}
196222

197-
private static void InitializeHttpClientIfNeeded(ApiContext apiContext)
198-
{
199-
if (client == null)
200-
{
201-
// TODO: Add HTTP Public Key Pinning. It is needed to prevent possible man-in-the-middle attacks using
202-
// the fake (or mis-issued) certificates.
203-
// More info: https://timtaubert.de/blog/2014/10/http-public-key-pinning-explained/
204-
// Simply put, we reduce the amount of certificates which are accepted in bunq API responses.
205-
client = new HttpClient
206-
{
207-
BaseAddress = new Uri(apiContext.GetBaseUri())
208-
};
209-
}
210-
}
211-
212223
private static void AssertResponseSuccess(HttpResponseMessage responseMessage)
213224
{
214225
if (responseMessage.IsSuccessStatusCode) return;

BunqSdk/Http/BunqProxy.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
using System.Net;
3+
4+
namespace Bunq.Sdk.Http
5+
{
6+
public class BunqProxy : IWebProxy
7+
{
8+
public BunqProxy(string proxyUri)
9+
: this(new Uri(proxyUri))
10+
{
11+
}
12+
13+
public BunqProxy(Uri proxyUri)
14+
{
15+
ProxyUri = proxyUri;
16+
}
17+
18+
public Uri ProxyUri { get; set; }
19+
20+
public ICredentials Credentials { get; set; }
21+
22+
public Uri GetProxy(Uri destination)
23+
{
24+
return ProxyUri;
25+
}
26+
27+
public bool IsBypassed(Uri host)
28+
{
29+
return false; /* Proxy all requests */
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)