-
Notifications
You must be signed in to change notification settings - Fork 0
/
WebRequest.cs
340 lines (302 loc) · 9 KB
/
WebRequest.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using WebRequest.Elegant.Core;
using WebRequest.Elegant.Fakes;
[assembly: InternalsVisibleTo("WebRequest.Tests")]
namespace WebRequest.Elegant
{
public sealed class WebRequest : IWebRequest,
IEquatable<IUri>,
IEquatable<Uri>,
IEquatable<string>,
IEquatable<IToken>,
IEquatable<HttpMethod>,
IEquatable<IBodyContent>,
IEquatable<Dictionary<string, string>>
{
private readonly HttpClient _httpClient;
internal readonly Dictionary<string, string> _queryParams;
internal readonly IToken _token;
internal readonly HttpMethod _httpMethod;
internal readonly IBodyContent _body;
#region Constructors
public WebRequest(
string uriString
) : this(uriString, new HttpClient())
{
}
public WebRequest(
string uriString,
HttpClient httpClient
) : this(new UriFromString(uriString), httpClient)
{
}
public WebRequest(
string uriString,
HttpMessageHandler messageHandler
) : this(new UriFromString(uriString), messageHandler)
{
}
public WebRequest(
Uri uri,
IRoute route
) : this(uri, new RoutedHttpMessageHandler(route))
{
}
public WebRequest(
Uri uri,
HttpMessageHandler messageHandler
) : this(new UriFromString(uri), new HttpClient(messageHandler))
{
}
public WebRequest(
Uri uri
) : this(uri, new HttpClient())
{
}
public WebRequest(
Uri uri,
HttpClient httpClient
) : this(new UriFromString(uri), new HttpAuthenticationHeaderToken(), httpClient)
{
}
public WebRequest(
Uri uri,
IToken token
) : this(uri, token, new HttpClient())
{
}
public WebRequest(
Uri uri,
IToken token,
HttpClient httpClient
) : this(
new UriFromString(uri),
token,
HttpMethod.Get,
new JsonBodyContent(new EmptyJsonObject()),
new Dictionary<string, string>(),
httpClient
)
{
}
public WebRequest(
Uri uri,
IToken token,
HttpMethod method,
IBodyContent body
) : this(
new UriFromString(uri),
token,
method,
body,
new Dictionary<string, string>(),
new HttpClient()
)
{
}
public WebRequest(
Uri uri,
IToken token,
HttpMethod method,
IBodyContent body,
Dictionary<string, string> queryParams,
HttpClient httpClient)
: this(new UriFromString(uri), token, method, body, queryParams, httpClient)
{
}
public WebRequest(
IUri uri,
HttpMessageHandler messageHandler
) : this(uri, new HttpClient(messageHandler))
{
}
public WebRequest(
IUri uri,
HttpClient httpClient
) : this(uri, new HttpAuthenticationHeaderToken(), httpClient)
{
}
public WebRequest(
IUri uri,
IToken token,
HttpClient httpClient
) : this(
uri,
token,
HttpMethod.Get,
new JsonBodyContent(new EmptyJsonObject()),
new Dictionary<string, string>(),
httpClient
)
{
}
public WebRequest(
IUri uri,
IToken token,
HttpMethod method,
IBodyContent body
) : this(
uri,
token,
method,
body,
new Dictionary<string, string>(),
new HttpClient()
)
{
}
public WebRequest(
IUri uri,
IToken token,
HttpMethod method,
IBodyContent body,
Dictionary<string, string> queryParams,
HttpClient httpClient)
{
Uri = uri ?? throw new ArgumentNullException(nameof(uri));
_token = token ?? throw new ArgumentNullException(nameof(token));
_httpMethod = method ?? throw new ArgumentNullException(nameof(method));
_body = body ?? throw new ArgumentNullException(nameof(body));
_queryParams = queryParams ?? throw new ArgumentNullException(nameof(queryParams));
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
}
#endregion
public IUri Uri { get; }
public async Task<HttpResponseMessage> GetResponseAsync()
{
var requestMessage = await RequestMessageAsync(_httpMethod).ConfigureAwait(false);
try
{
return await _httpClient.SendAsync(requestMessage).ConfigureAwait(false);
}
finally
{
requestMessage.Dispose();
}
}
public IWebRequest WithPath(IUri uri)
{
return new WebRequest(
uri,
_token,
_httpMethod,
_body,
_queryParams,
_httpClient
);
}
public IWebRequest WithMethod(HttpMethod method)
{
return new WebRequest(
Uri,
_token,
method,
_body,
_queryParams,
_httpClient
);
}
public IWebRequest WithQueryParams(params string[] onlyKeys)
{
var noValues = new Dictionary<string, string>();
foreach(var key in onlyKeys)
{
noValues.Add(key, string.Empty);
}
return new WebRequest(
Uri,
_token,
_httpMethod,
_body,
noValues,
_httpClient
);
}
public IWebRequest WithQueryParams(Dictionary<string, string> parameters)
{
return new WebRequest(
Uri,
_token,
_httpMethod,
_body,
parameters,
_httpClient
);
}
public IWebRequest WithBody(IBodyContent body)
{
return new WebRequest(
Uri,
_token,
_httpMethod,
body,
_queryParams,
_httpClient
);
}
public override string ToString()
{
return $"Uri: {new QueryParamsAsString(_queryParams).With(Uri.Uri())}\n" +
$"Token: {_token}\n" +
$"Body: {_body}";
}
bool IEquatable<IUri>.Equals(IUri uri)
{
return Uri.Uri().ToString() == uri.Uri().ToString();
}
bool IEquatable<Uri>.Equals(Uri dotNetUri)
{
return Uri.Uri().Equals(dotNetUri);
}
bool IEquatable<string>.Equals(string uriAsString)
{
return Uri.Uri().ToString() == uriAsString;
}
bool IEquatable<IToken>.Equals(IToken token)
{
return _token.Equals(token);
}
bool IEquatable<HttpMethod>.Equals(HttpMethod other)
{
return _httpMethod == other;
}
bool IEquatable<IBodyContent>.Equals(IBodyContent body)
{
return _body.Equals(body);
}
bool IEquatable<Dictionary<string, string>>.Equals(Dictionary<string, string> parameters)
{
return new TheSameDictionary<string, string>(
_queryParams,
parameters
).ToBool();
}
public override bool Equals(object obj)
{
return object.ReferenceEquals(this, obj)
|| new TheSameWebRequest(this, obj).ToBool();
}
public override int GetHashCode()
{
#if NETSTANDARD2_1
return HashCode.Combine(Uri, _token, _httpMethod, _body, _queryParams);
#else
return new { Uri, _token, _httpMethod, _body, _queryParams }.GetHashCode();
#endif
}
private async Task<HttpRequestMessage> RequestMessageAsync(HttpMethod method)
{
var request = new HttpRequestMessage(
method,
new QueryParamsAsString(_queryParams).With(Uri.Uri())
);
_body.InjectTo(request);
await _token.InjectToAsync(request).ConfigureAwait(false);
return request;
}
}
}