123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- 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
- {
- /// <summary>
- /// FastGithub配置
- /// </summary>
- public class FastGithubConfig
- {
- private SortedDictionary<DomainPattern, DomainConfig> domainConfigs;
- private ConcurrentDictionary<string, DomainConfig?> domainConfigCache;
- /// <summary>
- /// http代理端口
- /// </summary>
- public int HttpProxyPort { get; set; }
- /// <summary>
- /// 回退的dns
- /// </summary>
- public IPEndPoint[] FallbackDns { get; set; }
- /// <summary>
- /// FastGithub配置
- /// </summary>
- /// <param name="options"></param>
- /// <param name="logger"></param>
- public FastGithubConfig(IOptionsMonitor<FastGithubOptions> options)
- {
- var opt = options.CurrentValue;
- this.HttpProxyPort = opt.HttpProxyPort;
- this.FallbackDns = ConvertToIPEndPoints(opt.FallbackDns).ToArray();
- this.domainConfigs = ConvertDomainConfigs(opt.DomainConfigs);
- this.domainConfigCache = new ConcurrentDictionary<string, DomainConfig?>();
- options.OnChange(opt => this.Update(opt));
- }
- /// <summary>
- /// 更新配置
- /// </summary>
- /// <param name="options"></param>
- private void Update(FastGithubOptions options)
- {
- this.HttpProxyPort = options.HttpProxyPort;
- this.FallbackDns = ConvertToIPEndPoints(options.FallbackDns).ToArray();
- this.domainConfigs = ConvertDomainConfigs(options.DomainConfigs);
- this.domainConfigCache = new ConcurrentDictionary<string, DomainConfig?>();
- }
- /// <summary>
- /// 转换为IPEndPoint
- /// </summary>
- /// <param name="ipEndPoints"></param>
- /// <returns></returns>
- private static IEnumerable<IPEndPoint> ConvertToIPEndPoints(IEnumerable<string> ipEndPoints)
- {
- foreach (var item in ipEndPoints)
- {
- if (IPEndPoint.TryParse(item, out var endPoint))
- {
- yield return endPoint;
- }
- }
- }
- /// <summary>
- /// 配置转换
- /// </summary>
- /// <param name="domainConfigs"></param>
- /// <returns></returns>
- private static SortedDictionary<DomainPattern, DomainConfig> ConvertDomainConfigs(Dictionary<string, DomainConfig> domainConfigs)
- {
- var result = new SortedDictionary<DomainPattern, DomainConfig>();
- foreach (var kv in domainConfigs)
- {
- result.Add(new DomainPattern(kv.Key), kv.Value);
- }
- return result;
- }
- /// <summary>
- /// 是否匹配指定的域名
- /// </summary>
- /// <param name="domain"></param>
- /// <returns></returns>
- public bool IsMatch(string domain)
- {
- return this.TryGetDomainConfig(domain, out _);
- }
- /// <summary>
- /// 尝试获取域名配置
- /// </summary>
- /// <param name="domain"></param>
- /// <param name="value"></param>
- /// <returns></returns>
- 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];
- }
- }
- /// <summary>
- /// 获取所有域名表达式
- /// </summary>
- /// <returns></returns>
- public DomainPattern[] GetDomainPatterns()
- {
- return this.domainConfigs.Keys.ToArray();
- }
- }
- }
|