diff --git a/Tools/WebTools.cs b/Tools/WebTools.cs index 4135731..9901ed0 100644 --- a/Tools/WebTools.cs +++ b/Tools/WebTools.cs @@ -7,18 +7,22 @@ public static class WebTools /// /// The shortened URL /// The URL the redirect leads to - public static async Task UnshortenUrl(string url, bool UseHeadMethod = true) + public static async Task UnshortenUrl(string url, bool UseHeadMethod = true, int depth = 0, int maxDepth = 30) { + if (depth > maxDepth) + { + throw new DepthLimitReachedException(); + } + _logger?.LogDebug("Unshortening Url '{Url}', using head method: {UseHeadMethod}", url, UseHeadMethod); HttpClient client = new(new HttpClientHandler() { AllowAutoRedirect = false, AutomaticDecompression = DecompressionMethods.GZip, - }); client.Timeout = TimeSpan.FromSeconds(60); - client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36"); + client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"); client.DefaultRequestHeaders.Add("upgrade-insecure-requests", "1"); client.DefaultRequestHeaders.Add("accept-encoding", "gzip, deflate, br"); client.DefaultRequestHeaders.Add("accept-language", "en-US,en;q=0.9"); @@ -36,7 +40,7 @@ public static class WebTools catch (Exception) { if (UseHeadMethod) - return await UnshortenUrl(url, false); + return await UnshortenUrl(url, false, depth + 1, maxDepth); throw; } @@ -47,7 +51,7 @@ public static class WebTools if (UseHeadMethod && request_task.IsFaulted && request_task.Exception.InnerException.GetType() == typeof(HttpRequestException)) { _logger?.LogWarning("Unshortening Url '{Url}' failed, falling back to non-head method", url); - return await UnshortenUrl(url, false); + return await UnshortenUrl(url, false, depth + 1, maxDepth); } var statuscode = request_task.Result.StatusCode; @@ -56,7 +60,7 @@ public static class WebTools if (UseHeadMethod && statuscode is HttpStatusCode.NotFound or HttpStatusCode.InternalServerError) { _logger?.LogWarning("Unshortening Url '{Url}' failed, falling back to non-head method", url); - return await UnshortenUrl(url, false); + return await UnshortenUrl(url, false, depth + 1, maxDepth); } if (statuscode is HttpStatusCode.Found @@ -68,7 +72,13 @@ public static class WebTools or HttpStatusCode.TemporaryRedirect) { if (header is not null && header.Location is not null) - return await UnshortenUrl(header.Location.AbsoluteUri); + { + + if (header.Location.IsAbsoluteUri) + return await UnshortenUrl(header.Location.AbsoluteUri, UseHeadMethod, depth + 1, maxDepth); + else + return await UnshortenUrl(new Uri(requestMessage.RequestUri.GetLeftPart(UriPartial.Authority).ToString() + header.Location.ToString()).AbsoluteUri, UseHeadMethod, depth + 1, maxDepth); + } else return url; } @@ -76,3 +86,5 @@ public static class WebTools return url; } } + +public class DepthLimitReachedException : Exception { } \ No newline at end of file