using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net;
namespace FastGithub
{
///
/// FastGithub配置
///
public class FastGithubConfig
{
private readonly ILogger logger;
private ConcurrentDictionary domainConfigCache;
///
/// 未污染的dns
///
public IPEndPoint PureDns { get; private set; }
///
/// 速度快的dns
///
public IPEndPoint FastDns { get; private set; }
///
/// 获取域名配置
///
public Dictionary DomainConfigs { get; private set; }
///
/// FastGithub配置
///
///
///
public FastGithubConfig(
IOptionsMonitor options,
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);
options.OnChange(opt => this.Update(opt));
}
///
/// 更新配置
///
///
private void Update(FastGithubOptions options)
{
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);
}
catch (Exception ex)
{
this.logger.LogError(ex.Message);
}
}
///
/// 是否匹配指定的域名
///
///
///
public bool IsMatch(string domain)
{
return this.DomainConfigs.Keys.Any(item => item.IsMatch(domain));
}
///
/// 尝试获取域名配置
///
///
///
///
public bool TryGetDomainConfig(string domain, [MaybeNullWhen(false)] out DomainConfig value)
{
value = this.domainConfigCache.GetOrAdd(domain, this.GetDomainConfig);
return value != null;
}
///
/// 获取域名配置
///
///
///
private DomainConfig? GetDomainConfig(string domain)
{
var key = this.DomainConfigs.Keys.FirstOrDefault(item => item.IsMatch(domain));
return key == null ? null : this.DomainConfigs[key];
}
}
}