diff --git a/OF DL/Helpers/APIHelper.cs b/OF DL/Helpers/APIHelper.cs index d82be2f..d505146 100644 --- a/OF DL/Helpers/APIHelper.cs +++ b/OF DL/Helpers/APIHelper.cs @@ -2805,11 +2805,11 @@ public class APIHelper : IAPIHelper try { - var resp1 = PostData(licenceURL, drmHeaders, new byte[] { 0x08, 0x04 }); + var resp1 = await PostData(licenceURL, drmHeaders, new byte[] { 0x08, 0x04 }); var certDataB64 = Convert.ToBase64String(resp1); var cdm = new CDMApi(); var challenge = cdm.GetChallenge(pssh, certDataB64, false, false); - var resp2 = PostData(licenceURL, drmHeaders, challenge); + var resp2 = await PostData(licenceURL, drmHeaders, challenge); var licenseB64 = Convert.ToBase64String(resp2); Log.Debug($"resp1: {resp1}"); Log.Debug($"certDataB64: {certDataB64}"); diff --git a/OF DL/Helpers/Constants.cs b/OF DL/Helpers/Constants.cs index 857d1e3..01a410d 100644 --- a/OF DL/Helpers/Constants.cs +++ b/OF DL/Helpers/Constants.cs @@ -3,4 +3,7 @@ namespace OF_DL.Helpers; public static class Constants { public const string API_URL = "https://onlyfans.com/api2/v2"; + + public const int WIDEVINE_RETRY_DELAY = 10; + public const int WIDEVINE_MAX_RETRIES = 3; } diff --git a/OF DL/HttpUtil.cs b/OF DL/HttpUtil.cs index 89d1214..25f0ebe 100644 --- a/OF DL/HttpUtil.cs +++ b/OF DL/HttpUtil.cs @@ -1,4 +1,5 @@ -using System; +using OF_DL.Helpers; +using System; using System.Collections.Generic; using System.Net.Http; using System.Text; @@ -13,46 +14,66 @@ namespace WidevineClient //Proxy = null }); - public static byte[] PostData(string URL, Dictionary headers, string postData) + public static async Task PostData(string URL, Dictionary headers, string postData) { var mediaType = postData.StartsWith("{") ? "application/json" : "application/x-www-form-urlencoded"; - StringContent content = new StringContent(postData, Encoding.UTF8, mediaType); - //ByteArrayContent content = new ByteArrayContent(postData); + var response = await PerformOperation(async () => + { + StringContent content = new StringContent(postData, Encoding.UTF8, mediaType); + //ByteArrayContent content = new ByteArrayContent(postData); - HttpResponseMessage response = Post(URL, headers, content); - byte[] bytes = response.Content.ReadAsByteArrayAsync().Result; + return await Post(URL, headers, content); + }); + + byte[] bytes = await response.Content.ReadAsByteArrayAsync(); return bytes; } - public static byte[] PostData(string URL, Dictionary headers, byte[] postData) + public static async Task PostData(string URL, Dictionary headers, byte[] postData) { - ByteArrayContent content = new ByteArrayContent(postData); + var response = await PerformOperation(async () => + { + ByteArrayContent content = new ByteArrayContent(postData); - HttpResponseMessage response = Post(URL, headers, content); - byte[] bytes = response.Content.ReadAsByteArrayAsync().Result; + return await Post(URL, headers, content); + }); + + byte[] bytes = await response.Content.ReadAsByteArrayAsync(); return bytes; } - public static byte[] PostData(string URL, Dictionary headers, Dictionary postData) + public static async Task PostData(string URL, Dictionary headers, Dictionary postData) { - FormUrlEncodedContent content = new FormUrlEncodedContent(postData); + var response = await PerformOperation(async () => + { + FormUrlEncodedContent content = new FormUrlEncodedContent(postData); - HttpResponseMessage response = Post(URL, headers, content); - byte[] bytes = response.Content.ReadAsByteArrayAsync().Result; + return await Post(URL, headers, content); + }); + + byte[] bytes = await response.Content.ReadAsByteArrayAsync(); return bytes; } - public static string GetWebSource(string URL, Dictionary headers = null) + public static async Task GetWebSource(string URL, Dictionary headers = null) { - HttpResponseMessage response = Get(URL, headers); - byte[] bytes = response.Content.ReadAsByteArrayAsync().Result; + var response = await PerformOperation(async () => + { + return await Get(URL, headers); + }); + + byte[] bytes = await response.Content.ReadAsByteArrayAsync(); return Encoding.UTF8.GetString(bytes); } - public static byte[] GetBinary(string URL, Dictionary headers = null) + public static async Task GetBinary(string URL, Dictionary headers = null) { - HttpResponseMessage response = Get(URL, headers); - byte[] bytes = response.Content.ReadAsByteArrayAsync().Result; + var response = await PerformOperation(async () => + { + return await Get(URL, headers); + }); + + byte[] bytes = await response.Content.ReadAsByteArrayAsync(); return bytes; } public static string GetString(byte[] bytes) @@ -60,7 +81,7 @@ namespace WidevineClient return Encoding.UTF8.GetString(bytes); } - static HttpResponseMessage Get(string URL, Dictionary headers = null) + private static async Task Get(string URL, Dictionary headers = null) { HttpRequestMessage request = new HttpRequestMessage() { @@ -72,10 +93,10 @@ namespace WidevineClient foreach (KeyValuePair header in headers) request.Headers.TryAddWithoutValidation(header.Key, header.Value); - return Send(request); + return await Send(request); } - static HttpResponseMessage Post(string URL, Dictionary headers, HttpContent content) + private static async Task Post(string URL, Dictionary headers, HttpContent content) { HttpRequestMessage request = new HttpRequestMessage() { @@ -88,12 +109,41 @@ namespace WidevineClient foreach (KeyValuePair header in headers) request.Headers.TryAddWithoutValidation(header.Key, header.Value); - return Send(request); + return await Send(request); } - static HttpResponseMessage Send(HttpRequestMessage request) + private static async Task Send(HttpRequestMessage request) { - return Client.SendAsync(request).Result; + 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; } } }