From 771b5ead91c0703d02dab1794061140cd2ccefb2 Mon Sep 17 00:00:00 2001 From: Nicholas Schell Date: Mon, 2 Sep 2024 14:35:20 -0700 Subject: [PATCH] Fix: Volumes paginated (#3) * small bug when creating paginated list for Volumes (doesn't seem to be an issue for other paginations) * wrong string --- DigitalOcean.API/DigitalOceanClient.cs | 4 +++- DigitalOcean.API/Http/Connection.cs | 21 ++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/DigitalOcean.API/DigitalOceanClient.cs b/DigitalOcean.API/DigitalOceanClient.cs index 29d24cd..2f0a671 100644 --- a/DigitalOcean.API/DigitalOceanClient.cs +++ b/DigitalOcean.API/DigitalOceanClient.cs @@ -5,7 +5,9 @@ namespace DigitalOcean.API { public class DigitalOceanClient : IDigitalOceanClient { - public static readonly string DigitalOceanApiUrl = "https://api.digitalocean.com/v2/"; + // some APIs return only a relative URL of next paginated call + public const string RelativeUrl = "/v2/"; + public const string DigitalOceanApiUrl = "https://api.digitalocean.com" + RelativeUrl; private readonly IConnection _connection; public DigitalOceanClient(string token) { diff --git a/DigitalOcean.API/Http/Connection.cs b/DigitalOcean.API/Http/Connection.cs index da5862d..33220f6 100644 --- a/DigitalOcean.API/Http/Connection.cs +++ b/DigitalOcean.API/Http/Connection.cs @@ -62,7 +62,26 @@ public async Task> GetPaginated(string endpoint, IList(data); while (page != null && page.Pages != null && !String.IsNullOrWhiteSpace(page.Pages.Next)) { - endpoint = page.Pages.Next.Replace(DigitalOceanClient.DigitalOceanApiUrl, ""); + // some APIs seem to return the full URL in paginated links (or there is some code populating this? + // but others (notably /v2/volumes) returns only the relative URL + // maybe this was a bug introduced by DO? or it has always been this way, unknown + var absoluteIndex = page.Pages.Next.IndexOf(DigitalOceanClient.DigitalOceanApiUrl, StringComparison.Ordinal); + if (absoluteIndex == 0) { + // standard replacement of full URL (only if matches from beginning of string) + endpoint = page.Pages.Next.Substring(DigitalOceanClient.DigitalOceanApiUrl.Length); + } + else { + // test if relative URL replacement, and only replace from beginning of string + var relativeIndex = page.Pages.Next.IndexOf(DigitalOceanClient.RelativeUrl, StringComparison.Ordinal); + if (relativeIndex == 0) { + endpoint = page.Pages.Next.Substring(DigitalOceanClient.RelativeUrl.Length); + } + else { + // likely will error, but nothing is match to replacement + endpoint = page.Pages.Next; + } + } + var iter = await ExecuteRaw(endpoint, null).ConfigureAwait(false); parsedJson = (JObject)JsonConvert.DeserializeObject(iter.Content);