using OF_DL.Helpers; using System; using System.Collections.Generic; using System.Net.Http; using System.Text; namespace WidevineClient { class HttpUtil { public static HttpClient Client { get; set; } = new HttpClient(new HttpClientHandler { AllowAutoRedirect = true, //Proxy = null }); public static async Task PostData(string URL, Dictionary headers, string postData) { var mediaType = postData.StartsWith("{") ? "application/json" : "application/x-www-form-urlencoded"; var response = await PerformOperation(async () => { StringContent content = new StringContent(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) { var response = await PerformOperation(async () => { 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, Dictionary postData) { var response = await PerformOperation(async () => { FormUrlEncodedContent content = new FormUrlEncodedContent(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) { var 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) { var response = await PerformOperation(async () => { return await Get(URL, headers); }); byte[] bytes = await response.Content.ReadAsByteArrayAsync(); return bytes; } public static string GetString(byte[] bytes) { return Encoding.UTF8.GetString(bytes); } private static async Task Get(string URL, Dictionary headers = null) { HttpRequestMessage request = new HttpRequestMessage() { 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, HttpContent content) { HttpRequestMessage request = new HttpRequestMessage() { 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) { return await Client.SendAsync(request); } private static async Task PerformOperation(Func> operation) { var response = await operation(); var retryCount = 0; while (retryCount < Constants.WIDEVINE_MAX_RETRIES && response.StatusCode == System.Net.HttpStatusCode.TooManyRequests) { // // We've hit a rate limit, so we should wait before retrying. // var retryAfterSeconds = Constants.WIDEVINE_RETRY_DELAY * (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; } } }