diff --git a/FastGithub.Core/DomainMatch.cs b/FastGithub.Core/DomainMatch.cs index 8c2d438..2ce7b5b 100644 --- a/FastGithub.Core/DomainMatch.cs +++ b/FastGithub.Core/DomainMatch.cs @@ -1,11 +1,12 @@ -using System.Text.RegularExpressions; +using System; +using System.Text.RegularExpressions; namespace FastGithub { /// /// 域名匹配 /// - public class DomainMatch + public class DomainMatch : IComparable { private readonly Regex regex; private readonly string domainPattern; @@ -21,6 +22,82 @@ namespace FastGithub this.regex = new Regex($"^{regexPattern}$", RegexOptions.IgnoreCase); } + /// + /// 与目标比较 + /// + /// + /// + public int CompareTo(DomainMatch? other) + { + if (other is null) + { + return 1; + } + + var segmentsX = this.domainPattern.Split('.'); + var segmentsY = other.domainPattern.Split('.'); + if (segmentsX.Length > segmentsY.Length) + { + return 1; + } + if (segmentsX.Length < segmentsY.Length) + { + return -1; + } + + for (var i = 0; i < segmentsX.Length; i++) + { + var x = segmentsX[i]; + var y = segmentsY[i]; + + var value = Compare(x, y); + if (value == 0) + { + continue; + } + return value; + } + + return 0; + } + + + /// + /// 比较两个分段 + /// + /// abc + /// abc* + /// + private static int Compare(string x, string y) + { + if (x == y) + { + return 0; + } + + var valueX = x.Replace("*", null); + var valueY = y.Replace("*", null); + + var maskX = x.Length - valueX.Length; + var maskY = y.Length - valueY.Length; + if (maskX == 0 && maskY > 0) + { + return -1; + } + if (maskY == 0 && maskX > 0) + { + return 1; + } + + var value = valueX.CompareTo(valueY); + if (value == 0) + { + value = x.CompareTo(y); + } + return value; + } + + /// /// 是否与指定域名匹配 /// diff --git a/FastGithub.Core/FastGithubConfig.cs b/FastGithub.Core/FastGithubConfig.cs index f0413b3..4b2dd63 100644 --- a/FastGithub.Core/FastGithubConfig.cs +++ b/FastGithub.Core/FastGithubConfig.cs @@ -30,7 +30,7 @@ namespace FastGithub /// /// 获取域名配置 /// - public Dictionary DomainConfigs { get; private set; } + public SortedDictionary DomainConfigs { get; private set; } /// /// FastGithub配置 @@ -42,12 +42,12 @@ namespace FastGithub ILogger logger) { this.logger = logger; - var opt = options.CurrentValue; - this.domainConfigCache = new ConcurrentDictionary(); + this.PureDns = opt.PureDns.ToIPEndPoint(); this.FastDns = opt.FastDns.ToIPEndPoint(); - this.DomainConfigs = opt.DomainConfigs.ToDictionary(kv => new DomainMatch(kv.Key), kv => kv.Value); + this.DomainConfigs = ConvertDomainConfigs(opt.DomainConfigs); + this.domainConfigCache = new ConcurrentDictionary(); options.OnChange(opt => this.Update(opt)); } @@ -60,10 +60,10 @@ namespace FastGithub { try { - this.domainConfigCache = new ConcurrentDictionary(); this.PureDns = options.PureDns.ToIPEndPoint(); this.FastDns = options.FastDns.ToIPEndPoint(); - this.DomainConfigs = options.DomainConfigs.ToDictionary(kv => new DomainMatch(kv.Key), kv => kv.Value); + this.DomainConfigs = ConvertDomainConfigs(options.DomainConfigs); + this.domainConfigCache = new ConcurrentDictionary(); } catch (Exception ex) { @@ -71,6 +71,21 @@ namespace FastGithub } } + /// + /// 配置转换 + /// + /// + /// + private static SortedDictionary ConvertDomainConfigs(Dictionary domainConfigs) + { + var result = new SortedDictionary(); + foreach (var kv in domainConfigs) + { + result.Add(new DomainMatch(kv.Key), kv.Value); + } + return result; + } + /// /// 是否匹配指定的域名 ///