网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using DnsClient.Internal;
using Dpz.Core.Infrastructure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Refit;

namespace Dpz.Core.Service.Network;

public static class NetworkServicesExtension
{
    public static IServiceCollection AddNetworkServices(this IServiceCollection services)
    {
        services.AddTransient<AuthUpyunHeaderHandler>();

        var configuration = services.BuildServiceProvider().GetService<IConfiguration>();


        var configHost = configuration?.GetSection("config")["Host"];
        if (string.IsNullOrEmpty(configHost))
            throw new BusinessException("configuration config/Host node not found");

        services.AddRefitClient<IReadConfiguration>()
            .ConfigureHttpClient(x => x.BaseAddress = new Uri(configHost));

        services.AddRefitClient<IAppSettingsConfiguration>()
            .ConfigureHttpClient(c => c.BaseAddress = new Uri(configHost))
            .AddHttpMessageHandler<AuthUpyunHeaderHandler>();

        return services;
    }

    /// <summary>
    /// 从网络资源添加配置
    /// </summary>
    /// <param name="configurationBuilder"></param>
    /// <param name="readConfiguration"></param>
    /// <param name="loggerFactory"></param>
    /// <param name="timeSpan">签名过期时间,默认15秒</param>
    /// <returns></returns>
    /// <exception cref="BusinessException"></exception>
    public static async Task<IConfigurationBuilder> AddNetworkConfigurationAsync(
        this IConfigurationBuilder configurationBuilder,
        IReadConfiguration readConfiguration,
        ILoggerFactory? loggerFactory = null,
        TimeSpan? timeSpan = null)
    {
        var config = configurationBuilder.Build();
        var key = config?.GetSection("config")["Key"];
        if (string.IsNullOrEmpty(key))
            throw new BusinessException("configuration config/Key node not found");

        return await configurationBuilder
            .AddNetworkJsonStreamAsync(
                readConfiguration,
                null,
                null,
                loggerFactory,
                timeSpan);
    }

    /// <summary>
    /// 根据项目、环境从网络资源添加配置
    /// </summary>
    /// <param name="configurationBuilder"></param>
    /// <param name="readConfiguration"></param>
    /// <param name="project">项目</param>
    /// <param name="environmentFile">具体环境文件名</param>
    /// <param name="loggerFactory"></param>
    /// <param name="timeSpan">签名过期时间,默认15秒</param>
    /// <returns></returns>
    /// <exception cref="BusinessException"></exception>
    public static async Task<IConfigurationBuilder> AddNetworkConfigurationAsync(
        this IConfigurationBuilder configurationBuilder,
        IReadConfiguration readConfiguration,
        string project,
        string environmentFile,
        ILoggerFactory? loggerFactory = null,
        TimeSpan? timeSpan = null)
    {
        if (string.IsNullOrEmpty(project))
            throw new ArgumentNullException(nameof(project));
        if (string.IsNullOrEmpty(environmentFile))
            throw new ArgumentNullException(nameof(environmentFile));


        var config = configurationBuilder.Build();
        var key = config?.GetSection("config")["Key"];
        if (string.IsNullOrEmpty(key))
            throw new BusinessException("configuration config/Key node not found");

        return await configurationBuilder
            .AddNetworkJsonStreamAsync(
                readConfiguration,
                project,
                environmentFile,
                loggerFactory, timeSpan);
    }

    private static string CalculateSign(string key, string uri, TimeSpan? timeSpan = null)
    {
        timeSpan ??= TimeSpan.FromSeconds(15);
        var timeStamp = DateTime.Now.Add(timeSpan.Value).ToTimeStamp();
        var md5 = $"{key}&{timeStamp}&{uri}".GenerateHashMd5();
        var sign = md5.Substring(12, 8) + timeStamp;
        return sign;
    }

    private static async Task<IConfigurationBuilder> AddNetworkJsonStreamAsync(
        this IConfigurationBuilder configurationBuilder,
        IReadConfiguration readConfiguration,
        string? project,
        string? environmentFile,
        ILoggerFactory? loggerFactory = null,
        TimeSpan? timeSpan = null)
    {
        var config = configurationBuilder.Build();
        var key = config?.GetSection("config")["Key"];
        if (string.IsNullOrEmpty(key))
            throw new BusinessException("configuration config/Key node not found");

        try
        {
            if (string.IsNullOrEmpty(project) || string.IsNullOrEmpty(environmentFile))
            {
                var uri = "/config/appsettings.json";
                var sign = CalculateSign(key, uri, timeSpan);
                var result = await readConfiguration.ReadConfigurationAsync(sign);
                configurationBuilder.AddJsonStream(result.Content);
            }
            else
            {
                var uri = $"/config/{project}/{environmentFile}";
                var sign = CalculateSign(key, uri, timeSpan);
                var result = await readConfiguration.ReadConfigurationAsync(project, environmentFile, sign);
                configurationBuilder.AddJsonStream(result.Content);
            }
        }
        catch (Exception e)
        {
            if (loggerFactory == null)
            {
                throw new BusinessException("add network configuration fail", e);
            }

            var logger = loggerFactory.CreateLogger(nameof(Dpz.Core.Service.Network.NetworkServicesExtension));
            logger.LogError(e, "add network configuration fail");
        }

        return configurationBuilder;
    }
    
    internal static async Task SignatureAsync(this HttpRequestMessage request, UpyunOperator upyunOperator,
        string? contentMd5 = null)
    {
        if (request == null)
            throw new ArgumentNullException(nameof(request));
        if (upyunOperator == null)
            throw new ArgumentNullException(nameof(upyunOperator));


        var utcNow = DateTime.UtcNow;

        var pwd = upyunOperator.Password.GenerateHashMd5();
        var method = request.Method.ToString().ToUpper();
        var uri = request.RequestUri?.OriginalString ?? "";


        var message = $"{method}&{uri}&{utcNow:R}";
        if (!string.IsNullOrEmpty(contentMd5))
        {
            message += "&" + contentMd5;
        }

        var keyBytes = Encoding.UTF8.GetBytes(pwd);
        var sha1 = new HMACSHA1(keyBytes);
        var byteArray = Encoding.UTF8.GetBytes(message);
        var stream = new MemoryStream(byteArray);
        var sha1Result = await sha1.ComputeHashAsync(stream);
        var signBase64 = Convert.ToBase64String(sha1Result);

        request.Headers.Authorization =
            AuthenticationHeaderValue.Parse($"UPYUN {upyunOperator.Operator}:{signBase64}");
        request.Headers.Date = utcNow;
    }
}
loading