using Microsoft.Extensions.Options; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net; namespace FastGithub.Configuration { /// /// FastGithub配置 /// public class FastGithubConfig { private SortedDictionary domainConfigs; private ConcurrentDictionary domainConfigCache; /// /// http代理端口 /// public int HttpProxyPort { get; set; } /// /// 回退的dns /// public IPEndPoint[] FallbackDns { get; set; } /// /// FastGithub配置 /// /// /// public FastGithubConfig(IOptionsMonitor options) { var opt = options.CurrentValue; this.HttpProxyPort = opt.HttpProxyPort; this.FallbackDns = opt.FallbackDns; this.domainConfigs = ConvertDomainConfigs(opt.DomainConfigs); this.domainConfigCache = new ConcurrentDictionary(); options.OnChange(opt => this.Update(opt)); } /// /// 更新配置 /// /// private void Update(FastGithubOptions options) { this.HttpProxyPort = options.HttpProxyPort; this.FallbackDns = options.FallbackDns; this.domainConfigs = ConvertDomainConfigs(options.DomainConfigs); this.domainConfigCache = new ConcurrentDictionary(); } /// /// 配置转换 /// /// /// private static SortedDictionary ConvertDomainConfigs(Dictionary domainConfigs) { var result = new SortedDictionary(); foreach (var kv in domainConfigs) { result.Add(new DomainPattern(kv.Key), kv.Value); } return result; } /// /// 是否匹配指定的域名 /// /// /// public bool IsMatch(string domain) { return this.TryGetDomainConfig(domain, out _); } /// /// 尝试获取域名配置 /// /// /// /// public bool TryGetDomainConfig(string domain, [MaybeNullWhen(false)] out DomainConfig value) { value = this.domainConfigCache.GetOrAdd(domain, GetDomainConfig); return value != null; DomainConfig? GetDomainConfig(string domain) { var key = this.domainConfigs.Keys.FirstOrDefault(item => item.IsMatch(domain)); return key == null ? null : this.domainConfigs[key]; } } /// /// 获取所有域名表达式 /// /// public DomainPattern[] GetDomainPatterns() { return this.domainConfigs.Keys.ToArray(); } } }