Spotify.NET/SpotifyAPI.Web/Http/NetHttpClient.cs

142 lines
4.0 KiB
C#
Raw Permalink Normal View History

2020-05-12 19:33:25 +01:00
using System.Net;
2020-05-03 00:00:35 +01:00
using System.Text;
2020-05-01 19:05:28 +01:00
using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
namespace SpotifyAPI.Web.Http
{
public class NetHttpClient : IHTTPClient
{
2020-05-25 17:00:38 +01:00
private readonly HttpMessageHandler? _httpMessageHandler;
private readonly HttpClient _httpClient;
2020-05-01 19:05:28 +01:00
public NetHttpClient()
{
_httpClient = new HttpClient();
}
2020-05-22 11:23:25 +01:00
public NetHttpClient(HttpClient httpClient)
{
_httpClient = httpClient;
}
2020-05-12 19:33:25 +01:00
public NetHttpClient(IProxyConfig proxyConfig)
{
Ensure.ArgumentNotNull(proxyConfig, nameof(proxyConfig));
_httpMessageHandler = CreateMessageHandler(proxyConfig);
_httpClient = new HttpClient(_httpMessageHandler);
}
2020-05-01 19:05:28 +01:00
public async Task<IResponse> DoRequest(IRequest request)
{
Ensure.ArgumentNotNull(request, nameof(request));
using HttpRequestMessage requestMsg = BuildRequestMessage(request);
var responseMsg = await _httpClient
.SendAsync(requestMsg, HttpCompletionOption.ResponseContentRead)
.ConfigureAwait(false);
2020-05-01 19:05:28 +01:00
return await BuildResponse(responseMsg).ConfigureAwait(false);
2020-05-01 19:05:28 +01:00
}
private static async Task<IResponse> BuildResponse(HttpResponseMessage responseMsg)
2020-05-01 19:05:28 +01:00
{
Ensure.ArgumentNotNull(responseMsg, nameof(responseMsg));
// We only support text stuff for now
using var content = responseMsg.Content;
var headers = responseMsg.Headers.ToDictionary(header => header.Key, header => header.Value.First());
var body = await responseMsg.Content.ReadAsStringAsync().ConfigureAwait(false);
var contentType = content.Headers?.ContentType?.MediaType;
2020-05-16 17:48:32 +01:00
return new Response(headers)
{
ContentType = contentType,
StatusCode = responseMsg.StatusCode,
Body = body
};
2020-05-01 19:05:28 +01:00
}
private static HttpRequestMessage BuildRequestMessage(IRequest request)
2020-05-01 19:05:28 +01:00
{
Ensure.ArgumentNotNull(request, nameof(request));
var fullUri = new Uri(request.BaseAddress, request.Endpoint).ApplyParameters(request.Parameters);
var requestMsg = new HttpRequestMessage(request.Method, fullUri);
foreach (var header in request.Headers)
{
requestMsg.Headers.Add(header.Key, header.Value);
}
switch (request.Body)
{
case HttpContent body:
requestMsg.Content = body;
break;
case string body:
2020-05-03 00:00:35 +01:00
requestMsg.Content = new StringContent(body, Encoding.UTF8, "application/json");
2020-05-01 19:05:28 +01:00
break;
case Stream body:
requestMsg.Content = new StreamContent(body);
break;
}
return requestMsg;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
2020-05-01 19:05:28 +01:00
{
if (disposing)
{
_httpClient?.Dispose();
2020-05-12 19:33:25 +01:00
_httpMessageHandler?.Dispose();
2020-05-01 19:05:28 +01:00
}
}
public void SetRequestTimeout(TimeSpan timeout)
{
_httpClient.Timeout = timeout;
}
2020-05-12 19:33:25 +01:00
private static HttpMessageHandler CreateMessageHandler(IProxyConfig proxyConfig)
{
var proxy = new WebProxy
{
Address = new UriBuilder(proxyConfig.Host) { Port = proxyConfig.Port }.Uri,
UseDefaultCredentials = true,
BypassProxyOnLocal = proxyConfig.BypassProxyOnLocal
};
if (!string.IsNullOrEmpty(proxyConfig.User) || !string.IsNullOrEmpty(proxyConfig.Password))
{
proxy.UseDefaultCredentials = false;
proxy.Credentials = new NetworkCredential(proxyConfig.User, proxyConfig.Password);
}
var httpClientHandler = new HttpClientHandler
{
PreAuthenticate = proxy.UseDefaultCredentials,
UseDefaultCredentials = proxy.UseDefaultCredentials,
UseProxy = true,
Proxy = proxy,
};
if (proxyConfig.SkipSSLCheck)
{
httpClientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
}
return httpClientHandler;
}
2020-05-01 19:05:28 +01:00
}
}