using System.Net; using System.Text; using OF_DL.Helpers; namespace OF_DL.Utils; internal class HttpUtil { public static HttpClient Client { get; set; } = new(new HttpClientHandler { AllowAutoRedirect = true //Proxy = null }); public static async Task PostData(string URL, Dictionary headers, string postData) { string mediaType = postData.StartsWith("{") ? "application/json" : "application/x-www-form-urlencoded"; HttpResponseMessage response = await PerformOperation(async () => { StringContent content = new(postData, Encoding.UTF8, mediaType); //ByteArrayContent content = new ByteArrayContent(postData); return await Post(URL, headers, content); }); byte[] bytes = await response.Content.ReadAsByteArrayAsync(); return bytes; } public static async Task PostData(string URL, Dictionary headers, byte[] postData) { HttpResponseMessage response = await PerformOperation(async () => { ByteArrayContent content = new(postData); return await Post(URL, headers, content); }); byte[] bytes = await response.Content.ReadAsByteArrayAsync(); return bytes; } public static async Task PostData(string URL, Dictionary headers, Dictionary postData) { HttpResponseMessage response = await PerformOperation(async () => { FormUrlEncodedContent content = new(postData); return await Post(URL, headers, content); }); byte[] bytes = await response.Content.ReadAsByteArrayAsync(); return bytes; } public static async Task GetWebSource(string URL, Dictionary? headers = null) { HttpResponseMessage response = await PerformOperation(async () => { return await Get(URL, headers); }); byte[] bytes = await response.Content.ReadAsByteArrayAsync(); return Encoding.UTF8.GetString(bytes); } public static async Task GetBinary(string URL, Dictionary? headers = null) { HttpResponseMessage response = await PerformOperation(async () => { return await Get(URL, headers); }); byte[] bytes = await response.Content.ReadAsByteArrayAsync(); return bytes; } public static string GetString(byte[] bytes) => Encoding.UTF8.GetString(bytes); private static async Task Get(string URL, Dictionary? headers = null) { HttpRequestMessage request = new() { RequestUri = new Uri(URL), Method = HttpMethod.Get }; if (headers != null) { foreach (KeyValuePair header in headers) { request.Headers.TryAddWithoutValidation(header.Key, header.Value); } } return await Send(request); } private static async Task Post(string URL, Dictionary? headers = null, HttpContent? content = null) { HttpRequestMessage request = new() { RequestUri = new Uri(URL), Method = HttpMethod.Post, Content = content }; if (headers != null) { foreach (KeyValuePair header in headers) { request.Headers.TryAddWithoutValidation(header.Key, header.Value); } } return await Send(request); } private static async Task Send(HttpRequestMessage request) => await Client.SendAsync(request); private static async Task PerformOperation(Func> operation) { HttpResponseMessage response = await operation(); int retryCount = 0; while (retryCount < Constants.WidevineMaxRetries && response.StatusCode == HttpStatusCode.TooManyRequests) { // // We've hit a rate limit, so we should wait before retrying. // int retryAfterSeconds = Constants.WidevineRetryDelay * (retryCount + 1); // Default retry time. Increases with each retry. if (response.Headers.RetryAfter != null && response.Headers.RetryAfter.Delta.HasValue) { if (response.Headers.RetryAfter.Delta.Value.TotalSeconds > 0) { retryAfterSeconds = (int)response.Headers.RetryAfter.Delta.Value.TotalSeconds + 1; // Add 1 second to ensure we wait a bit longer than the suggested time } } await Task.Delay(retryAfterSeconds * 1000); // Peform the delay response = await operation(); retryCount++; } response.EnsureSuccessStatusCode(); // Throw an exception if the response is not successful return response; } }