HttpClient支持传入SNI

This commit is contained in:
xljiulang 2021-07-18 23:32:22 +08:00
parent d50c35466b
commit a7304ea5e0
4 changed files with 22 additions and 29 deletions

View File

@ -10,18 +10,18 @@ namespace FastGithub.ReverseProxy
/// </summary> /// </summary>
class HttpClient : HttpMessageInvoker class HttpClient : HttpMessageInvoker
{ {
private readonly bool tlsSni; private readonly string tlsSniValue;
/// <summary> /// <summary>
/// YARP的HttpClient /// YARP的HttpClient
/// </summary> /// </summary>
/// <param name="handler"></param> /// <param name="handler"></param>
/// <param name="tlsSniValue"></param>
/// <param name="disposeHandler"></param> /// <param name="disposeHandler"></param>
/// <param name="tlsSni"></param> public HttpClient(HttpMessageHandler handler, string tlsSniValue, bool disposeHandler = false) :
public HttpClient(HttpMessageHandler handler, bool disposeHandler, bool tlsSni) :
base(handler, disposeHandler) base(handler, disposeHandler)
{ {
this.tlsSni = tlsSni; this.tlsSniValue = tlsSniValue;
} }
/// <summary> /// <summary>
@ -33,7 +33,7 @@ namespace FastGithub.ReverseProxy
public override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) public override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{ {
var isHttps = request.RequestUri?.Scheme == Uri.UriSchemeHttps; var isHttps = request.RequestUri?.Scheme == Uri.UriSchemeHttps;
request.SetSniContext(new SniContext(isHttps, this.tlsSni)); request.SetSniContext(new SniContext(isHttps, this.tlsSniValue));
return base.SendAsync(request, cancellationToken); return base.SendAsync(request, cancellationToken);
} }
} }

View File

@ -26,14 +26,14 @@ namespace FastGithub.ReverseProxy
{ {
this.domainResolver = domainResolver; this.domainResolver = domainResolver;
this.logger = logger; this.logger = logger;
this.InnerHandler = CreateNoneSniHttpHandler(); this.InnerHandler = CreateSocketsHttpHandler();
} }
/// <summary> /// <summary>
/// 创建无Sni发送的httpHandler /// 创建转发代理的httpHandler
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private static HttpMessageHandler CreateNoneSniHttpHandler() private static SocketsHttpHandler CreateSocketsHttpHandler()
{ {
return new SocketsHttpHandler return new SocketsHttpHandler
{ {
@ -83,11 +83,9 @@ namespace FastGithub.ReverseProxy
request.RequestUri = builder.Uri; request.RequestUri = builder.Uri;
request.Headers.Host = uri.Host; request.Headers.Host = uri.Host;
// 计算Sni
var context = request.GetSniContext(); var context = request.GetSniContext();
if (context.IsHttps && context.TlsSni) if (context.IsHttps && context.TlsSniValue.Length > 0)
{ {
context.TlsSniValue = uri.Host;
this.logger.LogInformation($"[{address}--Sni->{uri.Host}]"); this.logger.LogInformation($"[{address}--Sni->{uri.Host}]");
} }
else else

View File

@ -55,9 +55,11 @@ namespace FastGithub.ReverseProxy
{ {
var destinationPrefix = GetDestinationPrefix(host, domainConfig.Destination); var destinationPrefix = GetDestinationPrefix(host, domainConfig.Destination);
var requestConfig = new ForwarderRequestConfig { Timeout = domainConfig.Timeout }; var requestConfig = new ForwarderRequestConfig { Timeout = domainConfig.Timeout };
var httpClient = new HttpClient(this.httpClientHanlder, false, domainConfig.TlsSni);
var error = await httpForwarder.SendAsync(context, destinationPrefix, httpClient, requestConfig); var tlsSniValue = domainConfig.TlsSni ? destinationPrefix.Host : string.Empty;
using var httpClient = new HttpClient(this.httpClientHanlder, tlsSniValue);
var error = await httpForwarder.SendAsync(context, destinationPrefix.ToString(), httpClient, requestConfig);
await ResponseErrorAsync(context, error); await ResponseErrorAsync(context, error);
} }
} }
@ -68,18 +70,16 @@ namespace FastGithub.ReverseProxy
/// <param name="host"></param> /// <param name="host"></param>
/// <param name="destination"></param> /// <param name="destination"></param>
/// <returns></returns> /// <returns></returns>
private string GetDestinationPrefix(string host, Uri? destination) private Uri GetDestinationPrefix(string host, Uri? destination)
{ {
var defaultValue = $"https://{host}/"; var defaultValue = new Uri($"https://{host}/");
if (destination == null) if (destination == null)
{ {
return defaultValue; return defaultValue;
} }
var baseUri = new Uri(defaultValue); var result = new Uri(defaultValue, destination);
var result = new Uri(baseUri, destination).ToString();
this.logger.LogInformation($"[{defaultValue}->{result}]"); this.logger.LogInformation($"[{defaultValue}->{result}]");
return result; return result;
} }

View File

@ -6,29 +6,24 @@
sealed class SniContext sealed class SniContext
{ {
/// <summary> /// <summary>
/// 获取请求是否为https /// 获取是否为https请求
/// </summary> /// </summary>
public bool IsHttps { get; } public bool IsHttps { get; }
/// <summary> /// <summary>
/// 获取是否发送Sni /// 获取Sni
/// </summary> /// </summary>
public bool TlsSni { get; } public string TlsSniValue { get; }
/// <summary>
/// Sni值
/// </summary>
public string TlsSniValue { get; set; } = string.Empty;
/// <summary> /// <summary>
/// Sni上下文 /// Sni上下文
/// </summary> /// </summary>
/// <param name="isHttps"></param> /// <param name="isHttps"></param>
/// <param name="tlsSni"></param> /// <param name="tlsSniValue"></param>
public SniContext(bool isHttps, bool tlsSni) public SniContext(bool isHttps, string tlsSniValue)
{ {
this.IsHttps = isHttps; this.IsHttps = isHttps;
this.TlsSni = tlsSni; this.TlsSniValue = tlsSniValue;
} }
} }
} }