using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Http.Features; using System.Buffers; using System.IO.Pipelines; using System.Threading.Tasks; namespace FastGithub.HttpServer.TlsMiddlewares { /// /// https入侵中间件 /// sealed class TlsInvadeMiddleware { /// /// 执行中间件 /// /// /// public async Task InvokeAsync(ConnectionDelegate next, ConnectionContext context) { // 连接不是tls if (await IsTlsConnectionAsync(context) == false) { // 没有任何tls中间件执行过 if (context.Features.Get() == null) { // 设置假的ITlsConnectionFeature,迫使https中间件跳过自身的工作 context.Features.Set(FakeTlsConnectionFeature.Instance); } } await next(context); } /// /// 是否为tls协议 /// /// /// private static async Task IsTlsConnectionAsync(ConnectionContext context) { try { var result = await context.Transport.Input.ReadAtLeastAsync(2, context.ConnectionClosed); var state = IsTlsProtocol(result); context.Transport.Input.AdvanceTo(result.Buffer.Start); return state; } catch { return false; } static bool IsTlsProtocol(ReadResult result) { var reader = new SequenceReader(result.Buffer); return reader.TryRead(out var firstByte) && reader.TryRead(out var nextByte) && firstByte == 0x16 && nextByte == 0x3; } } } }