using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using System.Net; using System.Net.Http; using System.Threading.Tasks; using Yarp.ReverseProxy.Forwarder; namespace KestrelApp.Middleware.HttpProxy { /// /// 普通http代理(非隧道代理)中间件 /// public class HttpProxyMiddleware { private readonly RequestDelegate next; private readonly IHttpForwarder httpForwarder; private readonly ILogger logger; private readonly HttpMessageInvoker httpClient = new(CreateSocketsHttpHandler()); /// /// 普通http代理(非隧道代理)中间件 /// /// /// /// public HttpProxyMiddleware( RequestDelegate next, IHttpForwarder httpForwarder, ILogger logger) { this.next = next; this.httpForwarder = httpForwarder; this.logger = logger; } /// /// 处理http代理 /// /// /// public async Task InvokeAsync(HttpContext context) { var feature = context.Features.Get(); if (feature == null) { await next(context); } else if (feature.ProxyProtocol == ProxyProtocol.None) { await context.Response.WriteAsJsonAsync(new { Error = "请使用http代理协议来访问" }); } else { var scheme = context.Request.Scheme; var destinationPrefix = $"{scheme}://{feature.ProxyHost}"; this.logger.LogInformation($"http代理到{destinationPrefix}"); await httpForwarder.SendAsync(context, destinationPrefix, this.httpClient, ForwarderRequestConfig.Empty, HttpTransformer.Empty); } } private static SocketsHttpHandler CreateSocketsHttpHandler() { return new SocketsHttpHandler { Proxy = null, UseProxy = false, UseCookies = false, AllowAutoRedirect = false, AutomaticDecompression = DecompressionMethods.None, }; } } }