forked from paypal/paypalhttp_dotnet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
HttpClient.cs
123 lines (102 loc) · 4.08 KB
/
HttpClient.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
namespace PayPalHttp
{
public class HttpClient
{
private readonly System.Net.Http.HttpClient _client;
private readonly List<IInjector> _injectors = new();
protected TimeSpan _timeout = TimeSpan.FromMinutes(5); //5 minute http pool default timeout
protected readonly IEnvironment _environment;
private static readonly ConcurrentDictionary<string, System.Net.Http.HttpClient> ClientDictionary = new();
public Encoder Encoder { get; private set; }
public HttpClient(IEnvironment environment)
{
_environment = environment;
Encoder = new Encoder();
#if NET6_0_OR_GREATER
_client = GetHttpClient(environment.BaseUrl());
#else
_client = new System.Net.Http.HttpClient();
_client.BaseAddress = new Uri(environment.BaseUrl());
_client.DefaultRequestHeaders.Add("User-Agent", GetUserAgent());
#endif
}
#if NET6_0_OR_GREATER
protected virtual SocketsHttpHandler GetHttpSocketHandler()
{
return new SocketsHttpHandler() { PooledConnectionLifetime = _timeout };
}
protected virtual System.Net.Http.HttpClient GetHttpClient(string baseUrl)
{
return ClientDictionary.GetOrAdd(baseUrl.ToLower(), (bUrl) => {
var client = new System.Net.Http.HttpClient(GetHttpSocketHandler())
{
BaseAddress = new Uri(baseUrl)
};
client.DefaultRequestHeaders.Add("User-Agent", GetUserAgent());
return client;
});
}
#endif
protected virtual string GetUserAgent()
{
return "PayPalHttp-Dotnet HTTP/1.1";
}
public void AddInjector(IInjector injector)
{
if (injector != null)
{
_injectors.Add(injector);
}
}
public void SetConnectTimeout(TimeSpan timeout)
{
_client.Timeout = _timeout = timeout;
}
public virtual async Task<HttpResponse> Execute<T>(T req) where T: HttpRequest
{
var request = req.Clone<T>();
foreach (var injector in _injectors) {
request = await injector.InjectAsync(request).ConfigureAwait(false);
}
request.RequestUri = new Uri(_environment.BaseUrl() + request.Path);
if (request.Body != null)
{
request.Content = await Encoder.SerializeRequestAsync(request).ConfigureAwait(false);
}
var response = await _client.SendAsync(request).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
object responseBody = null;
if (response.Content.Headers.ContentType != null)
{
responseBody = await Encoder.DeserializeResponseAsync(response.Content, request.ResponseType).ConfigureAwait(false);
}
return new HttpResponse(response.Headers, response.StatusCode, responseBody);
}
else
{
var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new HttpException(response.StatusCode, response.Headers, responseBody);
}
}
public virtual async Task<HttpResponseMessage> ExecuteRaw<T>(T req) where T : HttpRequest
{
var request = req.Clone<T>();
foreach (var injector in _injectors)
{
request = await injector.InjectAsync(request).ConfigureAwait(false);
}
request.RequestUri = new Uri(_environment.BaseUrl() + request.Path);
if (request.Body != null)
{
request.Content = await Encoder.SerializeRequestAsync(request).ConfigureAwait(false);
}
return await _client.SendAsync(request).ConfigureAwait(false);
}
}
}