diff --git a/SabreTools.RedumpLib/RedumpInfo/Client.cs b/SabreTools.RedumpLib/RedumpInfo/Client.cs
index fa226a4..c1ecd52 100644
--- a/SabreTools.RedumpLib/RedumpInfo/Client.cs
+++ b/SabreTools.RedumpLib/RedumpInfo/Client.cs
@@ -379,6 +379,67 @@ namespace SabreTools.RedumpLib.RedumpInfo
return null;
}
+ ///
+ /// Get the resolved URL for a given URI
+ ///
+ /// Remote URI to retrieve
+ /// Final URL, null on error
+ public async Task GetResolvedURL(string uri)
+ {
+ // Only retry a positive number of times
+ if (AttemptCount <= 0)
+ {
+ Console.Error.WriteLine("Invalid number of attempts provided, must be at least 1");
+ return null;
+ }
+
+ for (int i = 0; i < AttemptCount; i++)
+ {
+ try
+ {
+ if (Debug) Console.WriteLine($"DEBUG: GetResolvedURL(\"{uri}\"), Attempt {i + 1} of {AttemptCount}");
+#if NETCOREAPP
+ // Make the call to get the file
+ var response = await _internalClient.GetAsync(uri);
+ if (response?.Content?.Headers is null || !response.IsSuccessStatusCode)
+ {
+ if (Debug) Console.Error.WriteLine($"DEBUG: GetResolvedURL failed, continuing...");
+ continue;
+ }
+
+ return response.RequestMessage?.RequestUri?.AbsoluteUri;
+#elif NET40
+ await Task.Factory.StartNew(() => { _internalClient.DownloadData(uri); return true; });
+ string? lastUrl = _internalClient.LastUrl?.AbsoluteUri;
+ if (lastUrl is null)
+ {
+ if (Debug) Console.Error.WriteLine($"DEBUG: GetResolvedURL failed, continuing...");
+ continue;
+ }
+
+ return lastUrl;
+#else
+ await Task.Run(() => _internalClient.DownloadData(uri));
+ string? lastUrl = _internalClient.LastUrl?.AbsoluteUri;
+ if (lastUrl is null)
+ {
+ if (Debug) Console.Error.WriteLine($"DEBUG: GetResolvedURL failed, continuing...");
+ continue;
+ }
+
+ return lastUrl;
+#endif
+ }
+ catch { }
+
+ // Intentional delay here so we don't flood the server
+ DelayHelper.DelayRandom();
+ }
+
+ Console.Error.WriteLine($"Could not download \"{uri}\" after {AttemptCount} attempts");
+ return null;
+ }
+
#endregion
#region Single Page Helpers
@@ -449,11 +510,15 @@ namespace SabreTools.RedumpLib.RedumpInfo
if (dumpsPage.Contains("Disc
"))
{
if (Debug) Console.WriteLine($"DEBUG: CheckSingleDiscsPage(\"{url}\") - Single disc page");
- var value = Regex.Match(dumpsPage, pattern: @"/disc/([0-9]+)/edit").Groups[1].Value;
- if (int.TryParse(value, out int id))
- ids.Add(id);
+ string? lastUrl = await GetResolvedURL(url);
+ if (lastUrl is not null)
+ {
+ var value = Regex.Match(lastUrl, pattern: @"/disc/([0-9]+)").Groups[1].Value;
+ if (int.TryParse(value, out int id))
+ ids.Add(id);
- return ids;
+ return ids;
+ }
}
// Otherwise, traverse each dump on the page
diff --git a/SabreTools.RedumpLib/Web/CookieWebClient.cs b/SabreTools.RedumpLib/Web/CookieWebClient.cs
index 6e084a5..358116d 100644
--- a/SabreTools.RedumpLib/Web/CookieWebClient.cs
+++ b/SabreTools.RedumpLib/Web/CookieWebClient.cs
@@ -8,6 +8,11 @@ namespace SabreTools.RedumpLib.Web
#endif
internal class CookieWebClient : WebClient
{
+ ///
+ /// Last retrieved URL from a web request
+ ///
+ public Uri? LastUrl { get; private set; }
+
///
/// The timespan to wait before the request times out.
///
@@ -50,6 +55,14 @@ namespace SabreTools.RedumpLib.Web
return request;
}
+
+ ///
+ protected override WebResponse GetWebResponse(WebRequest request)
+ {
+ WebResponse response = base.GetWebResponse(request);
+ LastUrl = response.ResponseUri;
+ return response;
+ }
}
#if NET6_0_OR_GREATER
#pragma warning restore SYSLIB0014