From 401276cb6a5b491ff17277f5a832b2e7b34487a5 Mon Sep 17 00:00:00 2001 From: "Gui.H" Date: Tue, 3 May 2022 09:34:54 +0800 Subject: [PATCH] 1 --- FastTunnel.Client/Program.cs | 2 +- FastTunnel.Core/Client/FastTunnelClient.cs | 3 +- .../Extensions/ListenOptionsSwapExtensions.cs | 8 +- .../Extensions/ServicesExtensions.cs | 5 +- .../Extensions/SocketExtensions.cs | 1 + .../FastTunnelForwarderHttpClientFactory.cs | 5 +- .../FastTunnelProxyConfigProvider.cs | 17 --- .../Forwarder/InMemoryConfigProvider.cs | 2 +- .../Kestrel/ClientConnectionMiddleware.cs | 110 ++++++++++++++++++ .../SwapConnectionMiddleware.cs | 37 +++--- .../Forwarder/MiddleWare/DuplexPipeStream.cs | 12 +- .../MiddleWare/FastTunnelClientHandler.cs | 6 +- .../MiddleWare/FastTunnelSwapHandler.cs | 3 +- .../Handlers/Client/SwapHandler.cs | 15 ++- .../Handlers/Server/ForwardDispatcher.cs | 3 +- .../Handlers/Server/IClientMessageHandler.cs | 2 +- .../Handlers/Server/LoginHandler.cs | 4 +- FastTunnel.Core/Listener/PortProxyListener.cs | 2 +- .../Models/Massage/LogInMassage.cs | 2 +- .../Models/Massage/TunnelMassage.cs | 2 +- FastTunnel.Server/Program.cs | 3 +- FastTunnel.Server/Startup.cs | 1 - 22 files changed, 177 insertions(+), 68 deletions(-) delete mode 100644 FastTunnel.Core/Forwarder/FastTunnelProxyConfigProvider.cs create mode 100644 FastTunnel.Core/Forwarder/Kestrel/ClientConnectionMiddleware.cs rename FastTunnel.Core/Forwarder/{MiddleWare => Kestrel}/SwapConnectionMiddleware.cs (86%) diff --git a/FastTunnel.Client/Program.cs b/FastTunnel.Client/Program.cs index 01ac75b..0a2de75 100644 --- a/FastTunnel.Client/Program.cs +++ b/FastTunnel.Client/Program.cs @@ -8,9 +8,9 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System; using Microsoft.AspNetCore.Builder; -using FastTunnel.Core; using Microsoft.Extensions.Configuration; using Serilog; +using FastTunnel.Core.Extensions; namespace FastTunnel.Client; diff --git a/FastTunnel.Core/Client/FastTunnelClient.cs b/FastTunnel.Core/Client/FastTunnelClient.cs index 24546c3..b42947b 100644 --- a/FastTunnel.Core/Client/FastTunnelClient.cs +++ b/FastTunnel.Core/Client/FastTunnelClient.cs @@ -1,4 +1,4 @@ -// Licensed under the Apache License, Version 2.0 (the "License"). +// Licensed under the Apache License, Version 2.0 (the "License"). // You may not use this file except in compliance with the License. // You may obtain a copy of the License at // https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE @@ -16,6 +16,7 @@ using FastTunnel.Core.Handlers.Client; using Microsoft.Extensions.Options; using System.Net.WebSockets; using FastTunnel.Core.Utilitys; +using FastTunnel.Core.Models.Massage; namespace FastTunnel.Core.Client { diff --git a/FastTunnel.Core/Extensions/ListenOptionsSwapExtensions.cs b/FastTunnel.Core/Extensions/ListenOptionsSwapExtensions.cs index 36016fc..47909ac 100644 --- a/FastTunnel.Core/Extensions/ListenOptionsSwapExtensions.cs +++ b/FastTunnel.Core/Extensions/ListenOptionsSwapExtensions.cs @@ -10,7 +10,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using FastTunnel.Core.Client; -using FastTunnel.Core.Forwarder.MiddleWare; +using FastTunnel.Core.Forwarder.Kestrel; using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -19,13 +19,17 @@ namespace FastTunnel.Core.Extensions; public static class ListenOptionsSwapExtensions { - public static ListenOptions UseFastTunnelSwap(this ListenOptions listenOptions) + public static ListenOptions UseConnectionFastTunnel(this ListenOptions listenOptions) { var loggerFactory = listenOptions.KestrelServerOptions.ApplicationServices.GetRequiredService(); var logger = loggerFactory.CreateLogger(); + var loggerClient = loggerFactory.CreateLogger(); var fastTunnelServer = listenOptions.KestrelServerOptions.ApplicationServices.GetRequiredService(); listenOptions.Use(next => new SwapConnectionMiddleware(next, logger, fastTunnelServer).OnConnectionAsync); + + // 登录频率低,放在后面 + //listenOptions.Use(next => new ClientConnectionMiddleware(next, loggerClient, fastTunnelServer).OnConnectionAsync); return listenOptions; } } diff --git a/FastTunnel.Core/Extensions/ServicesExtensions.cs b/FastTunnel.Core/Extensions/ServicesExtensions.cs index d5e3070..6eac2d4 100644 --- a/FastTunnel.Core/Extensions/ServicesExtensions.cs +++ b/FastTunnel.Core/Extensions/ServicesExtensions.cs @@ -9,12 +9,10 @@ using FastTunnel.Core.Config; using FastTunnel.Core.Forwarder.MiddleWare; using FastTunnel.Core.Forwarder; using FastTunnel.Core.Handlers.Client; -using FastTunnel.Core.MiddleWares; using FastTunnel.Core.Services; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Yarp.ReverseProxy.Forwarder; -using Yarp.Sample; using Microsoft.AspNetCore.Builder; using FastTunnel.Core.Filters; using Microsoft.AspNetCore.Mvc.Filters; @@ -26,7 +24,7 @@ using System.Threading.Tasks; using System.Threading; using Microsoft.AspNetCore.Http; -namespace FastTunnel.Core +namespace FastTunnel.Core.Extensions { public static class ServicesExtensions { @@ -78,7 +76,6 @@ namespace FastTunnel.Core var swapHandler = app.ApplicationServices.GetRequiredService(); var clientHandler = app.ApplicationServices.GetRequiredService(); app.Use(clientHandler.Handle); - app.Use(swapHandler.Handle); } public static void MapFastTunnelServer(this IEndpointRouteBuilder endpoints) diff --git a/FastTunnel.Core/Extensions/SocketExtensions.cs b/FastTunnel.Core/Extensions/SocketExtensions.cs index b5710fe..565b32f 100644 --- a/FastTunnel.Core/Extensions/SocketExtensions.cs +++ b/FastTunnel.Core/Extensions/SocketExtensions.cs @@ -5,6 +5,7 @@ // Copyright (c) 2019 Gui.H using FastTunnel.Core.Models; +using FastTunnel.Core.Models.Massage; using System; using System.Collections.Generic; using System.Net.Sockets; diff --git a/FastTunnel.Core/Forwarder/FastTunnelForwarderHttpClientFactory.cs b/FastTunnel.Core/Forwarder/FastTunnelForwarderHttpClientFactory.cs index f1e2d17..6130dbd 100644 --- a/FastTunnel.Core/Forwarder/FastTunnelForwarderHttpClientFactory.cs +++ b/FastTunnel.Core/Forwarder/FastTunnelForwarderHttpClientFactory.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2022 Gui.H. https://github.com/FastTunnel/FastTunnel +// Copyright (c) 2019-2022 Gui.H. https://github.com/FastTunnel/FastTunnel // The FastTunnel licenses this file to you under the Apache License Version 2.0. // For more details,You may obtain License file at: https://github.com/FastTunnel/FastTunnel/blob/v2/LICENSE @@ -48,8 +48,9 @@ namespace FastTunnel.Core.Forwarder var res = await proxyAsync(host, context, cancellationToken); return res; } - catch (Exception) + catch (Exception ex) { + logger.LogError(ex, "ConnectCallback Error"); throw; } } diff --git a/FastTunnel.Core/Forwarder/FastTunnelProxyConfigProvider.cs b/FastTunnel.Core/Forwarder/FastTunnelProxyConfigProvider.cs deleted file mode 100644 index cf2ccd0..0000000 --- a/FastTunnel.Core/Forwarder/FastTunnelProxyConfigProvider.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Yarp.ReverseProxy.Configuration; - -namespace FastTunnel.Core.Forwarder -{ - public class FastTunnelProxyConfigProvider : IProxyConfigProvider - { - public IProxyConfig GetConfig() - { - return new FastTunnelProxyConfig(); - } - } -} diff --git a/FastTunnel.Core/Forwarder/InMemoryConfigProvider.cs b/FastTunnel.Core/Forwarder/InMemoryConfigProvider.cs index 903f3a5..8eea920 100644 --- a/FastTunnel.Core/Forwarder/InMemoryConfigProvider.cs +++ b/FastTunnel.Core/Forwarder/InMemoryConfigProvider.cs @@ -9,7 +9,7 @@ using Microsoft.Extensions.Primitives; using Yarp.ReverseProxy.Configuration; using System.Linq; -namespace Yarp.Sample +namespace FastTunnel.Core.Forwarder { /// /// Extends the IReverseProxyBuilder to support the InMemoryConfigProvider diff --git a/FastTunnel.Core/Forwarder/Kestrel/ClientConnectionMiddleware.cs b/FastTunnel.Core/Forwarder/Kestrel/ClientConnectionMiddleware.cs new file mode 100644 index 0000000..3c0f988 --- /dev/null +++ b/FastTunnel.Core/Forwarder/Kestrel/ClientConnectionMiddleware.cs @@ -0,0 +1,110 @@ +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE +// Copyright (c) 2019 Gui.H + +using System; +using System.Buffers; +using System.Collections.Generic; +using System.IO.Pipelines; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FastTunnel.Core.Client; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Connections.Features; +using Microsoft.Extensions.Logging; + +namespace FastTunnel.Core.Forwarder.Kestrel; +internal class ClientConnectionMiddleware +{ + readonly ConnectionDelegate next; + readonly ILogger logger; + FastTunnelServer fastTunnelServer; + + public ClientConnectionMiddleware(ConnectionDelegate next, ILogger logger, FastTunnelServer fastTunnelServer) + { + this.next = next; + this.logger = logger; + this.fastTunnelServer = fastTunnelServer; + } + + internal async Task OnConnectionAsync(ConnectionContext context) + { + var oldTransport = context.Transport; + + try + { + if (!await ReadPipeAsync(context)) + { + await next(context); + } + + await next(context); + } + finally + { + context.Transport = oldTransport; + } + } + + async Task ReadPipeAsync(ConnectionContext context) + { + var reader = context.Transport.Input; + + var isProxy = false; + while (true) + { + var result = await reader.ReadAsync(); + var buffer = result.Buffer; + SequencePosition? position = null; + + do + { + position = buffer.PositionOf((byte)'\n'); + + if (position != null) + { + isProxy = ProcessProxyLine(buffer.Slice(0, position.Value)); + if (isProxy) + { + await Login(buffer, position.Value, context); + return true; + } + else + { + context.Transport.Input.AdvanceTo(buffer.Start, buffer.Start); + return false; + } + } + } + while (position != null); + + if (result.IsCompleted) + { + break; + } + } + + return false; + } + + private async Task Login(ReadOnlySequence buffer, SequencePosition position, ConnectionContext context) + { + + + } + + /// + /// + /// + /// + private bool ProcessProxyLine(ReadOnlySequence readOnlySequence) + { + var str = Encoding.UTF8.GetString(readOnlySequence); + + return str.StartsWith("LOGIN"); + } +} + diff --git a/FastTunnel.Core/Forwarder/MiddleWare/SwapConnectionMiddleware.cs b/FastTunnel.Core/Forwarder/Kestrel/SwapConnectionMiddleware.cs similarity index 86% rename from FastTunnel.Core/Forwarder/MiddleWare/SwapConnectionMiddleware.cs rename to FastTunnel.Core/Forwarder/Kestrel/SwapConnectionMiddleware.cs index d4d7a05..65a8bec 100644 --- a/FastTunnel.Core/Forwarder/MiddleWare/SwapConnectionMiddleware.cs +++ b/FastTunnel.Core/Forwarder/Kestrel/SwapConnectionMiddleware.cs @@ -12,11 +12,12 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using FastTunnel.Core.Client; +using FastTunnel.Core.Forwarder.MiddleWare; using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Connections.Features; using Microsoft.Extensions.Logging; -namespace FastTunnel.Core.Forwarder.MiddleWare; +namespace FastTunnel.Core.Forwarder.Kestrel; internal class SwapConnectionMiddleware { @@ -35,30 +36,21 @@ internal class SwapConnectionMiddleware { var oldTransport = context.Transport; - try + if (!await ReadPipeAsync(context)) { - if (!await ReadPipeAsync(context)) - { - await next(context); - } - await next(context); } - finally - { - context.Transport = oldTransport; - } } async Task ReadPipeAsync(ConnectionContext context) { var reader = context.Transport.Input; - bool isProxy = false; + var isProxy = false; while (true) { - ReadResult result = await reader.ReadAsync(); - ReadOnlySequence buffer = result.Buffer; + var result = await reader.ReadAsync(); + var buffer = result.Buffer; SequencePosition? position = null; do @@ -121,9 +113,20 @@ internal class SwapConnectionMiddleware (task as TaskCompletionSource).SetResult(null); }, closedAwaiter); - await closedAwaiter.Task; - - logger.LogDebug($"[PROXY]:Closed {requestId}"); + try + { + await closedAwaiter.Task; + } + catch (Exception ex) + { + logger.LogError(ex, ""); + } + finally + { + context.Transport.Input.Complete(); + context.Transport.Output.Complete(); + logger.LogInformation($"=====================Swap End:{requestId}================== "); + } } /// diff --git a/FastTunnel.Core/Forwarder/MiddleWare/DuplexPipeStream.cs b/FastTunnel.Core/Forwarder/MiddleWare/DuplexPipeStream.cs index 8e515ca..bd9aa45 100644 --- a/FastTunnel.Core/Forwarder/MiddleWare/DuplexPipeStream.cs +++ b/FastTunnel.Core/Forwarder/MiddleWare/DuplexPipeStream.cs @@ -122,8 +122,12 @@ internal class DuplexPipeStream : Stream { while (true) { - var result = await _input.ReadAsync(cancellationToken); - var readableBuffer = result.Buffer; + ReadResult result; + ReadOnlySequence readableBuffer; + + result = await _input.ReadAsync(cancellationToken); + readableBuffer = result.Buffer; + try { if (_throwOnCancelled && result.IsCanceled && _cancelCalled) @@ -138,10 +142,6 @@ internal class DuplexPipeStream : Stream // buffer.Count is int var count = (int)Math.Min(readableBuffer.Length, destination.Length); readableBuffer = readableBuffer.Slice(0, count); - - var str = Encoding.UTF8.GetString(readableBuffer); - - Console.WriteLine($"[ReadAsyncInternal]:{str}"); readableBuffer.CopyTo(destination.Span); return count; } diff --git a/FastTunnel.Core/Forwarder/MiddleWare/FastTunnelClientHandler.cs b/FastTunnel.Core/Forwarder/MiddleWare/FastTunnelClientHandler.cs index 1993585..3046b34 100644 --- a/FastTunnel.Core/Forwarder/MiddleWare/FastTunnelClientHandler.cs +++ b/FastTunnel.Core/Forwarder/MiddleWare/FastTunnelClientHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2022 Gui.H. https://github.com/FastTunnel/FastTunnel +// Copyright (c) 2019-2022 Gui.H. https://github.com/FastTunnel/FastTunnel // The FastTunnel licenses this file to you under the Apache License Version 2.0. // For more details,You may obtain License file at: https://github.com/FastTunnel/FastTunnel/blob/v2/LICENSE @@ -13,7 +13,7 @@ using System.Net.WebSockets; using System.Threading; using System.Threading.Tasks; -namespace FastTunnel.Core.MiddleWares +namespace FastTunnel.Core.Forwarder.MiddleWare { public class FastTunnelClientHandler { @@ -91,7 +91,7 @@ namespace FastTunnel.Core.MiddleWares private bool checkToken(HttpContext context) { - bool checkToken = false; + var checkToken = false; if (fastTunnelServer.ServerOption.CurrentValue.Tokens != null && fastTunnelServer.ServerOption.CurrentValue.Tokens.Count != 0) { checkToken = true; diff --git a/FastTunnel.Core/Forwarder/MiddleWare/FastTunnelSwapHandler.cs b/FastTunnel.Core/Forwarder/MiddleWare/FastTunnelSwapHandler.cs index 040e1a4..cef8c90 100644 --- a/FastTunnel.Core/Forwarder/MiddleWare/FastTunnelSwapHandler.cs +++ b/FastTunnel.Core/Forwarder/MiddleWare/FastTunnelSwapHandler.cs @@ -1,6 +1,5 @@ -using FastTunnel.Core.Client; +using FastTunnel.Core.Client; using FastTunnel.Core.Extensions; -using FastTunnel.Core.MiddleWares; using Microsoft.AspNetCore.Connections.Features; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; diff --git a/FastTunnel.Core/Handlers/Client/SwapHandler.cs b/FastTunnel.Core/Handlers/Client/SwapHandler.cs index d082ebe..82e4459 100644 --- a/FastTunnel.Core/Handlers/Client/SwapHandler.cs +++ b/FastTunnel.Core/Handlers/Client/SwapHandler.cs @@ -38,7 +38,18 @@ namespace FastTunnel.Core.Handlers.Client var taskX = serverStream.CopyToAsync(localStream, cancellationToken); var taskY = localStream.CopyToAsync(serverStream, cancellationToken); - await Task.WhenAny(taskX, taskY); + try + { + await Task.WhenAll(taskX, taskY); + } + catch (Exception ex) + { + + } + finally + { + _logger.LogError($"=====================Swap End:{requestId}================== "); + } } } catch (Exception ex) @@ -66,6 +77,8 @@ namespace FastTunnel.Core.Handlers.Client } var reverse = $"PROXY /{requestId} HTTP/1.1\r\n"; + //var reverse = $"PROXY /{requestId} HTTP/1.1\r\nHost: {cleint.Server.ServerAddr}:{cleint.Server.ServerPort}\r\n\r\n"; + var requestMsg = Encoding.UTF8.GetBytes(reverse); await serverStream.WriteAsync(requestMsg, cancellationToken); return serverStream; diff --git a/FastTunnel.Core/Handlers/Server/ForwardDispatcher.cs b/FastTunnel.Core/Handlers/Server/ForwardDispatcher.cs index 59ef934..4228827 100644 --- a/FastTunnel.Core/Handlers/Server/ForwardDispatcher.cs +++ b/FastTunnel.Core/Handlers/Server/ForwardDispatcher.cs @@ -5,7 +5,6 @@ // Copyright (c) 2019 Gui.H using FastTunnel.Core.Client; -using FastTunnel.Core.Dispatchers; using FastTunnel.Core.Exceptions; using FastTunnel.Core.Extensions; using FastTunnel.Core.Models; @@ -21,7 +20,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; -namespace FastTunnel.Core.Dispatchers +namespace FastTunnel.Core.Handlers.Server { public class ForwardDispatcher { diff --git a/FastTunnel.Core/Handlers/Server/IClientMessageHandler.cs b/FastTunnel.Core/Handlers/Server/IClientMessageHandler.cs index 2c65214..221b181 100644 --- a/FastTunnel.Core/Handlers/Server/IClientMessageHandler.cs +++ b/FastTunnel.Core/Handlers/Server/IClientMessageHandler.cs @@ -13,7 +13,7 @@ using System.Net.WebSockets; using System.Text; using System.Threading.Tasks; -namespace FastTunnel.Core.Handlers +namespace FastTunnel.Core.Handlers.Server { public interface IClientMessageHandler { diff --git a/FastTunnel.Core/Handlers/Server/LoginHandler.cs b/FastTunnel.Core/Handlers/Server/LoginHandler.cs index 41a2219..6f01492 100644 --- a/FastTunnel.Core/Handlers/Server/LoginHandler.cs +++ b/FastTunnel.Core/Handlers/Server/LoginHandler.cs @@ -5,10 +5,11 @@ // Copyright (c) 2019 Gui.H using FastTunnel.Core.Client; -using FastTunnel.Core.Dispatchers; using FastTunnel.Core.Extensions; +using FastTunnel.Core.Forwarder; using FastTunnel.Core.Listener; using FastTunnel.Core.Models; +using FastTunnel.Core.Models.Massage; using Microsoft.Extensions.Logging; using System; using System.Linq; @@ -16,7 +17,6 @@ using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Yarp.ReverseProxy.Configuration; -using Yarp.Sample; namespace FastTunnel.Core.Handlers.Server { diff --git a/FastTunnel.Core/Listener/PortProxyListener.cs b/FastTunnel.Core/Listener/PortProxyListener.cs index 17b0e0b..1cf33c5 100644 --- a/FastTunnel.Core/Listener/PortProxyListener.cs +++ b/FastTunnel.Core/Listener/PortProxyListener.cs @@ -4,7 +4,7 @@ // https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE // Copyright (c) 2019 Gui.H -using FastTunnel.Core.Dispatchers; +using FastTunnel.Core.Handlers.Server; using Microsoft.Extensions.Logging; using System; using System.Net; diff --git a/FastTunnel.Core/Models/Massage/LogInMassage.cs b/FastTunnel.Core/Models/Massage/LogInMassage.cs index a685c4a..fcb236d 100644 --- a/FastTunnel.Core/Models/Massage/LogInMassage.cs +++ b/FastTunnel.Core/Models/Massage/LogInMassage.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; -namespace FastTunnel.Core.Models +namespace FastTunnel.Core.Models.Massage { public class LogInMassage : TunnelMassage { diff --git a/FastTunnel.Core/Models/Massage/TunnelMassage.cs b/FastTunnel.Core/Models/Massage/TunnelMassage.cs index 86ac135..84dd4f0 100644 --- a/FastTunnel.Core/Models/Massage/TunnelMassage.cs +++ b/FastTunnel.Core/Models/Massage/TunnelMassage.cs @@ -4,7 +4,7 @@ // https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE // Copyright (c) 2019 Gui.H -namespace FastTunnel.Core.Models +namespace FastTunnel.Core.Models.Massage { public class TunnelMassage { diff --git a/FastTunnel.Server/Program.cs b/FastTunnel.Server/Program.cs index e18dd90..def3984 100644 --- a/FastTunnel.Server/Program.cs +++ b/FastTunnel.Server/Program.cs @@ -65,8 +65,7 @@ public class Program var basePort = context.Configuration.GetValue("BASE_PORT") ?? 1270; options.ListenAnyIP(basePort, listenOptions => { - //listenOptions.UseConnectionLogging(); - listenOptions.UseFastTunnelSwap(); + listenOptions.UseConnectionFastTunnel(); }); }); diff --git a/FastTunnel.Server/Startup.cs b/FastTunnel.Server/Startup.cs index 61bce7c..a368ebf 100644 --- a/FastTunnel.Server/Startup.cs +++ b/FastTunnel.Server/Startup.cs @@ -4,7 +4,6 @@ // https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE // Copyright (c) 2019 Gui.H -using FastTunnel.Core; using FastTunnel.Core.Extensions; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder;