@@ -7,18 +7,22 @@ public static class WebTools
7
7
/// </summary>
8
8
/// <param name="url">The shortened URL</param>
9
9
/// <returns>The URL the redirect leads to</returns>
10
- public static async Task < string > UnshortenUrl ( string url , bool UseHeadMethod = true )
10
+ public static async Task < string > UnshortenUrl ( string url , bool UseHeadMethod = true , int depth = 0 , int maxDepth = 30 )
11
11
{
12
+ if ( depth > maxDepth )
13
+ {
14
+ throw new DepthLimitReachedException ( ) ;
15
+ }
16
+
12
17
_logger ? . LogDebug ( "Unshortening Url '{Url}', using head method: {UseHeadMethod}" , url , UseHeadMethod ) ;
13
18
14
19
HttpClient client = new ( new HttpClientHandler ( )
15
20
{
16
21
AllowAutoRedirect = false ,
17
22
AutomaticDecompression = DecompressionMethods . GZip ,
18
-
19
23
} ) ;
20
24
client . Timeout = TimeSpan . FromSeconds ( 60 ) ;
21
- 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" ) ;
25
+ 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" ) ;
22
26
client . DefaultRequestHeaders . Add ( "upgrade-insecure-requests" , "1" ) ;
23
27
client . DefaultRequestHeaders . Add ( "accept-encoding" , "gzip, deflate, br" ) ;
24
28
client . DefaultRequestHeaders . Add ( "accept-language" , "en-US,en;q=0.9" ) ;
@@ -36,7 +40,7 @@ public static async Task<string> UnshortenUrl(string url, bool UseHeadMethod = t
36
40
catch ( Exception )
37
41
{
38
42
if ( UseHeadMethod )
39
- return await UnshortenUrl ( url , false ) ;
43
+ return await UnshortenUrl ( url , false , depth + 1 , maxDepth ) ;
40
44
41
45
throw ;
42
46
}
@@ -47,7 +51,7 @@ public static async Task<string> UnshortenUrl(string url, bool UseHeadMethod = t
47
51
if ( UseHeadMethod && request_task . IsFaulted && request_task . Exception . InnerException . GetType ( ) == typeof ( HttpRequestException ) )
48
52
{
49
53
_logger ? . LogWarning ( "Unshortening Url '{Url}' failed, falling back to non-head method" , url ) ;
50
- return await UnshortenUrl ( url , false ) ;
54
+ return await UnshortenUrl ( url , false , depth + 1 , maxDepth ) ;
51
55
}
52
56
53
57
var statuscode = request_task . Result . StatusCode ;
@@ -56,7 +60,7 @@ public static async Task<string> UnshortenUrl(string url, bool UseHeadMethod = t
56
60
if ( UseHeadMethod && statuscode is HttpStatusCode . NotFound or HttpStatusCode . InternalServerError )
57
61
{
58
62
_logger ? . LogWarning ( "Unshortening Url '{Url}' failed, falling back to non-head method" , url ) ;
59
- return await UnshortenUrl ( url , false ) ;
63
+ return await UnshortenUrl ( url , false , depth + 1 , maxDepth ) ;
60
64
}
61
65
62
66
if ( statuscode is HttpStatusCode . Found
@@ -68,11 +72,19 @@ or HttpStatusCode.PermanentRedirect
68
72
or HttpStatusCode . TemporaryRedirect )
69
73
{
70
74
if ( header is not null && header . Location is not null )
71
- return await UnshortenUrl ( header . Location . AbsoluteUri ) ;
75
+ {
76
+
77
+ if ( header . Location . IsAbsoluteUri )
78
+ return await UnshortenUrl ( header . Location . AbsoluteUri , UseHeadMethod , depth + 1 , maxDepth ) ;
79
+ else
80
+ return await UnshortenUrl ( new Uri ( requestMessage . RequestUri . GetLeftPart ( UriPartial . Authority ) . ToString ( ) + header . Location . ToString ( ) ) . AbsoluteUri , UseHeadMethod , depth + 1 , maxDepth ) ;
81
+ }
72
82
else
73
83
return url ;
74
84
}
75
85
else
76
86
return url ;
77
87
}
78
88
}
89
+
90
+ public class DepthLimitReachedException : Exception { }
0 commit comments