FastGithub/FastGithub.PacketIntercept/Dns/HostsConflictSolver.cs
xingyuan55 4d9d97f871 start
2022-11-16 08:01:03 +08:00

116 lines
3.6 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.IO;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace FastGithub.PacketIntercept.Dns
{
/// <summary>
/// host文件冲解决者
/// </summary>
[SupportedOSPlatform("windows")]
sealed class HostsConflictSolver : IDnsConflictSolver
{
private readonly FastGithubConfig fastGithubConfig;
private readonly ILogger<HostsConflictSolver> logger;
/// <summary>
/// host文件冲解决者
/// </summary>
/// <param name="fastGithubConfig"></param>
/// <param name="logger"></param>
public HostsConflictSolver(
FastGithubConfig fastGithubConfig,
ILogger<HostsConflictSolver> logger)
{
this.fastGithubConfig = fastGithubConfig;
this.logger = logger;
}
/// <summary>
/// 解决冲突
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task SolveAsync(CancellationToken cancellationToken)
{
var hostsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "drivers/etc/hosts");
if (File.Exists(hostsPath) == false)
{
return;
}
Encoding hostsEncoding;
var hasConflicting = false;
var hostsBuilder = new StringBuilder();
using (var fileStream = new FileStream(hostsPath, FileMode.Open, FileAccess.Read))
{
using var streamReader = new StreamReader(fileStream);
while (streamReader.EndOfStream == false)
{
var line = await streamReader.ReadLineAsync(cancellationToken);
if (this.IsConflictingLine(line))
{
hasConflicting = true;
hostsBuilder.AppendLine($"# {line}");
}
else
{
hostsBuilder.AppendLine(line);
}
}
hostsEncoding = streamReader.CurrentEncoding;
}
if (hasConflicting == true)
{
try
{
await File.WriteAllTextAsync(hostsPath, hostsBuilder.ToString(), hostsEncoding, cancellationToken);
}
catch (Exception ex)
{
this.logger.LogWarning($"无法解决hosts文件冲突{ex.Message}");
}
}
}
/// <summary>
/// 恢复冲突
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public Task RestoreAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
/// <summary>
/// 是否为冲突的行
/// </summary>
/// <param name="line"></param>
/// <returns></returns>
private bool IsConflictingLine(string? line)
{
if (line == null || line.TrimStart().StartsWith("#"))
{
return false;
}
var items = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
if (items.Length < 2)
{
return false;
}
var domain = items[1];
return this.fastGithubConfig.IsMatch(domain);
}
}
}