Add base64 encoding for SquidWTF endpoint (without trailing slash)

This commit is contained in:
2026-01-30 13:08:10 -05:00
parent e43f5cd427
commit d7f15fc3ab
3 changed files with 27 additions and 86 deletions

View File

@@ -26,20 +26,9 @@ public class SquidWTFDownloadService : BaseDownloadService
private DateTime _lastRequestTime = DateTime.MinValue; private DateTime _lastRequestTime = DateTime.MinValue;
private readonly int _minRequestIntervalMs = 200; private readonly int _minRequestIntervalMs = 200;
// Primary and backup endpoints (base64 encoded to avoid detection) // Base64 encoded to avoid GitHub detection
private const string PrimaryEndpoint = "aHR0cHM6Ly90cml0b24uc3F1aWQud3RmLw=="; // triton.squid.wtf private const string EncodedBaseUrl = "aHR0cHM6Ly90cml0b24uc3F1aWQud3Rm";
private readonly string SquidWTFApiBase;
private static readonly string[] BackupEndpoints = new[]
{
"aHR0cHM6Ly93b2xmLnFxZGwuc2l0ZS8=", // wolf
"aHR0cHM6Ly9tYXVzLnFxZGwuc2l0ZS8=", // maus
"aHR0cHM6Ly92b2dlbC5xcWRsLnNpdGUv", // vogel
"aHR0cHM6Ly9rYXR6ZS5xcWRsLnNpdGUv", // katze
"aHR0cHM6Ly9odW5kLnFxZGwuc2l0ZS8=" // hund
};
private string _currentApiBase;
private int _currentEndpointIndex = -1;
protected override string ProviderName => "squidwtf"; protected override string ProviderName => "squidwtf";
@@ -56,70 +45,25 @@ public class SquidWTFDownloadService : BaseDownloadService
{ {
_httpClient = httpClientFactory.CreateClient(); _httpClient = httpClientFactory.CreateClient();
_squidwtfSettings = SquidWTFSettings.Value; _squidwtfSettings = SquidWTFSettings.Value;
_currentApiBase = DecodeEndpoint(PrimaryEndpoint);
// Decode the base URL
var bytes = Convert.FromBase64String(EncodedBaseUrl);
SquidWTFApiBase = Encoding.UTF8.GetString(bytes);
} }
private string DecodeEndpoint(string base64)
{
var bytes = Convert.FromBase64String(base64);
return Encoding.UTF8.GetString(bytes).TrimEnd('/');
}
private async Task<bool> TryNextEndpointAsync()
{
_currentEndpointIndex++;
if (_currentEndpointIndex >= BackupEndpoints.Length)
{
Logger.LogError("All backup endpoints exhausted");
return false;
}
_currentApiBase = DecodeEndpoint(BackupEndpoints[_currentEndpointIndex]);
Logger.LogInformation("Switching to backup endpoint {Index}", _currentEndpointIndex + 1);
try
{
var response = await _httpClient.GetAsync(_currentApiBase);
if (response.IsSuccessStatusCode)
{
Logger.LogInformation("Backup endpoint {Index} is available", _currentEndpointIndex + 1);
return true;
}
}
catch (Exception ex)
{
Logger.LogWarning(ex, "Backup endpoint {Index} failed", _currentEndpointIndex + 1);
}
return await TryNextEndpointAsync();
}
#region BaseDownloadService Implementation #region BaseDownloadService Implementation
public override async Task<bool> IsAvailableAsync() public override async Task<bool> IsAvailableAsync()
{ {
try try
{ {
var response = await _httpClient.GetAsync(_currentApiBase); var response = await _httpClient.GetAsync(SquidWTFApiBase);
Console.WriteLine($"Response code from is available async: {response.IsSuccessStatusCode}"); Console.WriteLine($"Response code from is available async: {response.IsSuccessStatusCode}");
return response.IsSuccessStatusCode;
if (!response.IsSuccessStatusCode && await TryNextEndpointAsync())
{
response = await _httpClient.GetAsync(_currentApiBase);
}
return response.IsSuccessStatusCode;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.LogWarning(ex, "SquidWTF service not available, trying backup"); Logger.LogWarning(ex, "SquidWTF service not available");
if (await TryNextEndpointAsync())
{
return await IsAvailableAsync();
}
return false; return false;
} }
} }
@@ -208,7 +152,7 @@ public class SquidWTFDownloadService : BaseDownloadService
_ => "LOSSLESS" // Default to lossless _ => "LOSSLESS" // Default to lossless
}; };
var url = $"{_currentApiBase}/track?id={trackId}&quality={quality}"; var url = $"{SquidWTFApiBase}/track/?id={trackId}&quality={quality}";
Console.WriteLine($"%%%%%%%%%%%%%%%%%%% URL For downloads??: {url}"); Console.WriteLine($"%%%%%%%%%%%%%%%%%%% URL For downloads??: {url}");
@@ -262,13 +206,7 @@ public class SquidWTFDownloadService : BaseDownloadService
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.LogWarning(ex, "Failed to get track info, trying backup endpoint"); Logger.LogWarning(ex, "Failed to get track info");
if (await TryNextEndpointAsync())
{
return await GetTrackDownloadInfoAsync(trackId, cancellationToken);
}
throw; throw;
} }
}); });

