Files
se-launcher/NuGet/NuGetClient.cs
pas2704 b12f1cc2f1
All checks were successful
Build / Compute Version (push) Successful in 6s
Build / Build Nuget package (SharedCringe) (push) Successful in 1m4s
Build / Build Nuget package (NuGet) (push) Successful in 1m6s
Build / Build Nuget package (CringeBootstrap.Abstractions) (push) Successful in 1m10s
Build / Build Nuget package (CringePlugins) (push) Successful in 1m18s
Build / Build Launcher (push) Successful in 1m54s
Retry source requests
Handle missing sources
Minor Optimizations
Move thread pool improvement to debug while we fix it
2025-06-01 11:11:50 -04:00

144 lines
4.7 KiB
C#

using System.Net;
using System.Net.Http.Json;
using System.Text.Json;
using System.Web;
using NuGet.Converters;
using NuGet.Models;
using NuGet.Versioning;
namespace NuGet;
public class NuGetClient
{
private readonly Uri _index;
private readonly HttpClient _client;
private readonly Uri _packageBaseAddress;
private readonly Uri _registration;
private readonly Uri _search;
public static JsonSerializerOptions SerializerOptions { get; } = new(JsonSerializerDefaults.Web)
{
Converters =
{
new VersionJsonConverter(),
new VersionRangeJsonConverter(),
new FrameworkJsonConverter(FrameworkNameFormat.ShortFolderName),
},
WriteIndented = true
};
private NuGetClient(Uri index, HttpClient client, Uri packageBaseAddress, Uri registration, Uri search)
{
_index = index;
_client = client;
_packageBaseAddress = packageBaseAddress;
_registration = registration;
_search = search;
}
public Task<Stream> GetPackageContentStreamAsync(string id, NuGetVersion version)
{
id = id.ToLower();
return _client.GetStreamAsync(new Uri(_packageBaseAddress,
new Uri($"{id}/{version}/{id}.{version}.nupkg", UriKind.Relative)));
}
public Task<Registration> GetPackageRegistrationAsync(string id, NuGetVersion version)
{
return _client.GetFromJsonAsync<Registration>(
new Uri(_registration,
new Uri($"{id.ToLower()}/{version}.json", UriKind.Relative)),
SerializerOptions
)!;
}
public Task<RegistrationRoot> GetPackageRegistrationRootAsync(string id)
{
return _client.GetFromJsonAsync<RegistrationRoot>(
new Uri(_registration,
new Uri($"{id.ToLower()}/index.json", UriKind.Relative)),
SerializerOptions
)!;
}
public Task<CatalogEntry> GetPackageCatalogEntryAsync(string url)
{
return _client.GetFromJsonAsync<CatalogEntry>(url, SerializerOptions)!;
}
public Task<SearchResult> SearchPackagesAsync(string? query = null, int? skip = null, int? take = null,
bool? includePrerelease = null, NuGetVersion? minVersion = null, string? packageType = null)
{
var queryParameters = HttpUtility.ParseQueryString(string.Empty);
if (!string.IsNullOrEmpty(query))
queryParameters.Add("q", query);
if (skip.HasValue)
queryParameters.Add("skip", skip.Value.ToString());
if (take.HasValue)
queryParameters.Add("take", take.Value.ToString());
if (includePrerelease.HasValue)
queryParameters.Add("prerelease", includePrerelease.Value.ToString());
if (minVersion is not null)
queryParameters.Add("semVerLevel", minVersion.ToString());
if (!string.IsNullOrEmpty(packageType))
queryParameters.Add("packageType", packageType);
var builder = new UriBuilder(_search)
{
Query = queryParameters.ToString()
};
return _client.GetFromJsonAsync<SearchResult>(builder.Uri, SerializerOptions)!;
}
public static async Task<NuGetClient?> CreateFromIndexUrlAsync(string indexUrl)
{
var client = new HttpClient(new HttpClientHandler
{
AutomaticDecompression = DecompressionMethods.All,
});
NuGetClient? ngClient = null;
const int MaxRetries = 10;
for (var i = 0; i < MaxRetries; i++)
{
try
{
var index = await client.GetFromJsonAsync<NuGetIndex>(indexUrl, SerializerOptions);
var (packageBaseAddress, _, _) = index!.Resources.First(b => b.Type.Id == "PackageBaseAddress");
var (registration, _, _) = index.Resources.First(b => b.Type.Id == "RegistrationsBaseUrl");
var (search, _, _) = index.Resources.First(b => b.Type.Id == "SearchQueryService");
if (!packageBaseAddress.EndsWith('/'))
packageBaseAddress += '/';
if (!registration.EndsWith('/'))
registration += '/';
ngClient = new NuGetClient(new Uri(indexUrl), client, new Uri(packageBaseAddress), new Uri(registration), new Uri(search));
break;
}
catch (HttpRequestException ex)
{
Console.WriteLine(ex.Message);
}
}
return ngClient;
}
public override string ToString() => _index.ToString();
public override bool Equals(object? obj) => obj is NuGetClient { _index: { } index } && index == _index;
public override int GetHashCode() => _index.GetHashCode();
}