FastGithub/FastGithub.Dns/HostsConflictValidator.cs
2021-09-15 09:58:29 +08:00

118 lines
3.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using FastGithub.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Net;
using System.Threading.Tasks;
namespace FastGithub.Dns
{
/// <summary>
/// host文件冲突验证器
/// </summary>
sealed class HostsConflictValidator : IConflictValidator
{
private readonly FastGithubConfig fastGithubConfig;
private readonly ILogger<HostsConflictValidator> logger;
/// <summary>
/// host文件冲突验证器
/// </summary>
/// <param name="fastGithubConfig"></param>
/// <param name="logger"></param>
public HostsConflictValidator(
FastGithubConfig fastGithubConfig,
ILogger<HostsConflictValidator> logger)
{
this.fastGithubConfig = fastGithubConfig;
this.logger = logger;
}
/// <summary>
/// 验证冲突
/// </summary>
/// <returns></returns>
public async Task ValidateAsync()
{
var hostsPath = @"/etc/hosts";
if (OperatingSystem.IsWindows())
{
hostsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), $"drivers/{hostsPath}");
}
if (File.Exists(hostsPath) == false)
{
return;
}
var lines = await File.ReadAllLinesAsync(hostsPath);
foreach (var line in lines)
{
if (HostsRecord.TryParse(line, out var record) == false)
{
continue;
}
if (IPAddress.Loopback.Equals(record.Address) == true)
{
continue;
}
if (this.fastGithubConfig.IsMatch(record.Domain))
{
this.logger.LogError($"由于你的hosts文件设置了{record}{nameof(FastGithub)}无法加速此域名");
}
}
}
/// <summary>
/// hosts文件记录
/// </summary>
private class HostsRecord
{
/// <summary>
/// 获取域名
/// </summary>
public string Domain { get; }
/// <summary>
/// 获取地址
/// </summary>
public IPAddress Address { get; }
private HostsRecord(string domain, IPAddress address)
{
this.Domain = domain;
this.Address = address;
}
public override string ToString()
{
return $"[{this.Domain}->{this.Address}]";
}
public static bool TryParse(string record, [MaybeNullWhen(false)] out HostsRecord value)
{
value = null;
if (record.TrimStart().StartsWith("#"))
{
return false;
}
var items = record.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
if (items.Length < 2)
{
return false;
}
if (IPAddress.TryParse(items[0], out var address) == false)
{
return false;
}
value = new HostsRecord(items[1], address);
return true;
}
}
}
}