mirror of
https://github.com/FastTunnel/FastTunnel.git
synced 2025-02-08 10:59:31 +08:00
清理代码
This commit is contained in:
parent
7624d71a2b
commit
0ab538cc58
|
@ -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;
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
|
@ -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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
||||||
|
|
||||||
// 登录频率低,放在后面
|
// 登录频率低,放在后面
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
||||||
|
|
|
@ -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, "[全局异常]");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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决定是否进行代理
|
||||||
|
|
|
@ -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;
|
|
@ -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}================== ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -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; }
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
|
@ -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
|
||||||
|
|
|
@ -18,6 +18,5 @@ public class WebInfo
|
||||||
internal void LogOut()
|
internal void LogOut()
|
||||||
{
|
{
|
||||||
// TODO:退出登录
|
// TODO:退出登录
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
|
@ -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>
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
Loading…
Reference in New Issue
Block a user