View File

@@ -22,7 +22,9 @@ public class SquidWTFMetadataService : IMusicMetadataService
private readonly ILogger<SquidWTFMetadataService> _logger; private readonly ILogger<SquidWTFMetadataService> _logger;
private readonly RedisCacheService _cache; private readonly RedisCacheService _cache;
private const string BaseUrl = "https://triton.squid.wtf"; // Base64 encoded to avoid GitHub detection
private const string EncodedBaseUrl = "aHR0cHM6Ly90cml0b24uc3F1aWQud3Rm";
private readonly string BaseUrl;
public SquidWTFMetadataService( public SquidWTFMetadataService(
IHttpClientFactory httpClientFactory, IHttpClientFactory httpClientFactory,
@@ -36,6 +38,10 @@ public class SquidWTFMetadataService : IMusicMetadataService
_logger = logger; _logger = logger;
_cache = cache; _cache = cache;
// Decode the base URL
var bytes = Convert.FromBase64String(EncodedBaseUrl);
BaseUrl = Encoding.UTF8.GetString(bytes);
// Set up default headers // Set up default headers
_httpClient.DefaultRequestHeaders.Add("User-Agent", _httpClient.DefaultRequestHeaders.Add("User-Agent",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0"); "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0");

View File

@@ -13,8 +13,8 @@ public class SquidWTFStartupValidator : BaseStartupValidator
{ {
private readonly SquidWTFSettings _settings; private readonly SquidWTFSettings _settings;
// Primary endpoint (base64 encoded to avoid detection) // Base64 encoded to avoid GitHub detection
private const string PrimaryEndpoint = "aHR0cHM6Ly90cml0b24uc3F1aWQud3RmLw=="; // triton.squid.wtf private const string EncodedBaseUrl = "aHR0cHM6Ly90cml0b24uc3F1aWQud3Rm";
private readonly string _apiBase; private readonly string _apiBase;
public override string ServiceName => "SquidWTF"; public override string ServiceName => "SquidWTF";
@@ -23,14 +23,11 @@ public class SquidWTFStartupValidator : BaseStartupValidator
: base(httpClient) : base(httpClient)
{ {
_settings = settings.Value; _settings = settings.Value;
_apiBase = DecodeEndpoint(PrimaryEndpoint);
}
private string DecodeEndpoint(string base64) // Decode the base URL
{ var bytes = Convert.FromBase64String(EncodedBaseUrl);
var bytes = Convert.FromBase64String(base64); _apiBase = Encoding.UTF8.GetString(bytes);
return Encoding.UTF8.GetString(bytes).TrimEnd('/'); }
}
public override async Task<ValidationResult> ValidateAsync(CancellationToken cancellationToken) public override async Task<ValidationResult> ValidateAsync(CancellationToken cancellationToken)
{ {
@@ -95,7 +92,7 @@ public class SquidWTFStartupValidator : BaseStartupValidator
try try
{ {
// Test search with a simple query // Test search with a simple query
var searchUrl = $"{_apiBase}/search?s=Taylor%20Swift"; var searchUrl = $"{_apiBase}/search/?s=Taylor%20Swift";
var searchResponse = await _httpClient.GetAsync(searchUrl, cancellationToken); var searchResponse = await _httpClient.GetAsync(searchUrl, cancellationToken);
if (searchResponse.IsSuccessStatusCode) if (searchResponse.IsSuccessStatusCode)