mirror of
https://github.com/Cleanuparr/Cleanuparr.git
synced 2026-10-31 04:21:23 -04:00
54 lines
1.9 KiB
C#
54 lines
1.9 KiB
C#
namespace Cleanuparr.Persistence.Startup;
|
|
|
|
/// <summary>
|
|
/// Parses and strips URL userinfo (<c>user:pass@host</c>).
|
|
/// </summary>
|
|
public static class UserInfoMigration
|
|
{
|
|
/// <summary>
|
|
/// Splits raw userinfo on the first colon and percent-decodes both sides.
|
|
/// No colon means no password.
|
|
/// An empty username becomes null.
|
|
/// </summary>
|
|
public static UserInfoCredential ParseCredential(string userInfo)
|
|
{
|
|
int separatorIndex = userInfo.IndexOf(':');
|
|
|
|
string usernamePart = separatorIndex < 0 ? userInfo : userInfo[..separatorIndex];
|
|
string? passwordPart = separatorIndex < 0 ? null : userInfo[(separatorIndex + 1)..];
|
|
|
|
string? username = usernamePart.Length == 0 ? null : Uri.UnescapeDataString(usernamePart);
|
|
string? password = passwordPart is null ? null : Uri.UnescapeDataString(passwordPart);
|
|
|
|
return new UserInfoCredential(username, password);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes the userinfo and its <c>@</c>, leaving the rest of the string as is.
|
|
/// <see cref="UriBuilder"/> would normalize the scheme and add a default port and trailing slash.
|
|
/// </summary>
|
|
public static Uri StripUserInfo(Uri host)
|
|
{
|
|
string original = host.OriginalString;
|
|
int authorityStart = original.IndexOf("://", StringComparison.Ordinal) + 3;
|
|
|
|
int authorityEnd = authorityStart;
|
|
while (authorityEnd < original.Length
|
|
&& original[authorityEnd] != '/'
|
|
&& original[authorityEnd] != '?'
|
|
&& original[authorityEnd] != '#')
|
|
{
|
|
authorityEnd++;
|
|
}
|
|
|
|
int atIndex = original.IndexOf('@', authorityStart, authorityEnd - authorityStart);
|
|
if (atIndex < 0)
|
|
{
|
|
return host;
|
|
}
|
|
|
|
string rebuilt = original.Remove(authorityStart, atIndex - authorityStart + 1);
|
|
return new Uri(rebuilt, UriKind.RelativeOrAbsolute);
|
|
}
|
|
}
|