forked from JustDerb/Tiltify-Client
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTiltifyHttpClient.cs
137 lines (122 loc) · 6.26 KB
/
TiltifyHttpClient.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
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Tiltify.Exceptions;
namespace Tiltify
{
public class TiltifyhHttpClient : IHttpCallHandler
{
private readonly ILogger<TiltifyhHttpClient> _logger;
private readonly HttpClient _http;
/// <summary>
/// Creates an Instance of the TiltifyhHttpClient Class.
/// </summary>
/// <param name="logger">Instance Of Logger, otherwise no logging is used, </param>
public TiltifyhHttpClient(ILogger<TiltifyhHttpClient> logger = null)
{
_logger = logger;
_http = new HttpClient(new TiltifyHttpClientHandler(_logger));
}
public async Task PutBytesAsync(string url, byte[] payload)
{
var response = await _http.PutAsync(new Uri(url), new ByteArrayContent(payload)).ConfigureAwait(false);
if (!response.IsSuccessStatusCode)
HandleWebException(response);
}
public async Task<KeyValuePair<int, string>> GeneralRequestAsync(string url, string method,
string payload = null, ApiVersion api = ApiVersion.Latest, string accessToken = null)
{
var request = new HttpRequestMessage
{
RequestUri = new Uri(url),
Method = new HttpMethod(method)
};
request.Headers.Add(HttpRequestHeader.Accept.ToString(), "application/json");
if (!string.IsNullOrWhiteSpace(accessToken))
{
request.Headers.Add(HttpRequestHeader.Authorization.ToString(), $"Bearer {FormatOAuth(accessToken)}");
}
else if (method.ToLower() == "get")
{
// All their GET apis require an oauth token in some regard.
throw new InvalidCredentialException("A Client-Id and OAuth token is required to use the Tiltify API.");
}
if (payload != null)
{
request.Content = new StringContent(payload, Encoding.UTF8, "application/json");
request.Headers.Add(HttpRequestHeader.ContentType.ToString(), "application/json");
}
var response = await _http.SendAsync(request).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
var respStr = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
return new KeyValuePair<int, string>((int)response.StatusCode, respStr);
}
HandleWebException(response);
return new KeyValuePair<int, string>(0, null);
}
public async Task<int> RequestReturnResponseCodeAsync(string url, string method, List<KeyValuePair<string, string>> getParams = null)
{
if (getParams != null)
{
for (var i = 0; i < getParams.Count; i++)
{
if (i == 0)
url += $"?{getParams[i].Key}={Uri.EscapeDataString(getParams[i].Value)}";
else
url += $"&{getParams[i].Key}={Uri.EscapeDataString(getParams[i].Value)}";
}
}
var request = new HttpRequestMessage
{
RequestUri = new Uri(url),
Method = new HttpMethod(method)
};
var response = await _http.SendAsync(request).ConfigureAwait(false);
return (int)response.StatusCode;
}
/// <summary>
/// Function that extracts just the token for consistency
/// </summary>
/// <param name="token">Full token string</param>
/// <returns></returns>
private static string FormatOAuth(string token)
{
return token.Contains(" ") ? token.Split(' ')[1] : token;
}
private void HandleWebException(HttpResponseMessage errorResp)
{
switch (errorResp.StatusCode)
{
case HttpStatusCode.BadRequest:
throw new BadRequestException("Your request failed because either: \n 1. Your ClientID was invalid/not set. \n 2. Your refresh token was invalid. \n 3. You requested a username when the server was expecting a user ID.");
case HttpStatusCode.Unauthorized:
var authenticateHeader = errorResp.Headers.WwwAuthenticate;
if (authenticateHeader == null || authenticateHeader.Count <= 0)
throw new BadScopeException("Your request was blocked due to bad credentials (Do you have the right scope for your access token?).");
else
throw new TokenExpiredException("Your request was blocked due to an expired Token. Please refresh your token and update your API instance settings.");
case HttpStatusCode.Forbidden:
throw new BadTokenException("The token provided in the request did not match the associated user. Make sure the token you're using is from the resource owner.");
case HttpStatusCode.NotFound:
throw new BadResourceException("The resource you tried to access was not valid.");
case (HttpStatusCode)429:
errorResp.Headers.TryGetValues("Ratelimit-Reset", out var resetTime);
throw new TooManyRequestsException("You have reached your rate limit. Too many requests were made", resetTime.FirstOrDefault());
case HttpStatusCode.BadGateway:
throw new BadGatewayException("The API answered with a 502 Bad Gateway. Please retry your request");
case HttpStatusCode.GatewayTimeout:
throw new GatewayTimeoutException("The API answered with a 504 Gateway Timeout. Please retry your request");
case HttpStatusCode.InternalServerError:
throw new InternalServerErrorException("The API answered with a 500 Internal Server Error. Please retry your request");
default:
throw new HttpRequestException($"Something went wrong during the request! Please try again later. Status code: {errorResp.StatusCode}");
}
}
}
}