From c3fefdf4d3fa4eeefcc442505b977ac350ecc165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=9B=BD=E4=BC=9F?= <366193849@qq.com> Date: Fri, 16 Jul 2021 16:05:22 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=82=E5=B8=B8=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../KestrelServerOptionsExtensions.cs | 2 +- ...everseProxyApplicationBuilderExtensions.cs | 22 +++++++++--- .../ReverseProxyException.cs | 20 +++++++++++ FastGithub.ReverseProxy/TrustedResolver.cs | 36 ++++++++++++------- 4 files changed, 62 insertions(+), 18 deletions(-) create mode 100644 FastGithub.ReverseProxy/ReverseProxyException.cs diff --git a/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs b/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs index a2dc252..47d865d 100644 --- a/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs +++ b/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs @@ -77,7 +77,7 @@ namespace FastGithub store.Close(); } } - catch (Exception ) + catch (Exception) { logger.LogError($"安装根证书{caPublicCerPath}失败:请手动安装到“将所有的证书都放入下载存储”\\“受信任的根证书颁发机构”"); } diff --git a/FastGithub.ReverseProxy/ReverseProxyApplicationBuilderExtensions.cs b/FastGithub.ReverseProxy/ReverseProxyApplicationBuilderExtensions.cs index 9fcc6c8..bfac93d 100644 --- a/FastGithub.ReverseProxy/ReverseProxyApplicationBuilderExtensions.cs +++ b/FastGithub.ReverseProxy/ReverseProxyApplicationBuilderExtensions.cs @@ -30,13 +30,25 @@ namespace FastGithub if (options.CurrentValue.IsMatch(host) == false) { await context.Response.WriteAsJsonAsync(new { message = $"不支持以{host}访问" }); + return; } - else + + var port = context.Request.Host.Port ?? 443; + var destinationPrefix = $"https://{host}:{port}/"; + var httpClient = new HttpMessageInvoker(httpClientHanlder, disposeHandler: false); + var error = await httpForwarder.SendAsync(context, destinationPrefix, httpClient); + + if (error != ForwarderError.None) { - var port = context.Request.Host.Port ?? 443; - var destinationPrefix = $"https://{host}:{port}/"; - var httpClient = new HttpMessageInvoker(httpClientHanlder, disposeHandler: false); - await httpForwarder.SendAsync(context, destinationPrefix, httpClient); + var errorFeature = context.GetForwarderErrorFeature(); + if (errorFeature != null) + { + await context.Response.WriteAsJsonAsync(new + { + error = error.ToString(), + message = errorFeature.Exception?.Message + }); + } } }); diff --git a/FastGithub.ReverseProxy/ReverseProxyException.cs b/FastGithub.ReverseProxy/ReverseProxyException.cs new file mode 100644 index 0000000..16aa1b7 --- /dev/null +++ b/FastGithub.ReverseProxy/ReverseProxyException.cs @@ -0,0 +1,20 @@ +using System; + +namespace FastGithub.ReverseProxy +{ + /// + /// 反向代理异常 + /// + sealed class ReverseProxyException : Exception + { + /// + /// 反向代理异常 + /// + /// + /// + public ReverseProxyException(string message, Exception? inner) + : base(message, inner) + { + } + } +} diff --git a/FastGithub.ReverseProxy/TrustedResolver.cs b/FastGithub.ReverseProxy/TrustedResolver.cs index 2f8d721..402786f 100644 --- a/FastGithub.ReverseProxy/TrustedResolver.cs +++ b/FastGithub.ReverseProxy/TrustedResolver.cs @@ -5,7 +5,6 @@ using Microsoft.Extensions.Options; using System; using System.Linq; using System.Net; -using System.Net.Http; using System.Threading; using System.Threading.Tasks; @@ -44,23 +43,36 @@ namespace FastGithub.ReverseProxy { // 缓存以避免做不必要的并发查询 var key = $"domain:{domain}"; - var address = await this.memoryCache.GetOrCreateAsync(key, async e => + var address = await this.memoryCache.GetOrCreateAsync(key, e => { e.SetAbsoluteExpiration(this.cacheTimeSpan); - var dnsClient = new DnsClient(this.options.CurrentValue.TrustedDns.ToIPEndPoint()); - var addresses = await dnsClient.Lookup(domain, DNS.Protocol.RecordType.A, cancellationToken); - return addresses?.FirstOrDefault(); + return this.LookupAsync(domain, cancellationToken); }); - if (address == null) - { - var message = $"无法解析{domain}的ip"; - this.logger.LogWarning(message); - throw new HttpRequestException(message); - } - this.logger.LogInformation($"[{address}->{domain}]"); return address; } + + /// + /// 查找ip + /// + /// + /// + /// + private async Task LookupAsync(string domain, CancellationToken cancellationToken) + { + var endpoint = this.options.CurrentValue.TrustedDns.ToIPEndPoint(); + try + { + var dnsClient = new DnsClient(endpoint); + var addresses = await dnsClient.Lookup(domain, DNS.Protocol.RecordType.A, cancellationToken); + var address = addresses?.FirstOrDefault(); + return address ?? throw new Exception($"解析不到{domain}的ip"); + } + catch (Exception ex) + { + throw new ReverseProxyException($"dns({endpoint}):{ex.Message}", ex); + } + } } }