diff --git a/.editorconfig b/.editorconfig
index 0c21054..e50f5b5 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -26,3 +26,6 @@ dotnet_diagnostic.IDE0047.severity = none
# DV2001: No Dependency Diagram linked
dotnet_diagnostic.DV2001.severity = none
+
+# CS8602: Dereference of a possibly null reference.
+dotnet_diagnostic.CS8602.severity = silent
diff --git a/UniversalExtensions.cs b/UniversalExtensions.cs
index 3942fda..409f827 100644
--- a/UniversalExtensions.cs
+++ b/UniversalExtensions.cs
@@ -104,20 +104,60 @@ public static class UniversalExtensions
///
/// The shortened URL
/// The URL the redirect leads to
- public static async Task UnshortenUrl(string url)
+ public static async Task UnshortenUrl(string url, bool UseHeadMethod = true)
{
- HttpClient client = new(new HttpClientHandler() { AllowAutoRedirect = false });
- var request = await client.GetAsync(url);
+ HttpClient client = new(new HttpClientHandler()
+ {
+ AllowAutoRedirect = false,
+ AutomaticDecompression = DecompressionMethods.GZip,
+
+ });
+ client.Timeout = TimeSpan.FromSeconds(10);
+ 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.Add("upgrade-insecure-requests", "1");
+ client.DefaultRequestHeaders.Add("accept-encoding", "gzip, deflate, br");
+ client.DefaultRequestHeaders.Add("accept-language", "en-US,en;q=0.9");
+ client.MaxResponseContentBufferSize = 4096;
- if (request.StatusCode is HttpStatusCode.Found
+ HttpRequestMessage requestMessage = new HttpRequestMessage((UseHeadMethod ? HttpMethod.Head : HttpMethod.Get), url);
+
+ CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
+ var request_task = client.SendAsync(requestMessage, cancellationTokenSource.Token);
+
+ try
+ {
+ await request_task.WaitAsync(TimeSpan.FromSeconds(3));
+ }
+ catch (Exception)
+ {
+ if (UseHeadMethod)
+ return await UnshortenUrl(url, false);
+
+ throw;
+ }
+
+ if (!request_task.IsCompleted)
+ cancellationTokenSource.Cancel();
+
+ if (UseHeadMethod && request_task.IsFaulted && request_task.Exception.InnerException.GetType().FullName == "System.Net.Http.HttpRequestException")
+ return await UnshortenUrl(url, false);
+
+ var statuscode = request_task.Result.StatusCode;
+ var header = request_task.Result.Headers;
+
+ if (UseHeadMethod && statuscode is HttpStatusCode.NotFound or HttpStatusCode.InternalServerError)
+ return await UnshortenUrl(url, false);
+
+ if (statuscode is HttpStatusCode.Found
or HttpStatusCode.Redirect
+ or HttpStatusCode.SeeOther
or HttpStatusCode.RedirectKeepVerb
or HttpStatusCode.RedirectMethod
or HttpStatusCode.PermanentRedirect
or HttpStatusCode.TemporaryRedirect)
{
- if (request.Headers is not null && request.Headers.Location is not null)
- return await UnshortenUrl(request.Headers.Location.AbsoluteUri);
+ if (header is not null && header.Location is not null)
+ return await UnshortenUrl(header.Location.AbsoluteUri);
else
return url;
}