清理代码

This commit is contained in:
Gui.H 2022-05-10 23:31:59 +08:00
parent 7624d71a2b
commit 0ab538cc58
35 changed files with 97 additions and 951 deletions

View File

@ -5,7 +5,7 @@
// Copyright (c) 2019 Gui.H // Copyright (c) 2019 Gui.H
using FastTunnel.Api.Models; using FastTunnel.Api.Models;
using FastTunnel.Core.Client; using FastTunnel.Core.Server;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System; using System;

View File

@ -12,8 +12,8 @@ using System.Threading.Tasks;
using FastTunnel.Core.Config; using FastTunnel.Core.Config;
using FastTunnel.Core.Extensions; using FastTunnel.Core.Extensions;
using FastTunnel.Core.Handlers.Client; using FastTunnel.Core.Handlers.Client;
using FastTunnel.Core.Models;
using FastTunnel.Core.Models.Massage; using FastTunnel.Core.Models.Massage;
using FastTunnel.Core.Protocol;
using FastTunnel.Core.Utilitys; using FastTunnel.Core.Utilitys;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@ -80,8 +80,8 @@ public class FastTunnelClient : IFastTunnelClient
// 连接到的目标IP // 连接到的目标IP
socket = new ClientWebSocket(); socket = new ClientWebSocket();
socket.Options.RemoteCertificateValidationCallback = delegate { return true; }; socket.Options.RemoteCertificateValidationCallback = delegate { return true; };
socket.Options.SetRequestHeader(FastTunnelConst.FASTTUNNEL_VERSION, AssemblyUtility.GetVersion().ToString()); socket.Options.SetRequestHeader(ProtocolConst.FASTTUNNEL_VERSION, AssemblyUtility.GetVersion().ToString());
socket.Options.SetRequestHeader(FastTunnelConst.FASTTUNNEL_TOKEN, ClientConfig.Token); socket.Options.SetRequestHeader(ProtocolConst.FASTTUNNEL_TOKEN, ClientConfig.Token);
_logger.LogInformation($"正在连接服务端 {Server.ServerAddr}:{Server.ServerPort}"); _logger.LogInformation($"正在连接服务端 {Server.ServerAddr}:{Server.ServerPort}");
await socket.ConnectAsync( await socket.ConnectAsync(
@ -110,7 +110,7 @@ public class FastTunnelClient : IFastTunnelClient
private async Task ReceiveServerAsync(CancellationToken cancellationToken) private async Task ReceiveServerAsync(CancellationToken cancellationToken)
{ {
var buffer = new byte[FastTunnelConst.MAX_CMD_LENGTH]; var buffer = new byte[ProtocolConst.MAX_CMD_LENGTH];
while (!cancellationToken.IsCancellationRequested) while (!cancellationToken.IsCancellationRequested)
{ {
var res = await socket.ReceiveAsync(buffer, cancellationToken); var res = await socket.ReceiveAsync(buffer, cancellationToken);
@ -144,7 +144,7 @@ public class FastTunnelClient : IFastTunnelClient
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex); _logger.LogError(ex, "HandleServerRequest Error");
} }
} }

View File

@ -7,11 +7,10 @@
using System; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using FastTunnel.Core.Client;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace FastTunnel.Core.Services; namespace FastTunnel.Core.Client;
public class ServiceFastTunnelClient : IHostedService public class ServiceFastTunnelClient : IHostedService
{ {

View File

@ -1,17 +0,0 @@
// 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;
namespace FastTunnel.Core.Exceptions;
public class APIErrorException : Exception
{
public APIErrorException(string message)
: base(message)
{
}
}

View File

@ -4,8 +4,8 @@
// https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE // https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE
// Copyright (c) 2019 Gui.H // Copyright (c) 2019 Gui.H
using FastTunnel.Core.Client; using FastTunnel.Core.Forwarder.Kestrel.MiddleWare;
using FastTunnel.Core.Forwarder.Kestrel; using FastTunnel.Core.Server;
using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -14,15 +14,19 @@ namespace FastTunnel.Core.Extensions;
public static class ListenOptionsSwapExtensions public static class ListenOptionsSwapExtensions
{ {
/// <summary>
/// 使用FastTunnel中间件
/// </summary>
/// <param name="listenOptions"></param>
/// <returns></returns>
public static ListenOptions UseConnectionFastTunnel(this ListenOptions listenOptions) public static ListenOptions UseConnectionFastTunnel(this ListenOptions listenOptions)
{ {
var fastTunnelServer = listenOptions.KestrelServerOptions.ApplicationServices.GetRequiredService<FastTunnelServer>();
var loggerFactory = listenOptions.KestrelServerOptions.ApplicationServices.GetRequiredService<ILoggerFactory>(); var loggerFactory = listenOptions.KestrelServerOptions.ApplicationServices.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger<SwapConnectionMiddleware>(); var logger = loggerFactory.CreateLogger<SwapConnectionMiddleware>();
var loggerClient = loggerFactory.CreateLogger<ClientConnectionMiddleware>(); var loggerHttp = loggerFactory.CreateLogger<FastTunnelConnectionMiddleware>();
var loggerHttp = loggerFactory.CreateLogger<HandleHttpConnectionMiddleware>();
var fastTunnelServer = listenOptions.KestrelServerOptions.ApplicationServices.GetRequiredService<FastTunnelServer>();
listenOptions.Use(next => new HandleHttpConnectionMiddleware(next, loggerHttp, fastTunnelServer).OnConnectionAsync); listenOptions.Use(next => new FastTunnelConnectionMiddleware(next, loggerHttp, fastTunnelServer).OnConnectionAsync);
listenOptions.Use(next => new SwapConnectionMiddleware(next, logger, fastTunnelServer).OnConnectionAsync); listenOptions.Use(next => new SwapConnectionMiddleware(next, logger, fastTunnelServer).OnConnectionAsync);
// 登录频率低,放在后面 // 登录频率低,放在后面

View File

@ -1,18 +0,0 @@
// 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 Microsoft.Extensions.Logging;
namespace FastTunnel.Core.Extensions;
public static class LoggerExtentions
{
public static void LogError(this ILogger logger, Exception ex)
{
logger.LogError(ex, string.Empty);
}
}

View File

@ -9,7 +9,7 @@ using FastTunnel.Core.Config;
using FastTunnel.Core.Forwarder.MiddleWare; using FastTunnel.Core.Forwarder.MiddleWare;
using FastTunnel.Core.Handlers.Client; using FastTunnel.Core.Handlers.Client;
using FastTunnel.Core.Handlers.Server; using FastTunnel.Core.Handlers.Server;
using FastTunnel.Core.Services; using FastTunnel.Core.Server;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -46,7 +46,6 @@ public static class ServicesExtensions
services.Configure<DefaultServerConfig>(configurationSection) services.Configure<DefaultServerConfig>(configurationSection)
.AddTransient<ILoginHandler, LoginHandler>() .AddTransient<ILoginHandler, LoginHandler>()
.AddSingleton<FastTunnelClientHandler>() .AddSingleton<FastTunnelClientHandler>()
.AddSingleton<FastTunnelSwapHandler>()
.AddSingleton<FastTunnelServer>(); .AddSingleton<FastTunnelServer>();
} }

View File

@ -1,21 +0,0 @@
// 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.Net.Sockets;
using System.Text;
using FastTunnel.Core.Models;
using FastTunnel.Core.Models.Massage;
namespace FastTunnel.Core.Extensions;
public static class SocketExtensions
{
public static void SendCmd<T>(this Socket socket, Message<T> message)
where T : TunnelMassage
{
socket.Send(Encoding.UTF8.GetBytes(message.ToJson() + "\n"));
}
}

View File

@ -10,7 +10,8 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using FastTunnel.Core.Exceptions; using FastTunnel.Core.Exceptions;
using FastTunnel.Core.Models; using FastTunnel.Core.Models.Massage;
using FastTunnel.Core.Protocol;
namespace FastTunnel.Core.Extensions; namespace FastTunnel.Core.Extensions;
@ -24,7 +25,7 @@ public static class WebSocketExtensions
} }
var buffer = Encoding.UTF8.GetBytes($"{(char)type}{content}\n"); var buffer = Encoding.UTF8.GetBytes($"{(char)type}{content}\n");
if (type != MessageType.LogIn && buffer.Length > FastTunnelConst.MAX_CMD_LENGTH) if (type != MessageType.LogIn && buffer.Length > ProtocolConst.MAX_CMD_LENGTH)
throw new ArgumentOutOfRangeException(nameof(content)); throw new ArgumentOutOfRangeException(nameof(content));
await socket.SendAsync(buffer, WebSocketMessageType.Binary, false, cancellationToken); await socket.SendAsync(buffer, WebSocketMessageType.Binary, false, cancellationToken);

View File

@ -1,37 +0,0 @@
// 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 FastTunnel.Core.Extensions;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace FastTunnel.Core.Filters;
public class FastTunnelExceptionFilter : IExceptionFilter
{
private readonly IWebHostEnvironment _hostingEnvironment;
private readonly ILogger<FastTunnelExceptionFilter> logger;
public FastTunnelExceptionFilter(
ILogger<FastTunnelExceptionFilter> logger,
IWebHostEnvironment hostingEnvironment)
{
this.logger = logger;
_hostingEnvironment = hostingEnvironment;
}
public void OnException(ExceptionContext context)
{
if (!_hostingEnvironment.IsDevelopment())
{
return;
}
logger.LogError(context.Exception, "[全局异常]");
}
}

View File

@ -1,100 +0,0 @@
// 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.Text;
using System.Threading.Tasks;
using FastTunnel.Core.Client;
using Microsoft.AspNetCore.Connections;
using Microsoft.Extensions.Logging;
namespace FastTunnel.Core.Forwarder.Kestrel;
internal class ClientConnectionMiddleware
{
private readonly ConnectionDelegate next;
private readonly ILogger<ClientConnectionMiddleware> logger;
private readonly FastTunnelServer fastTunnelServer;
public ClientConnectionMiddleware(ConnectionDelegate next, ILogger<ClientConnectionMiddleware> logger, FastTunnelServer fastTunnelServer)
{
this.next = next;
this.logger = logger;
this.fastTunnelServer = fastTunnelServer;
}
internal async Task OnConnectionAsync(ConnectionContext context)
{
if (!await ReadPipeAsync(context))
{
await next(context);
}
}
/// <summary>
///
/// </summary>
/// <param name="context"></param>
/// <returns>is for FastTunnel</returns>
private async Task<bool> 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<byte> buffer, SequencePosition position, ConnectionContext context)
{
}
/// <summary>
///
/// </summary>
/// <param name="readOnlySequence"></param>
private bool ProcessProxyLine(ReadOnlySequence<byte> readOnlySequence)
{
var str = Encoding.UTF8.GetString(readOnlySequence);
return str.StartsWith("LOGIN");
}
}

View File

@ -10,8 +10,8 @@ using System.Collections.Generic;
using System.IO.Pipelines; using System.IO.Pipelines;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using FastTunnel.Core.Client;
using FastTunnel.Core.Models; using FastTunnel.Core.Models;
using FastTunnel.Core.Server;
using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -38,7 +38,7 @@ internal class FastTunnelConnectionContext : ConnectionContext
public override IDictionary<object, object> Items { get => _inner.Items; set => _inner.Items = value; } public override IDictionary<object, object> Items { get => _inner.Items; set => _inner.Items = value; }
public bool IsFastTunnel => Method == "PROXY" || MatchWeb != null; public bool IsFastTunnel => Method == ProtocolConst.HTTP_METHOD_SWAP || MatchWeb != null;
public WebInfo MatchWeb { get; private set; } public WebInfo MatchWeb { get; private set; }
@ -47,13 +47,10 @@ internal class FastTunnelConnectionContext : ConnectionContext
return _inner.DisposeAsync(); return _inner.DisposeAsync();
} }
private readonly ReadOnlySequence<byte> readableBuffer;
/// <summary> /// <summary>
/// 解析FastTunnel协议 /// 解析FastTunnel协议
/// </summary> /// </summary>
/// <returns>is for FastTunnel</returns> internal async Task TryAnalysisPipeAsync()
internal async Task<bool> TryAnalysisPipeAsync()
{ {
var reader = Transport.Input; var reader = Transport.Input;
@ -73,21 +70,22 @@ internal class FastTunnelConnectionContext : ConnectionContext
if (position != null) if (position != null)
{ {
var readedPosition = readableBuffer.GetPosition(1, position.Value);
if (ProcessLine(tempBuffer.Slice(0, position.Value))) if (ProcessLine(tempBuffer.Slice(0, position.Value)))
{ {
if (Method == "PROXY") if (Method == ProtocolConst.HTTP_METHOD_SWAP)
{ {
reader.AdvanceTo(position.Value, position.Value); reader.AdvanceTo(readedPosition, readedPosition);
} }
else else
{ {
reader.AdvanceTo(readableBuffer.Start, readableBuffer.Start); reader.AdvanceTo(readableBuffer.Start, readableBuffer.Start);
} }
return false; return;
} }
tempBuffer = tempBuffer.Slice(readableBuffer.GetPosition(1, position.Value)); tempBuffer = tempBuffer.Slice(readedPosition);
} }
} }
while (position != null && !readableBuffer.IsEmpty); while (position != null && !readableBuffer.IsEmpty);
@ -99,15 +97,16 @@ internal class FastTunnelConnectionContext : ConnectionContext
} }
} }
return false; return;
} }
public string Method; public string Method;
public string Host = null; public string Host = null;
public string MessageId; public string MessageId;
private bool complete = false;
private bool isFirstLine = true; private bool isFirstLine = true;
public IList<string> HasReadLInes { get; private set; } = new List<string>();
/// <summary> /// <summary>
/// ///
/// GET / HTTP/1.1 /// GET / HTTP/1.1
@ -121,17 +120,19 @@ internal class FastTunnelConnectionContext : ConnectionContext
/// ///
/// </summary> /// </summary>
/// <param name="readOnlySequence"></param> /// <param name="readOnlySequence"></param>
/// <returns>Header读取完毕</returns>
private bool ProcessLine(ReadOnlySequence<byte> readOnlySequence) private bool ProcessLine(ReadOnlySequence<byte> readOnlySequence)
{ {
var lineStr = Encoding.UTF8.GetString(readOnlySequence); var lineStr = Encoding.UTF8.GetString(readOnlySequence);
Console.WriteLine($"[HandleLien] {lineStr}"); HasReadLInes.Add(lineStr);
if (isFirstLine) if (isFirstLine)
{ {
Method = lineStr.Substring(0, lineStr.IndexOf(" ")).ToUpper(); Method = lineStr.Substring(0, lineStr.IndexOf(" ")).ToUpper();
switch (Method) switch (Method)
{ {
case "PROXY": case ProtocolConst.HTTP_METHOD_SWAP:
// 客户端发起消息互转 // 客户端发起消息互转
var endIndex = lineStr.IndexOf(" ", 7); var endIndex = lineStr.IndexOf(" ", 7);
MessageId = lineStr.Substring(7, endIndex - 7); MessageId = lineStr.Substring(7, endIndex - 7);
@ -147,9 +148,11 @@ internal class FastTunnelConnectionContext : ConnectionContext
{ {
if (lineStr.Equals("\r")) if (lineStr.Equals("\r"))
{ {
complete = true; if (Method == ProtocolConst.HTTP_METHOD_SWAP)
{
if (Method != "PROXY") // do nothing
}
else
{ {
// 匹配Host // 匹配Host
if (fastTunnelServer.TryGetWebProxyByHost(Host, out var web)) if (fastTunnelServer.TryGetWebProxyByHost(Host, out var web))
@ -163,9 +166,8 @@ internal class FastTunnelConnectionContext : ConnectionContext
switch (Method) switch (Method)
{ {
case "PROXY": case ProtocolConst.HTTP_METHOD_SWAP:
// 找msgid // do nothing
break; break;
default: default:
// 检查Host决定是否进行代理 // 检查Host决定是否进行代理

View File

@ -5,19 +5,23 @@
// Copyright (c) 2019 Gui.H // Copyright (c) 2019 Gui.H
using System.Threading.Tasks; using System.Threading.Tasks;
using FastTunnel.Core.Client; using FastTunnel.Core.Forwarder.Kestrel;
using FastTunnel.Core.Server;
using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Connections;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace FastTunnel.Core.Forwarder.Kestrel; namespace FastTunnel.Core.Forwarder.Kestrel.MiddleWare;
internal class HandleHttpConnectionMiddleware /// <summary>
/// 预处理中间件
/// </summary>
internal class FastTunnelConnectionMiddleware
{ {
private readonly ConnectionDelegate next; private readonly ConnectionDelegate next;
private readonly ILogger<HandleHttpConnectionMiddleware> logger; private readonly ILogger<FastTunnelConnectionMiddleware> logger;
private readonly FastTunnelServer fastTunnelServer; private readonly FastTunnelServer fastTunnelServer;
public HandleHttpConnectionMiddleware(ConnectionDelegate next, ILogger<HandleHttpConnectionMiddleware> logger, FastTunnelServer fastTunnelServer) public FastTunnelConnectionMiddleware(ConnectionDelegate next, ILogger<FastTunnelConnectionMiddleware> logger, FastTunnelServer fastTunnelServer)
{ {
this.next = next; this.next = next;
this.logger = logger; this.logger = logger;

View File

@ -10,16 +10,21 @@ using System.IO;
using System.Net.WebSockets; using System.Net.WebSockets;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using FastTunnel.Core.Client; using FastTunnel.Core.Exceptions;
using FastTunnel.Core.Extensions; using FastTunnel.Core.Extensions;
using FastTunnel.Core.Forwarder.Kestrel;
using FastTunnel.Core.Forwarder.MiddleWare; using FastTunnel.Core.Forwarder.MiddleWare;
using FastTunnel.Core.Models; using FastTunnel.Core.Models.Massage;
using FastTunnel.Core.Server;
using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Connections.Features; using Microsoft.AspNetCore.Connections.Features;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace FastTunnel.Core.Forwarder.Kestrel; namespace FastTunnel.Core.Forwarder.Kestrel.MiddleWare;
/// <summary>
/// 核心逻辑处理中间件
/// </summary>
internal class SwapConnectionMiddleware internal class SwapConnectionMiddleware
{ {
private readonly ConnectionDelegate next; private readonly ConnectionDelegate next;
@ -38,7 +43,7 @@ internal class SwapConnectionMiddleware
var ctx = context as FastTunnelConnectionContext; var ctx = context as FastTunnelConnectionContext;
if (ctx != null && ctx.IsFastTunnel) if (ctx != null && ctx.IsFastTunnel)
{ {
if (ctx.Method == "PROXY") if (ctx.Method == ProtocolConst.HTTP_METHOD_SWAP)
{ {
await doSwap(ctx); await doSwap(ctx);
} }
@ -50,8 +55,6 @@ internal class SwapConnectionMiddleware
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }
} }
else else
{ {
@ -82,7 +85,7 @@ internal class SwapConnectionMiddleware
web.LogOut(); web.LogOut();
// 通讯异常,返回客户端离线 // 通讯异常,返回客户端离线
throw new Exception("客户端离线"); throw new ClienOffLineException("客户端离线");
} }
using var res = await tcs.Task; using var res = await tcs.Task;
@ -142,50 +145,4 @@ internal class SwapConnectionMiddleware
logger.LogInformation($"=====================Swap End:{requestId}================== "); logger.LogInformation($"=====================Swap End:{requestId}================== ");
} }
} }
private async Task Swap(ReadOnlySequence<byte> buffer, SequencePosition position, ConnectionContext context)
{
var firstLineBuffer = buffer.Slice(0, position);
var firstLine = Encoding.UTF8.GetString(firstLineBuffer);
// SWAP /c74eb488a0f54d888e63d85c67428b52 HTTP/1.1
var endIndex = firstLine.IndexOf(" ", 6);
var requestId = firstLine.Substring(6, endIndex - 6);
Console.WriteLine($"[开始进行Swap操作] {requestId}");
context.Transport.Input.AdvanceTo(buffer.GetPosition(1, position), buffer.GetPosition(1, position));
if (!fastTunnelServer.ResponseTasks.TryRemove(requestId, out var responseForYarp))
{
logger.LogError($"[PROXY]:RequestId不存在 {requestId}");
return;
};
using var reverseConnection = new DuplexPipeStream(context.Transport.Input, context.Transport.Output, true);
responseForYarp.TrySetResult(reverseConnection);
var lifetime = context.Features.Get<IConnectionLifetimeFeature>();
var closedAwaiter = new TaskCompletionSource<object>();
lifetime.ConnectionClosed.Register((task) =>
{
(task as TaskCompletionSource<object>).SetResult(null);
}, closedAwaiter);
try
{
await closedAwaiter.Task;
}
catch (Exception ex)
{
logger.LogError(ex, "");
}
finally
{
context.Transport.Input.Complete();
context.Transport.Output.Complete();
logger.LogInformation($"=====================Swap End:{requestId}================== ");
}
}
} }

View File

@ -9,7 +9,7 @@ using System.Diagnostics;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace FastTunnel.Core.Forwarder.MiddleWare namespace FastTunnel.Core.Forwarder.Kestrel.MiddleWare
{ {
internal static class TaskToApm internal static class TaskToApm
{ {
@ -21,7 +21,7 @@ namespace FastTunnel.Core.Forwarder.MiddleWare
/// <param name="callback">The callback to be invoked upon completion.</param> /// <param name="callback">The callback to be invoked upon completion.</param>
/// <param name="state">The state to be stored in the IAsyncResult.</param> /// <param name="state">The state to be stored in the IAsyncResult.</param>
/// <returns>An IAsyncResult to represent the task's asynchronous operation.</returns> /// <returns>An IAsyncResult to represent the task's asynchronous operation.</returns>
public static IAsyncResult Begin(Task task, AsyncCallback? callback, object? state) => public static IAsyncResult Begin(Task task, AsyncCallback callback, object state) =>
new TaskAsyncResult(task, state, callback); new TaskAsyncResult(task, state, callback);
/// <summary>Processes an IAsyncResult returned by Begin.</summary> /// <summary>Processes an IAsyncResult returned by Begin.</summary>
@ -60,13 +60,13 @@ namespace FastTunnel.Core.Forwarder.MiddleWare
/// <summary>The wrapped Task.</summary> /// <summary>The wrapped Task.</summary>
internal readonly Task _task; internal readonly Task _task;
/// <summary>Callback to invoke when the wrapped task completes.</summary> /// <summary>Callback to invoke when the wrapped task completes.</summary>
private readonly AsyncCallback? _callback; private readonly AsyncCallback _callback;
/// <summary>Initializes the IAsyncResult with the Task to wrap and the associated object state.</summary> /// <summary>Initializes the IAsyncResult with the Task to wrap and the associated object state.</summary>
/// <param name="task">The Task to wrap.</param> /// <param name="task">The Task to wrap.</param>
/// <param name="state">The new AsyncState value.</param> /// <param name="state">The new AsyncState value.</param>
/// <param name="callback">Callback to invoke when the wrapped task completes.</param> /// <param name="callback">Callback to invoke when the wrapped task completes.</param>
internal TaskAsyncResult(Task task, object? state, AsyncCallback? callback) internal TaskAsyncResult(Task task, object state, AsyncCallback callback)
{ {
Debug.Assert(task != null); Debug.Assert(task != null);
_task = task; _task = task;
@ -99,7 +99,7 @@ namespace FastTunnel.Core.Forwarder.MiddleWare
} }
/// <summary>Gets a user-defined object that qualifies or contains information about an asynchronous operation.</summary> /// <summary>Gets a user-defined object that qualifies or contains information about an asynchronous operation.</summary>
public object? AsyncState { get; } public object AsyncState { get; }
/// <summary>Gets a value that indicates whether the asynchronous operation completed synchronously.</summary> /// <summary>Gets a value that indicates whether the asynchronous operation completed synchronously.</summary>
/// <remarks>This is set lazily based on whether the <see cref="_task"/> has completed by the time this object is created.</remarks> /// <remarks>This is set lazily based on whether the <see cref="_task"/> has completed by the time this object is created.</remarks>
public bool CompletedSynchronously { get; } public bool CompletedSynchronously { get; }

View File

@ -9,6 +9,7 @@ using System.Buffers;
using System.IO; using System.IO;
using System.IO.Pipelines; using System.IO.Pipelines;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using FastTunnel.Core.Extensions; using FastTunnel.Core.Extensions;
@ -139,6 +140,7 @@ internal class DuplexPipeStream : Stream
// buffer.Count is int // buffer.Count is int
var count = (int)Math.Min(readableBuffer.Length, destination.Length); var count = (int)Math.Min(readableBuffer.Length, destination.Length);
readableBuffer = readableBuffer.Slice(0, count); readableBuffer = readableBuffer.Slice(0, count);
Console.WriteLine($"[{this.GetHashCode()}读取]{Encoding.UTF8.GetString(readableBuffer)}");
readableBuffer.CopyTo(destination.Span); readableBuffer.CopyTo(destination.Span);
return count; return count;
} }

View File

@ -8,10 +8,12 @@ using System;
using System.Net.WebSockets; using System.Net.WebSockets;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using FastTunnel.Core.Client;
using FastTunnel.Core.Extensions; using FastTunnel.Core.Extensions;
using FastTunnel.Core.Handlers.Server; using FastTunnel.Core.Handlers.Server;
using FastTunnel.Core.Models; using FastTunnel.Core.Models;
using FastTunnel.Core.Models.Massage;
using FastTunnel.Core.Protocol;
using FastTunnel.Core.Server;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -38,7 +40,7 @@ public class FastTunnelClientHandler
{ {
try try
{ {
if (!context.WebSockets.IsWebSocketRequest || !context.Request.Headers.TryGetValue(FastTunnelConst.FASTTUNNEL_VERSION, out var version)) if (!context.WebSockets.IsWebSocketRequest || !context.Request.Headers.TryGetValue(ProtocolConst.FASTTUNNEL_VERSION, out var version))
{ {
await next(); await next();
return; return;
@ -48,7 +50,7 @@ public class FastTunnelClientHandler
} }
catch (Exception ex) catch (Exception ex)
{ {
logger.LogError(ex); logger.LogError(ex, "处理登录异常");
} }
} }
@ -103,7 +105,7 @@ public class FastTunnelClientHandler
return true; return true;
// 客户端未携带token登录失败 // 客户端未携带token登录失败
if (!context.Request.Headers.TryGetValue(FastTunnelConst.FASTTUNNEL_TOKEN, out var token)) if (!context.Request.Headers.TryGetValue(ProtocolConst.FASTTUNNEL_TOKEN, out var token))
return false; return false;
if (fastTunnelServer.ServerOption.CurrentValue.Tokens?.Contains(token) ?? false) if (fastTunnelServer.ServerOption.CurrentValue.Tokens?.Contains(token) ?? false)

View File

@ -1,73 +0,0 @@
// 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.Threading.Tasks;
using FastTunnel.Core.Client;
using FastTunnel.Core.Extensions;
using Microsoft.AspNetCore.Connections.Features;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
namespace FastTunnel.Core.Forwarder.MiddleWare;
public class FastTunnelSwapHandler
{
private readonly ILogger<FastTunnelClientHandler> logger;
private readonly FastTunnelServer fastTunnelServer;
public FastTunnelSwapHandler(ILogger<FastTunnelClientHandler> logger, FastTunnelServer fastTunnelServer)
{
this.logger = logger;
this.fastTunnelServer = fastTunnelServer;
}
public async Task Handle(HttpContext context, Func<Task> next)
{
try
{
if (context.Request.Method != "PROXY")
{
await next();
return;
}
var requestId = context.Request.Path.Value.Trim('/');
logger.LogDebug($"[PROXY]:Start {requestId}");
if (!fastTunnelServer.ResponseTasks.TryRemove(requestId, out var responseAwaiter))
{
logger.LogError($"[PROXY]:RequestId不存在 {requestId}");
return;
};
var lifetime = context.Features.Get<IConnectionLifetimeFeature>();
var transport = context.Features.Get<IConnectionTransportFeature>();
if (lifetime == null || transport == null)
{
return;
}
using var reverseConnection = new WebSocketStream(lifetime, transport);
responseAwaiter.TrySetResult(reverseConnection);
var closedAwaiter = new TaskCompletionSource<object>();
lifetime.ConnectionClosed.Register((task) =>
{
(task as TaskCompletionSource<object>).SetResult(null);
}, closedAwaiter);
await closedAwaiter.Task;
logger.LogDebug($"[PROXY]:Closed {requestId}");
}
catch (Exception ex)
{
logger.LogError(ex);
}
}
}

View File

@ -1,233 +0,0 @@
// 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.Globalization;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
namespace FastTunnel.Core.Forwarder.MiddleWare;
internal sealed class LoggingStream : Stream
{
private readonly Stream _inner;
private readonly ILogger _logger;
public LoggingStream(Stream inner, ILogger logger)
{
_inner = inner;
_logger = logger;
}
public override bool CanRead
{
get
{
return _inner.CanRead;
}
}
public override bool CanSeek
{
get
{
return _inner.CanSeek;
}
}
public override bool CanWrite
{
get
{
return _inner.CanWrite;
}
}
public override long Length
{
get
{
return _inner.Length;
}
}
public override long Position
{
get
{
return _inner.Position;
}
set
{
_inner.Position = value;
}
}
public override void Flush()
{
_inner.Flush();
}
public override Task FlushAsync(CancellationToken cancellationToken)
{
return _inner.FlushAsync(cancellationToken);
}
public override int Read(byte[] buffer, int offset, int count)
{
var read = _inner.Read(buffer, offset, count);
Log("[Read]", new ReadOnlySpan<byte>(buffer, offset, read));
return read;
}
public override int Read(Span<byte> destination)
{
var read = _inner.Read(destination);
Log("[Read]", destination.Slice(0, read));
return read;
}
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
var read = await _inner.ReadAsync(buffer.AsMemory(offset, count), cancellationToken);
Log("[ReadAsync]", new ReadOnlySpan<byte>(buffer, offset, read));
return read;
}
public override async ValueTask<int> ReadAsync(Memory<byte> destination, CancellationToken cancellationToken = default)
{
var read = await _inner.ReadAsync(destination, cancellationToken);
Log("[ReadAsync]", destination.Span.Slice(0, read));
return read;
}
public override long Seek(long offset, SeekOrigin origin)
{
return _inner.Seek(offset, origin);
}
public override void SetLength(long value)
{
_inner.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
Log("[Write]", new ReadOnlySpan<byte>(buffer, offset, count));
_inner.Write(buffer, offset, count);
}
public override void Write(ReadOnlySpan<byte> source)
{
Log("[Write]", source);
_inner.Write(source);
}
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
Log("WriteAsync", new ReadOnlySpan<byte>(buffer, offset, count));
return _inner.WriteAsync(buffer, offset, count, cancellationToken);
}
public override ValueTask WriteAsync(ReadOnlyMemory<byte> source, CancellationToken cancellationToken = default)
{
Log("WriteAsync", source.Span);
return _inner.WriteAsync(source, cancellationToken);
}
private void Log(string method, ReadOnlySpan<byte> buffer)
{
var builder = new StringBuilder();
builder.Append(method);
builder.Append('[');
builder.Append(buffer.Length);
builder.Append(']');
if (buffer.Length > 0)
{
builder.AppendLine();
}
var charBuilder = new StringBuilder();
// Write the hex
for (var i = 0; i < buffer.Length; i++)
{
builder.Append(buffer[i].ToString("X2", CultureInfo.InvariantCulture));
builder.Append(' ');
var bufferChar = (char)buffer[i];
if (char.IsControl(bufferChar))
{
charBuilder.Append('.');
}
else
{
charBuilder.Append(bufferChar);
}
if ((i + 1) % 16 == 0)
{
builder.Append(" ");
builder.Append(charBuilder);
if (i != buffer.Length - 1)
{
builder.AppendLine();
}
charBuilder.Clear();
}
else if ((i + 1) % 8 == 0)
{
builder.Append(' ');
charBuilder.Append(' ');
}
}
// Different than charBuffer.Length since charBuffer contains an extra " " after the 8th byte.
var numBytesInLastLine = buffer.Length % 16;
if (numBytesInLastLine > 0)
{
// 2 (between hex and char blocks) + num bytes left (3 per byte)
var padLength = 2 + (3 * (16 - numBytesInLastLine));
// extra for space after 8th byte
if (numBytesInLastLine < 8)
{
padLength++;
}
builder.Append(new string(' ', padLength));
builder.Append(charBuilder);
}
_logger.LogInformation(builder.ToString());
}
// The below APM methods call the underlying Read/WriteAsync methods which will still be logged.
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
{
return TaskToApm.Begin(ReadAsync(buffer, offset, count), callback, state);
}
public override int EndRead(IAsyncResult asyncResult)
{
return TaskToApm.End<int>(asyncResult);
}
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
{
return TaskToApm.Begin(WriteAsync(buffer, offset, count), callback, state);
}
public override void EndWrite(IAsyncResult asyncResult)
{
TaskToApm.End(asyncResult);
}
}

View File

@ -1,82 +0,0 @@
// 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.IO;
using System.Text;
using System.Threading.Tasks;
namespace FastTunnel.Core.Forwarder;
public class ResponseStream : Stream
{
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => true;
public override long Length => throw new NotImplementedException();
public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
private readonly MemoryStream m_Stream;
public ResponseStream(byte[] bytes)
{
m_Stream = new MemoryStream(bytes);
}
public override void Flush()
{
throw new NotImplementedException();
}
private bool complete;
public override int Read(byte[] buffer, int offset, int count)
{
if (!complete)
{
return 0;
};
var len = m_Stream.Read(buffer, offset, count);
return len;
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
Console.Write(Encoding.UTF8.GetString(buffer, offset, count));
complete = true;
}
protected override void Dispose(bool disposing)
{
if (!disposing)
{
return;
}
m_Stream.Dispose();
}
public override ValueTask DisposeAsync()
{
Dispose(true);
return ValueTask.CompletedTask;
}
}

View File

@ -1,109 +0,0 @@
// 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.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
namespace FastTunnel.Core.Forwarder;
public class TranStream : Stream
{
private readonly Stream readStream;
private readonly Stream wirteStream;
public TranStream(HttpContext context)
{
this.readStream = context.Request.BodyReader.AsStream();
this.wirteStream = context.Response.BodyWriter.AsStream();
}
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => true;
public override long Length => throw new NotSupportedException();
public override long Position
{
get => throw new NotSupportedException();
set => throw new NotSupportedException();
}
public override void Flush()
{
this.wirteStream.Flush();
}
public override Task FlushAsync(CancellationToken cancellationToken)
{
return this.wirteStream.FlushAsync(cancellationToken);
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
return this.readStream.Read(buffer, offset, count);
}
public override void Write(byte[] buffer, int offset, int count)
{
this.wirteStream.Write(buffer, offset, count);
}
public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default)
{
return this.readStream.ReadAsync(buffer, cancellationToken);
}
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
var len = await this.readStream.ReadAsync(buffer, offset, count, cancellationToken);
if (len == 0) { Console.WriteLine("==========ReadAsync END=========="); }
return len;
}
public override void Write(ReadOnlySpan<byte> buffer)
{
this.wirteStream.Write(buffer);
}
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
return this.wirteStream.WriteAsync(buffer, offset, count, cancellationToken);
}
public override async ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)
{
await this.wirteStream.WriteAsync(buffer, cancellationToken);
}
protected override void Dispose(bool disposing)
{
Console.WriteLine("========Dispose=========");
}
public override ValueTask DisposeAsync()
{
return ValueTask.CompletedTask;
}
public override void Close()
{
Console.WriteLine("========Close=========");
base.Close();
}
}

View File

@ -1,112 +0,0 @@
// 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.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Connections.Features;
namespace FastTunnel.Core.Forwarder;
internal sealed class WebSocketStream : Stream
{
private readonly Stream readStream;
private readonly Stream wirteStream;
private readonly IConnectionLifetimeFeature lifetimeFeature;
public WebSocketStream(IConnectionLifetimeFeature lifetimeFeature, IConnectionTransportFeature transportFeature)
{
this.readStream = transportFeature.Transport.Input.AsStream();
this.wirteStream = transportFeature.Transport.Output.AsStream();
this.lifetimeFeature = lifetimeFeature;
}
public WebSocketStream(Stream stream)
{
this.readStream = stream;
this.wirteStream = stream;
this.lifetimeFeature = null;
}
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => true;
public override long Length => throw new NotSupportedException();
public override long Position
{
get => throw new NotSupportedException();
set => throw new NotSupportedException();
}
public override void Flush()
{
this.wirteStream.Flush();
}
public override Task FlushAsync(CancellationToken cancellationToken)
{
return this.wirteStream.FlushAsync(cancellationToken);
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
return this.readStream.Read(buffer, offset, count);
}
public override void Write(byte[] buffer, int offset, int count)
{
this.wirteStream.Write(buffer, offset, count);
}
public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default)
{
return this.readStream.ReadAsync(buffer, cancellationToken);
}
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
return this.readStream.ReadAsync(buffer, offset, count, cancellationToken);
}
public override void Write(ReadOnlySpan<byte> buffer)
{
this.wirteStream.Write(buffer);
}
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
return this.wirteStream.WriteAsync(buffer, offset, count, cancellationToken);
}
public override async ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)
{
await this.wirteStream.WriteAsync(buffer, cancellationToken);
}
protected override void Dispose(bool disposing)
{
this.lifetimeFeature?.Abort();
}
public override ValueTask DisposeAsync()
{
this.lifetimeFeature?.Abort();
return ValueTask.CompletedTask;
}
}

View File

@ -10,10 +10,11 @@ using System.Net.Sockets;
using System.Net.WebSockets; using System.Net.WebSockets;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using FastTunnel.Core.Client;
using FastTunnel.Core.Exceptions; using FastTunnel.Core.Exceptions;
using FastTunnel.Core.Extensions; using FastTunnel.Core.Extensions;
using FastTunnel.Core.Models; using FastTunnel.Core.Models;
using FastTunnel.Core.Models.Massage;
using FastTunnel.Core.Server;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace FastTunnel.Core.Handlers.Server; namespace FastTunnel.Core.Handlers.Server;

View File

@ -6,7 +6,7 @@
using System.Net.WebSockets; using System.Net.WebSockets;
using System.Threading.Tasks; using System.Threading.Tasks;
using FastTunnel.Core.Client; using FastTunnel.Core.Server;
namespace FastTunnel.Core.Handlers.Server; namespace FastTunnel.Core.Handlers.Server;

View File

@ -5,8 +5,8 @@
// Copyright (c) 2019 Gui.H // Copyright (c) 2019 Gui.H
using System.Threading.Tasks; using System.Threading.Tasks;
using FastTunnel.Core.Client;
using FastTunnel.Core.Models; using FastTunnel.Core.Models;
using FastTunnel.Core.Server;
namespace FastTunnel.Core.Handlers.Server; namespace FastTunnel.Core.Handlers.Server;

View File

@ -9,11 +9,11 @@ using System.Linq;
using System.Text.Json; using System.Text.Json;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using FastTunnel.Core.Client;
using FastTunnel.Core.Extensions; using FastTunnel.Core.Extensions;
using FastTunnel.Core.Listener; using FastTunnel.Core.Listener;
using FastTunnel.Core.Models; using FastTunnel.Core.Models;
using FastTunnel.Core.Models.Massage; using FastTunnel.Core.Models.Massage;
using FastTunnel.Core.Server;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace FastTunnel.Core.Handlers.Server; namespace FastTunnel.Core.Handlers.Server;

View File

@ -4,14 +4,8 @@
// https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE // https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE
// Copyright (c) 2019 Gui.H // Copyright (c) 2019 Gui.H
namespace FastTunnel.Core.Models; namespace FastTunnel.Core.Models.Massage;
public struct Message<T>
{
public MessageType MessageType { get; set; }
public T Content { get; set; }
}
public enum MessageType : byte public enum MessageType : byte
{ {

View File

@ -10,9 +10,9 @@ using System.Net;
using System.Net.WebSockets; using System.Net.WebSockets;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using FastTunnel.Core.Client;
using FastTunnel.Core.Handlers.Server; using FastTunnel.Core.Handlers.Server;
using FastTunnel.Core.Protocol; using FastTunnel.Core.Protocol;
using FastTunnel.Core.Server;
namespace FastTunnel.Core.Models; namespace FastTunnel.Core.Models;
@ -53,7 +53,7 @@ public class TunnelClient
public async Task ReviceAsync(CancellationToken cancellationToken) public async Task ReviceAsync(CancellationToken cancellationToken)
{ {
var buffer = new byte[FastTunnelConst.MAX_CMD_LENGTH]; var buffer = new byte[ProtocolConst.MAX_CMD_LENGTH];
var tunnelProtocol = new TunnelProtocol(); var tunnelProtocol = new TunnelProtocol();
while (true) while (true)
@ -71,6 +71,7 @@ public class TunnelClient
} }
} }
} }
private async Task<bool> HandleCmdAsync(TunnelClient tunnelClient, string lineCmd) private async Task<bool> HandleCmdAsync(TunnelClient tunnelClient, string lineCmd)
{ {
try try

View File

@ -18,6 +18,5 @@ public class WebInfo
internal void LogOut() internal void LogOut()
{ {
// TODO:退出登录 // TODO:退出登录
throw new NotImplementedException();
} }
} }

View File

@ -4,13 +4,15 @@
// https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE // https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE
// Copyright (c) 2019 Gui.H // Copyright (c) 2019 Gui.H
namespace FastTunnel.Core; namespace FastTunnel.Core.Protocol;
public class FastTunnelConst public class ProtocolConst
{ {
public const string FASTTUNNEL_VERSION = "FT_VERSION"; public const string FASTTUNNEL_VERSION = "FT_VERSION";
public const string FASTTUNNEL_MSGID = "FT_MSGID"; public const string FASTTUNNEL_MSGID = "FT_MSGID";
public const string FASTTUNNEL_TOKEN = "FT_TOKEN"; public const string FASTTUNNEL_TOKEN = "FT_TOKEN";
public const int MAX_CMD_LENGTH = 100; public const int MAX_CMD_LENGTH = 100;
public const string HTTP_METHOD_SWAP = "PROXY";
} }

View File

@ -15,7 +15,7 @@ using FastTunnel.Core.Models;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
namespace FastTunnel.Core.Client; namespace FastTunnel.Core.Server;
public class FastTunnelServer public class FastTunnelServer
{ {
@ -38,7 +38,7 @@ public class FastTunnelServer
public FastTunnelServer(ILogger<FastTunnelServer> logger, IOptionsMonitor<DefaultServerConfig> serverSettings) public FastTunnelServer(ILogger<FastTunnelServer> logger, IOptionsMonitor<DefaultServerConfig> serverSettings)
{ {
this.logger = logger; this.logger = logger;
this.ServerOption = serverSettings; ServerOption = serverSettings;
} }
/// <summary> /// <summary>

View File

@ -8,8 +8,15 @@ using System;
namespace FastTunnel.Core.Utilitys; namespace FastTunnel.Core.Utilitys;
/// <summary>
/// Assembly工具集
/// </summary>
public static class AssemblyUtility public static class AssemblyUtility
{ {
/// <summary>
/// 获取版本号
/// </summary>
/// <returns></returns>
public static Version GetVersion() public static Version GetVersion()
{ {
return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;

View File

@ -43,8 +43,5 @@
<None Update="uninstall.bat"> <None Update="uninstall.bat">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Update="install.bat">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,12 +0,0 @@
CHCP 65001
@echo off
color 0e
@echo ==================================
@echo 提醒:请右键本文件,用管理员方式打开。
@echo ==================================
@echo Start Install FastTunnel.Server
sc create FastTunnel.Server binPath=%~dp0\FastTunnel.Server.exe start= auto
sc description FastTunnel.Server "FastTunnel-开源内网穿透服务仓库地址https://github.com/SpringHgui/FastTunnel star项目以支持作者"
Net Start FastTunnel.Server
pause

View File

@ -1,11 +0,0 @@
CHCP 65001
@echo off
color 0e
@echo ==================================
@echo 提醒:请右键本文件,用管理员方式打开。
@echo ==================================
@echo Start Remove FastTunnel.Server
Net stop FastTunnel.Server
sc delete FastTunnel.Server
pause