From 54be8fc8b28fe89bb19315f24625869615106328 Mon Sep 17 00:00:00 2001
From: token <239573049@qq.com>
Date: Thu, 25 Jan 2024 19:57:51 +0800
Subject: [PATCH 1/7] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=83=A8=E5=88=86?=
=?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Gateway.sln | 21 +++
src/Gateway.Client/Gateway.Client.csproj | 19 +++
src/Gateway.Client/Gateway.Client.http | 11 ++
src/Gateway.Client/Program.cs | 15 ++
.../Properties/launchSettings.json | 12 ++
.../appsettings.Development.json | 8 +
src/Gateway.Client/appsettings.json | 31 ++++
src/Gateway/Gateway.csproj | 4 +
src/Gateway/Program.cs | 8 +
.../Transport/HttpClientConnectionContext.cs | 124 ++++++++++++++
.../TrackLifetimeConnectionContext.cs | 73 +++++++++
.../Transport/TunnelConnectionListener.cs | 118 ++++++++++++++
.../TunnelConnectionListenerFactory.cs | 18 +++
src/Tunnel.Client/Transport/TunnelOptions.cs | 12 ++
src/Tunnel.Client/Transport/UriEndpoint2.cs | 17 ++
.../Transport/WebHostBuilderExtensions.cs | 26 +++
.../Transport/WebSocketConnectionContext.cs | 64 ++++++++
src/Tunnel.Client/Tunnel.Client.csproj | 14 ++
src/Tunnel.Server/Tunnel.Server.csproj | 13 ++
.../Tunnel/ConnectionContextStream.cs | 152 ++++++++++++++++++
src/Tunnel.Server/Tunnel/DuplexHttpStream.cs | 107 ++++++++++++
src/Tunnel.Server/Tunnel/ICloseable.cs | 5 +
.../Tunnel/TunnelClientFactory.cs | 69 ++++++++
src/Tunnel.Server/Tunnel/TunnelExensions.cs | 107 ++++++++++++
src/Tunnel.Server/Tunnel/WebSocketStream.cs | 136 ++++++++++++++++
25 files changed, 1184 insertions(+)
create mode 100644 src/Gateway.Client/Gateway.Client.csproj
create mode 100644 src/Gateway.Client/Gateway.Client.http
create mode 100644 src/Gateway.Client/Program.cs
create mode 100644 src/Gateway.Client/Properties/launchSettings.json
create mode 100644 src/Gateway.Client/appsettings.Development.json
create mode 100644 src/Gateway.Client/appsettings.json
create mode 100644 src/Tunnel.Client/Transport/HttpClientConnectionContext.cs
create mode 100644 src/Tunnel.Client/Transport/TrackLifetimeConnectionContext.cs
create mode 100644 src/Tunnel.Client/Transport/TunnelConnectionListener.cs
create mode 100644 src/Tunnel.Client/Transport/TunnelConnectionListenerFactory.cs
create mode 100644 src/Tunnel.Client/Transport/TunnelOptions.cs
create mode 100644 src/Tunnel.Client/Transport/UriEndpoint2.cs
create mode 100644 src/Tunnel.Client/Transport/WebHostBuilderExtensions.cs
create mode 100644 src/Tunnel.Client/Transport/WebSocketConnectionContext.cs
create mode 100644 src/Tunnel.Client/Tunnel.Client.csproj
create mode 100644 src/Tunnel.Server/Tunnel.Server.csproj
create mode 100644 src/Tunnel.Server/Tunnel/ConnectionContextStream.cs
create mode 100644 src/Tunnel.Server/Tunnel/DuplexHttpStream.cs
create mode 100644 src/Tunnel.Server/Tunnel/ICloseable.cs
create mode 100644 src/Tunnel.Server/Tunnel/TunnelClientFactory.cs
create mode 100644 src/Tunnel.Server/Tunnel/TunnelExensions.cs
create mode 100644 src/Tunnel.Server/Tunnel/WebSocketStream.cs
diff --git a/Gateway.sln b/Gateway.sln
index 840a100..e46a93c 100644
--- a/Gateway.sln
+++ b/Gateway.sln
@@ -4,6 +4,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gateway", "src\Gateway\Gate
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{9BBA9B8C-370F-4334-9E88-D5B246139818}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gateway.Client", "src\Gateway.Client\Gateway.Client.csproj", "{D8869D80-CD5A-44C2-905E-58703A80EAE6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tunnel.Client", "src\Tunnel.Client\Tunnel.Client.csproj", "{20FA848D-CBC1-43B4-8905-00DE19911E3E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tunnel.Server", "src\Tunnel.Server\Tunnel.Server.csproj", "{4A2A054F-ED58-4EC3-96A6-57C71CA371FD}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -14,8 +20,23 @@ Global
{5239265F-7E74-4345-91B2-3EE96EC181EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5239265F-7E74-4345-91B2-3EE96EC181EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5239265F-7E74-4345-91B2-3EE96EC181EF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D8869D80-CD5A-44C2-905E-58703A80EAE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D8869D80-CD5A-44C2-905E-58703A80EAE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D8869D80-CD5A-44C2-905E-58703A80EAE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D8869D80-CD5A-44C2-905E-58703A80EAE6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {20FA848D-CBC1-43B4-8905-00DE19911E3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {20FA848D-CBC1-43B4-8905-00DE19911E3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {20FA848D-CBC1-43B4-8905-00DE19911E3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {20FA848D-CBC1-43B4-8905-00DE19911E3E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4A2A054F-ED58-4EC3-96A6-57C71CA371FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4A2A054F-ED58-4EC3-96A6-57C71CA371FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4A2A054F-ED58-4EC3-96A6-57C71CA371FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4A2A054F-ED58-4EC3-96A6-57C71CA371FD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{5239265F-7E74-4345-91B2-3EE96EC181EF} = {9BBA9B8C-370F-4334-9E88-D5B246139818}
+ {D8869D80-CD5A-44C2-905E-58703A80EAE6} = {9BBA9B8C-370F-4334-9E88-D5B246139818}
+ {20FA848D-CBC1-43B4-8905-00DE19911E3E} = {9BBA9B8C-370F-4334-9E88-D5B246139818}
+ {4A2A054F-ED58-4EC3-96A6-57C71CA371FD} = {9BBA9B8C-370F-4334-9E88-D5B246139818}
EndGlobalSection
EndGlobal
diff --git a/src/Gateway.Client/Gateway.Client.csproj b/src/Gateway.Client/Gateway.Client.csproj
new file mode 100644
index 0000000..d68f045
--- /dev/null
+++ b/src/Gateway.Client/Gateway.Client.csproj
@@ -0,0 +1,19 @@
+
+
+
+ net8.0
+ enable
+ enable
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Gateway.Client/Gateway.Client.http b/src/Gateway.Client/Gateway.Client.http
new file mode 100644
index 0000000..07c76c6
--- /dev/null
+++ b/src/Gateway.Client/Gateway.Client.http
@@ -0,0 +1,11 @@
+@Gateway.Client_HostAddress = http://localhost:5160
+
+GET {{Gateway.Client_HostAddress}}/todos/
+Accept: application/json
+
+###
+
+GET {{Gateway.Client_HostAddress}}/todos/1
+Accept: application/json
+
+###
diff --git a/src/Gateway.Client/Program.cs b/src/Gateway.Client/Program.cs
new file mode 100644
index 0000000..5493a3e
--- /dev/null
+++ b/src/Gateway.Client/Program.cs
@@ -0,0 +1,15 @@
+var builder = WebApplication.CreateBuilder(args);
+
+builder.Services.AddReverseProxy()
+ .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
+
+// This is the HTTP/2 endpoint to register this app as part of the cluster endpoint
+var url = builder.Configuration["Tunnel:Url"]!;
+
+builder.WebHost.UseTunnelTransport(url);
+
+var app = builder.Build();
+
+app.MapReverseProxy();
+
+app.Run();
\ No newline at end of file
diff --git a/src/Gateway.Client/Properties/launchSettings.json b/src/Gateway.Client/Properties/launchSettings.json
new file mode 100644
index 0000000..5d00c86
--- /dev/null
+++ b/src/Gateway.Client/Properties/launchSettings.json
@@ -0,0 +1,12 @@
+{
+ "profiles": {
+ "Frontend": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "applicationUrl": "https://localhost:7244;http://localhost:5244",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+}}
diff --git a/src/Gateway.Client/appsettings.Development.json b/src/Gateway.Client/appsettings.Development.json
new file mode 100644
index 0000000..0c208ae
--- /dev/null
+++ b/src/Gateway.Client/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/src/Gateway.Client/appsettings.json b/src/Gateway.Client/appsettings.json
new file mode 100644
index 0000000..371f774
--- /dev/null
+++ b/src/Gateway.Client/appsettings.json
@@ -0,0 +1,31 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*",
+ "Tunnel": {
+ "Url": "http://localhost:8080/connect-h2?host=try.token-ai.cn"
+ },
+ "ReverseProxy": {
+ "Routes": {
+ "route1": {
+ "ClusterId": "cluster1",
+ "Match": {
+ "Path": "{**catch-all}"
+ }
+ }
+ },
+ "Clusters": {
+ "cluster1": {
+ "Destinations": {
+ "cluster1/destination1": {
+ "Address": "https://cn.bing.com/"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/Gateway/Gateway.csproj b/src/Gateway/Gateway.csproj
index fd4ccfe..feac1b3 100644
--- a/src/Gateway/Gateway.csproj
+++ b/src/Gateway/Gateway.csproj
@@ -20,4 +20,8 @@
+
+
+
+
diff --git a/src/Gateway/Program.cs b/src/Gateway/Program.cs
index a74580b..3a9391b 100644
--- a/src/Gateway/Program.cs
+++ b/src/Gateway/Program.cs
@@ -135,6 +135,7 @@ builder.Services.AddSingleton();
builder.Services.AddSingleton();
builder.Services.AddSingleton(freeSql);
+builder.Services.AddTunnelServices();
// 使用内存加载配置
builder.Services.AddReverseProxy()
@@ -161,6 +162,13 @@ app.MapNetWork();
// 添加自定义授权
app.UseCustomAuthentication();
+// Uncomment to support websocket connections
+app.MapWebSocketTunnel("/connect-ws");
+
+// Auth can be added to this endpoint and we can restrict it to certain points
+// to avoid exteranl traffic hitting it
+app.MapHttp2Tunnel("/connect-h2");
+
app.UseAuthentication();
app.UseAuthorization();
diff --git a/src/Tunnel.Client/Transport/HttpClientConnectionContext.cs b/src/Tunnel.Client/Transport/HttpClientConnectionContext.cs
new file mode 100644
index 0000000..a166145
--- /dev/null
+++ b/src/Tunnel.Client/Transport/HttpClientConnectionContext.cs
@@ -0,0 +1,124 @@
+using System.IO.Pipelines;
+using System.Net;
+using Microsoft.AspNetCore.Connections;
+using Microsoft.AspNetCore.Connections.Features;
+using Microsoft.AspNetCore.Http.Features;
+
+internal class HttpClientConnectionContext : ConnectionContext,
+ IConnectionLifetimeFeature,
+ IConnectionEndPointFeature,
+ IConnectionItemsFeature,
+ IConnectionIdFeature,
+ IConnectionTransportFeature,
+ IDuplexPipe
+{
+ private readonly TaskCompletionSource _executionTcs = new(TaskCreationOptions.RunContinuationsAsynchronously);
+
+ private HttpClientConnectionContext()
+ {
+ Transport = this;
+
+ Features.Set(this);
+ Features.Set(this);
+ Features.Set(this);
+ Features.Set(this);
+ Features.Set(this);
+ }
+
+ public Task ExecutionTask => _executionTcs.Task;
+
+ public override string ConnectionId { get; set; } = Guid.NewGuid().ToString();
+
+ public override IFeatureCollection Features { get; } = new FeatureCollection();
+
+ public override IDictionary