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-------------------- }); } }