XFEExtension.NetCore.ServerInteractive
[DLL] Server interaction extension, including user identity verification and querying in conjunction with AutoConfig
关注
0
Fork
0
Star
0
namespace XFEExtension.NetCore.ServerInteractive.Utilities.Helpers;
/// <summary>
/// 路由通配符匹配辅助类
/// </summary>
internal static class RouteMatchHelper
{
/// <summary>
/// 判断路由是否包含通配符
/// </summary>
/// <param name="pattern">路由模式</param>
/// <returns>是否包含通配符</returns>
public static bool IsWildcardRoute(string pattern) => pattern.Split('/').Any(segment => segment is "*" or "**");
/// <summary>验证通配符必须独占路径段,且双星号只能出现在末尾。</summary>
public static void ValidatePattern(string pattern)
{
ArgumentException.ThrowIfNullOrWhiteSpace(pattern);
var segments = pattern.Split('/');
if (segments.Any(segment => segment.Length == 0 || segment.Contains('*') && segment is not ("*" or "**")) ||
Array.IndexOf(segments, "**") is var catchAllIndex && catchAllIndex >= 0 && catchAllIndex != segments.Length - 1)
throw new ArgumentException($"路由模式无效:'{pattern}'。* 必须匹配一个完整路径段,** 只能作为最后一个路径段。", nameof(pattern));
}
/// <summary>
/// 将路由模式与实际路由进行通配符匹配
/// <para>支持的通配符:</para>
/// <para>- <c>*</c>:匹配一个路径段</para>
/// <para>- <c>**</c>:匹配零个或多个剩余路径段,且只能位于末尾</para>
/// <para>- <c>v1/*</c>:匹配 v1/ 后跟一个路径段</para>
/// <para>- <c>v1/*/test</c>:匹配 v1/ 后跟任意一个段再跟 /test</para>
/// </summary>
/// <param name="pattern">包含通配符的路由模式</param>
/// <param name="route">实际请求路由</param>
/// <returns>是否匹配</returns>
public static bool MatchWildcardRoute(string pattern, string route)
{
var patternSegments = pattern.Split('/', StringSplitOptions.RemoveEmptyEntries);
var routeSegments = route.Split('/', StringSplitOptions.RemoveEmptyEntries);
var catchAllIndex = Array.IndexOf(patternSegments, "**");
if (catchAllIndex >= 0 && catchAllIndex != patternSegments.Length - 1)
return false;
if (catchAllIndex < 0 && patternSegments.Length != routeSegments.Length)
return false;
if (catchAllIndex >= 0 && routeSegments.Length < catchAllIndex)
return false;
var comparisonLength = catchAllIndex >= 0 ? catchAllIndex : patternSegments.Length;
for (var index = 0; index < comparisonLength; index++)
{
if (patternSegments[index] == "*") continue;
if (!patternSegments[index].Equals(routeSegments[index], StringComparison.Ordinal)) return false;
}
return true;
}
/// <summary>
/// 计算路由模式的优先级,优先级规则如下
/// </summary>
/// <param name="pattern"></param>
/// <returns></returns>
public static int GetWildcardPatternPriority(string pattern)
{
var segments = pattern.Split('/', StringSplitOptions.RemoveEmptyEntries);
var literalSegmentCount = 0;
var wildcardSegmentCount = 0;
foreach (var segment in segments)
{
if (segment is "*" or "**")
wildcardSegmentCount++;
else
literalSegmentCount++;
}
return (literalSegmentCount * 1000) - (wildcardSegmentCount * 10) + pattern.Length;
}
}
namespace XFEExtension.NetCore.ServerInteractive.Utilities.Helpers;
/// <summary>
/// 路由通配符匹配辅助类
/// </summary>
internal static class RouteMatchHelper
{
/// <summary>
/// 判断路由是否包含通配符
/// </summary>
/// <param name="pattern">路由模式</param>
/// <returns>是否包含通配符</returns>
public static bool IsWildcardRoute(string pattern) => pattern.Split('/').Any(segment => segment is "*" or "**");
/// <summary>验证通配符必须独占路径段,且双星号只能出现在末尾。</summary>
public static void ValidatePattern(string pattern)
{
ArgumentException.ThrowIfNullOrWhiteSpace(pattern);
var segments = pattern.Split('/');
if (segments.Any(segment => segment.Length == 0 || segment.Contains('*') && segment is not ("*" or "**")) ||
Array.IndexOf(segments, "**") is var catchAllIndex && catchAllIndex >= 0 && catchAllIndex != segments.Length - 1)
throw new ArgumentException($"路由模式无效:'{pattern}'。* 必须匹配一个完整路径段,** 只能作为最后一个路径段。", nameof(pattern));
}
/// <summary>
/// 将路由模式与实际路由进行通配符匹配
/// <para>支持的通配符:</para>
/// <para>- <c>*</c>:匹配一个路径段</para>
/// <para>- <c>**</c>:匹配零个或多个剩余路径段,且只能位于末尾</para>
/// <para>- <c>v1/*</c>:匹配 v1/ 后跟一个路径段</para>
/// <para>- <c>v1/*/test</c>:匹配 v1/ 后跟任意一个段再跟 /test</para>
/// </summary>
/// <param name="pattern">包含通配符的路由模式</param>
/// <param name="route">实际请求路由</param>
/// <returns>是否匹配</returns>
public static bool MatchWildcardRoute(string pattern, string route)
{
var patternSegments = pattern.Split('/', StringSplitOptions.RemoveEmptyEntries);
var routeSegments = route.Split('/', StringSplitOptions.RemoveEmptyEntries);
var catchAllIndex = Array.IndexOf(patternSegments, "**");
if (catchAllIndex >= 0 && catchAllIndex != patternSegments.Length - 1)
return false;
if (catchAllIndex < 0 && patternSegments.Length != routeSegments.Length)
return false;
if (catchAllIndex >= 0 && routeSegments.Length < catchAllIndex)
return false;
var comparisonLength = catchAllIndex >= 0 ? catchAllIndex : patternSegments.Length;
for (var index = 0; index < comparisonLength; index++)
{
if (patternSegments[index] == "*") continue;
if (!patternSegments[index].Equals(routeSegments[index], StringComparison.Ordinal)) return false;
}
return true;
}
/// <summary>
/// 计算路由模式的优先级,优先级规则如下
/// </summary>
/// <param name="pattern"></param>
/// <returns></returns>
public static int GetWildcardPatternPriority(string pattern)
{
var segments = pattern.Split('/', StringSplitOptions.RemoveEmptyEntries);
var literalSegmentCount = 0;
var wildcardSegmentCount = 0;
foreach (var segment in segments)
{
if (segment is "*" or "**")
wildcardSegmentCount++;
else
literalSegmentCount++;
}
return (literalSegmentCount * 1000) - (wildcardSegmentCount * 10) + pattern.Length;
}
}