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();
}
}
}