diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 0000000..84233be
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,7 @@
+
+
+ 2.0.1
+ enable
+ net5.0
+
+
\ No newline at end of file
diff --git a/FastTunnel.Api/FastTunnel.Api.csproj b/FastTunnel.Api/FastTunnel.Api.csproj
index e8a4500..1a20f89 100644
--- a/FastTunnel.Api/FastTunnel.Api.csproj
+++ b/FastTunnel.Api/FastTunnel.Api.csproj
@@ -1,8 +1,6 @@
-
+
- net5.0
- enable
1.0.0
https://github.com/FastTunnel/FastTunnel/tree/v2/FastTunnel.Api
https://github.com/FastTunnel/FastTunnel/tree/v2/FastTunnel.Api
diff --git a/FastTunnel.Client/FastTunnel.Client.csproj b/FastTunnel.Client/FastTunnel.Client.csproj
index cbd946d..79a26b5 100644
--- a/FastTunnel.Client/FastTunnel.Client.csproj
+++ b/FastTunnel.Client/FastTunnel.Client.csproj
@@ -2,7 +2,6 @@
Exe
- net5.0
@@ -21,12 +20,6 @@
Always
-
- PreserveNewest
-
-
- PreserveNewest
-
diff --git a/FastTunnel.Core/Client/FastTunnelClient.cs b/FastTunnel.Core/Client/FastTunnelClient.cs
index 81a51fc..aaa303e 100644
--- a/FastTunnel.Core/Client/FastTunnelClient.cs
+++ b/FastTunnel.Core/Client/FastTunnelClient.cs
@@ -85,7 +85,7 @@ namespace FastTunnel.Core.Client
_logger.LogInformation($"正在连接服务端 {Server.ServerAddr}:{Server.ServerPort}");
await socket.ConnectAsync(
- new Uri($"ws://{Server.ServerAddr}:{Server.ServerPort}"), cancellationToken);
+ new Uri($"{Server.Protocol}://{Server.ServerAddr}:{Server.ServerPort}"), cancellationToken);
_logger.LogDebug("连接服务端成功");
@@ -151,13 +151,6 @@ namespace FastTunnel.Core.Client
public void Stop(CancellationToken cancellationToken)
{
_logger.LogInformation("===== FastTunnel Client Stoping =====");
- if (socket == null)
- return;
-
- if (socket.State == WebSocketState.Connecting)
- return;
-
- socket.CloseAsync(WebSocketCloseStatus.Empty, string.Empty, cancellationToken);
}
}
}
diff --git a/FastTunnel.Core/Config/IClientConfig.cs b/FastTunnel.Core/Config/IClientConfig.cs
index ebc76fc..c3ccb7f 100644
--- a/FastTunnel.Core/Config/IClientConfig.cs
+++ b/FastTunnel.Core/Config/IClientConfig.cs
@@ -18,6 +18,8 @@ namespace FastTunnel.Core.Config
public class SuiDaoServer
{
+ public string Protocol { get; set; } = "ws";
+
public string ServerAddr { get; set; }
public int ServerPort { get; set; }
diff --git a/FastTunnel.Core/Extensions/ServicesExtensions.cs b/FastTunnel.Core/Extensions/ServicesExtensions.cs
index 856851c..dc04488 100644
--- a/FastTunnel.Core/Extensions/ServicesExtensions.cs
+++ b/FastTunnel.Core/Extensions/ServicesExtensions.cs
@@ -14,6 +14,11 @@ using FastTunnel.Core.Filters;
using Microsoft.AspNetCore.Mvc.Filters;
using FastTunnel.Core.Models;
using FastTunnel.Core.Handlers.Server;
+using Microsoft.AspNetCore.Routing;
+using Microsoft.Extensions.Options;
+using System.Threading.Tasks;
+using System.Threading;
+using Microsoft.AspNetCore.Http;
namespace FastTunnel.Core
{
@@ -71,5 +76,24 @@ namespace FastTunnel.Core
app.Use(clientHandler.Handle);
app.Use(swapHandler.Handle);
}
+
+ public static void MapFastTunnelServer(this IEndpointRouteBuilder endpoints)
+ {
+ endpoints.MapReverseProxy();
+ endpoints.MapFallback(context =>
+ {
+ var options = context.RequestServices.GetRequiredService>();
+ var host = context.Request.Host.Host;
+ if (!host.EndsWith(options.CurrentValue.WebDomain) || host.Equals(options.CurrentValue.WebDomain))
+ {
+ context.Response.StatusCode = 404;
+ return Task.CompletedTask;
+ }
+
+ context.Response.StatusCode = 200;
+ context.Response.WriteAsync(TunnelResource.Page_NotFound, CancellationToken.None);
+ return Task.CompletedTask;
+ });
+ }
}
}
\ No newline at end of file
diff --git a/FastTunnel.Core/FastTunnel.Core.csproj b/FastTunnel.Core/FastTunnel.Core.csproj
index 2007eb2..134a323 100644
--- a/FastTunnel.Core/FastTunnel.Core.csproj
+++ b/FastTunnel.Core/FastTunnel.Core.csproj
@@ -1,10 +1,6 @@
- Library
- net5.0
-
-
https://github.com/SpringHgui/FastTunnel
MIT
FastTunnel
@@ -18,7 +14,6 @@
git
FastTunnel.Core
FastTunnel.Core
- 2.0.1
@@ -52,7 +47,7 @@
- ResXFileCodeGenerator
+ PublicResXFileCodeGenerator
TunnelResource.Designer.cs
diff --git a/FastTunnel.Core/TunnelResource.Designer.cs b/FastTunnel.Core/TunnelResource.Designer.cs
index 2a800a4..9af06ff 100644
--- a/FastTunnel.Core/TunnelResource.Designer.cs
+++ b/FastTunnel.Core/TunnelResource.Designer.cs
@@ -22,7 +22,7 @@ namespace FastTunnel.Core {
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class TunnelResource {
+ public class TunnelResource {
private static global::System.Resources.ResourceManager resourceMan;
@@ -36,7 +36,7 @@ namespace FastTunnel.Core {
/// Returns the cached ResourceManager instance used by this class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager {
+ public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FastTunnel.Core.TunnelResource", typeof(TunnelResource).Assembly);
@@ -51,7 +51,7 @@ namespace FastTunnel.Core {
/// resource lookups using this strongly typed resource class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture {
+ public static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
@@ -63,7 +63,7 @@ namespace FastTunnel.Core {
///
/// Looks up a localized string similar to 服务端禁用了Forward.
///
- internal static string ForwardDisabled {
+ public static string ForwardDisabled {
get {
return ResourceManager.GetString("ForwardDisabled", resourceCulture);
}
@@ -72,7 +72,7 @@ namespace FastTunnel.Core {
///
/// Looks up a localized string similar to 您尚未创建任何隧道,请登录https://suidao.io 创建后重试。.
///
- internal static string NoTunnel {
+ public static string NoTunnel {
get {
return ResourceManager.GetString("NoTunnel", resourceCulture);
}
@@ -101,7 +101,7 @@ namespace FastTunnel.Core {
/// color: #fff;
/// background-color [rest of string was truncated]";.
///
- internal static string Page_HostRequired {
+ public static string Page_HostRequired {
get {
return ResourceManager.GetString("Page_HostRequired", resourceCulture);
}
@@ -129,7 +129,7 @@ namespace FastTunnel.Core {
/// color: #fff;
/// background-color: [rest of string was truncated]";.
///
- internal static string Page_NoSite {
+ public static string Page_NoSite {
get {
return ResourceManager.GetString("Page_NoSite", resourceCulture);
}
@@ -158,7 +158,7 @@ namespace FastTunnel.Core {
/// color: #fff;
/// background-color [rest of string was truncated]";.
///
- internal static string Page_NotAccessIps {
+ public static string Page_NotAccessIps {
get {
return ResourceManager.GetString("Page_NotAccessIps", resourceCulture);
}
@@ -187,9 +187,38 @@ namespace FastTunnel.Core {
/// color: #fff;
/// background-color [rest of string was truncated]";.
///
- internal static string Page_Offline {
+ public static string Page_NotFound {
get {
- return ResourceManager.GetString("Page_NoTunnel", resourceCulture);
+ return ResourceManager.GetString("Page_NotFund", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to <!DOCTYPE html>
+ ///<html lang="en">
+ ///
+ ///<head>
+ /// <meta charset="utf-8" />
+ /// <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ /// <title>FastTunnel</title>
+ /// <link href="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
+ /// <style>
+ /// .err-info {
+ /// margin-top: 120px;
+ /// }
+ ///
+ /// /* Provide sufficient contrast against white background */
+ /// a {
+ /// color: #0366d6;
+ /// }
+ ///
+ /// .btn-primary {
+ /// color: #fff;
+ /// background-color [rest of string was truncated]";.
+ ///
+ public static string Page_Offline {
+ get {
+ return ResourceManager.GetString("Page_Offline", resourceCulture);
}
}
@@ -213,7 +242,7 @@ namespace FastTunnel.Core {
///<body>
/// <head [rest of string was truncated]";.
///
- internal static string Test {
+ public static string Test {
get {
return ResourceManager.GetString("Test", resourceCulture);
}
@@ -222,7 +251,7 @@ namespace FastTunnel.Core {
///
/// Looks up a localized string similar to \n=====隧道已建立成功,现在可以通过以下方式访问您的内网服务了=====\n{0}\n.
///
- internal static string TunnelLlist {
+ public static string TunnelLlist {
get {
return ResourceManager.GetString("TunnelLlist", resourceCulture);
}
diff --git a/FastTunnel.Core/TunnelResource.resx b/FastTunnel.Core/TunnelResource.resx
index dfe9d82..de0b6c5 100644
--- a/FastTunnel.Core/TunnelResource.resx
+++ b/FastTunnel.Core/TunnelResource.resx
@@ -471,7 +471,7 @@
</html>
-
+
<!DOCTYPE html>
<html lang="en">
@@ -585,6 +585,122 @@
</footer>
</body>
+</html>
+
+
+ <!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>FastTunnel</title>
+ <link href="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
+ <style>
+ .err-info {
+ margin-top: 120px;
+ }
+
+ /* Provide sufficient contrast against white background */
+ a {
+ color: #0366d6;
+ }
+
+ .btn-primary {
+ color: #fff;
+ background-color: #1b6ec2;
+ border-color: #1861ac;
+ }
+
+ .nav-pills .nav-link.active,
+ .nav-pills .show>.nav-link {
+ color: #fff;
+ background-color: #1b6ec2;
+ border-color: #1861ac;
+ }
+
+ /* Sticky footer styles
+-------------------------------------------------- */
+ html {
+ font-size: 14px;
+ }
+
+ @media (min-width: 768px) {
+ html {
+ font-size: 16px;
+ }
+ }
+
+ .border-top {
+ border-top: 1px solid #e5e5e5;
+ }
+
+ .border-bottom {
+ border-bottom: 1px solid #e5e5e5;
+ }
+
+ .box-shadow {
+ box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
+ }
+
+ button.accept-policy {
+ font-size: 1rem;
+ line-height: inherit;
+ }
+
+ /* Sticky footer styles
+-------------------------------------------------- */
+ html {
+ position: relative;
+ min-height: 100%;
+ }
+
+ body {
+ /* Margin bottom by footer height */
+ margin-bottom: 60px;
+ }
+
+ .footer {
+ position: absolute;
+ bottom: 0;
+ width: 100%;
+ white-space: nowrap;
+ line-height: 60px;
+ /* Vertically center the text there */
+ }
+ </style>
+</head>
+
+<body>
+ <div class="container err-info">
+ <main role="main" class="pb-3">
+ <div class="text-center">
+ <h1 class="display-4">客户端已离线</h1>
+ <p>登录遇到问题? 去github提交<a target="_blank" href="https://github.com/SpringHgui/FastTunnel/issues">issue</a>给软件作者.
+ </p>
+ </div>
+
+ <blockquote style="padding-top: 4em;">
+ <p class="lead">您看到本页面表示当前隧道尚未登录,如果您是当前隧道地址的拥有者,请检查以下原因:</p>
+ </blockquote>
+ <ol>
+ <li class="lead">是否创建了当前子域名的隧道</li>
+ <li class="lead">是否在后台设置中禁用了当前隧道</li>
+ <li class="lead">是否启动了客户端并登录成功</li>
+ </ol>
+ <blockquote style="padding-top: 4em;">
+ <p class="lead">提醒:当前软件处于开发阶段,客户端版本可能会更新频繁,如遇到客户端异常,请登录<a target="_blank" href="https://suidao.io">suidao.io</a>下载最新的客户端重试。</p>
+ </blockquote>
+ </main>
+ </div>
+
+ <footer class="border-top footer text-muted">
+ <div class="container">
+ <a href="https://github.com/SpringHgui/FastTunnel" target="_blank">© Power By FastTunnel</a>
+ </div>
+ </footer>
+</body>
+
</html>
客户端未登录
diff --git a/FastTunnel.Server/FastTunnel.Server.csproj b/FastTunnel.Server/FastTunnel.Server.csproj
index 761339f..7001933 100644
--- a/FastTunnel.Server/FastTunnel.Server.csproj
+++ b/FastTunnel.Server/FastTunnel.Server.csproj
@@ -1,12 +1,5 @@
-
- net5.0
- c508b25f-0a51-4bab-b64c-8a7e993f24f6
- true
- Linux
-
-
@@ -29,12 +22,6 @@
-
- PreserveNewest
-
-
- PreserveNewest
-
Always
@@ -42,8 +29,4 @@
Always
-
-
-
-
diff --git a/FastTunnel.Server/Startup.cs b/FastTunnel.Server/Startup.cs
index 0aa9782..eab224e 100644
--- a/FastTunnel.Server/Startup.cs
+++ b/FastTunnel.Server/Startup.cs
@@ -1,10 +1,15 @@
using FastTunnel.Core;
+using FastTunnel.Core.Config;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
+using System.Threading;
+using System.Threading.Tasks;
namespace FastTunnel.Server
{
@@ -26,9 +31,9 @@ namespace FastTunnel.Server
c.SwaggerDoc("v2", new OpenApiInfo { Title = "FastTunel.Api", Version = "v2" });
});
- // -------------------FastTunnel START------------------
+ // -------------------FastTunnel STEP1 OF 3------------------
services.AddFastTunnelServer(Configuration.GetSection("ServerSettings"));
- // -------------------FastTunnel END--------------------
+ // -------------------FastTunnel STEP1 END--------------------
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -41,16 +46,18 @@ namespace FastTunnel.Server
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v2/swagger.json", "FastTunel.WebApi v2"));
}
- // -------------------FastTunnel START------------------
+ // -------------------FastTunnel STEP2 OF 3------------------
app.UseFastTunnelServer();
- // -------------------FastTunnel END--------------------
+ // -------------------FastTunnel STEP2 END--------------------
app.UseRouting();
app.UseEndpoints(endpoints =>
{
- endpoints.MapReverseProxy();
endpoints.MapControllers();
+ // -------------------FastTunnel STEP3 OF 3------------------
+ endpoints.MapFastTunnelServer();
+ // -------------------FastTunnel STEP3 END--------------------
});
}
}