mirror of
https://github.com/FastTunnel/FastTunnel.git
synced 2025-02-08 10:59:31 +08:00
添加Hosting项目
This commit is contained in:
parent
593f12d925
commit
634e10f16d
18
FastTunnel.Hosting/FastTunnel.Hosting.csproj
Normal file
18
FastTunnel.Hosting/FastTunnel.Hosting.csproj
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.0-preview.3.22175.4" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\FastTunnel.Core\FastTunnel.Core.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
39
FastTunnel.Hosting/FastTunnelHostingStartup.cs
Normal file
39
FastTunnel.Hosting/FastTunnelHostingStartup.cs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// 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.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using FastTunnel.Core.Extensions;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
|
||||||
|
[assembly: HostingStartup(typeof(FastTunnelHostingStartup))]
|
||||||
|
|
||||||
|
namespace FastTunnel.Hosting;
|
||||||
|
|
||||||
|
public class FastTunnelHostingStartup : IHostingStartup
|
||||||
|
{
|
||||||
|
public void Configure(IWebHostBuilder builder)
|
||||||
|
{
|
||||||
|
builder.ConfigureServices((webHostBuilderContext, services) =>
|
||||||
|
{
|
||||||
|
services.AddFastTunnelServer(webHostBuilderContext.Configuration.GetSection("FastTunnel"));
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.UseKestrel((context, options) =>
|
||||||
|
{
|
||||||
|
var basePort = context.Configuration.GetValue<int?>("FastTunnel:BASE_PORT") ?? 1270;
|
||||||
|
options.ListenAnyIP(basePort, listenOptions =>
|
||||||
|
{
|
||||||
|
listenOptions.UseConnectionFastTunnel();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Configure((webHostBuilderContext, app) =>
|
||||||
|
{
|
||||||
|
app.UseFastTunnelServer();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,76 +0,0 @@
|
||||||
// Licensed to the .NET Foundation under one or more agreements.
|
|
||||||
// The .NET Foundation licenses this file to you under the MIT license.
|
|
||||||
|
|
||||||
using System.Security.Cryptography.X509Certificates;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Connections.Features;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Http.Features;
|
|
||||||
using Microsoft.AspNetCore.WebUtilities;
|
|
||||||
|
|
||||||
namespace FastTunnel.Server;
|
|
||||||
|
|
||||||
internal static class ClientCertBufferingExtensions
|
|
||||||
{
|
|
||||||
// Buffers HTTP/1.x request bodies received over TLS (https) if a client certificate needs to be negotiated.
|
|
||||||
// This avoids the issue where POST data is received during the certificate negotiation:
|
|
||||||
// InvalidOperationException: Received data during renegotiation.
|
|
||||||
public static IApplicationBuilder UseClientCertBuffering(this IApplicationBuilder builder)
|
|
||||||
{
|
|
||||||
return builder.Use((context, next) =>
|
|
||||||
{
|
|
||||||
var tlsFeature = context.Features.Get<ITlsConnectionFeature>();
|
|
||||||
var bodyFeature = context.Features.Get<IHttpRequestBodyDetectionFeature>();
|
|
||||||
var connectionItems = context.Features.Get<IConnectionItemsFeature>();
|
|
||||||
|
|
||||||
// Look for TLS connections that don't already have a client cert, and requests that could have a body.
|
|
||||||
if (tlsFeature != null && tlsFeature.ClientCertificate == null && bodyFeature.CanHaveBody
|
|
||||||
&& !connectionItems.Items.TryGetValue("tls.clientcert.negotiated", out var _))
|
|
||||||
{
|
|
||||||
context.Features.Set<ITlsConnectionFeature>(new ClientCertBufferingFeature(tlsFeature, context));
|
|
||||||
}
|
|
||||||
|
|
||||||
return next(context);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class ClientCertBufferingFeature : ITlsConnectionFeature
|
|
||||||
{
|
|
||||||
private readonly ITlsConnectionFeature _tlsFeature;
|
|
||||||
private readonly HttpContext _context;
|
|
||||||
|
|
||||||
public ClientCertBufferingFeature(ITlsConnectionFeature tlsFeature, HttpContext context)
|
|
||||||
{
|
|
||||||
_tlsFeature = tlsFeature;
|
|
||||||
_context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public X509Certificate2 ClientCertificate
|
|
||||||
{
|
|
||||||
get => _tlsFeature.ClientCertificate;
|
|
||||||
set => _tlsFeature.ClientCertificate = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<X509Certificate2> GetClientCertificateAsync(CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
// Note: This doesn't set its own size limit for the buffering or draining, it relies on the server's
|
|
||||||
// 30mb default request size limit.
|
|
||||||
if (!_context.Request.Body.CanSeek)
|
|
||||||
{
|
|
||||||
_context.Request.EnableBuffering();
|
|
||||||
}
|
|
||||||
|
|
||||||
var body = _context.Request.Body;
|
|
||||||
await body.DrainAsync(cancellationToken);
|
|
||||||
body.Position = 0;
|
|
||||||
|
|
||||||
// Negative caching, prevent buffering on future requests even if the client does not give a cert when prompted.
|
|
||||||
var connectionItems = _context.Features.Get<IConnectionItemsFeature>();
|
|
||||||
connectionItems.Items["tls.clientcert.negotiated"] = true;
|
|
||||||
|
|
||||||
return await _tlsFeature.GetClientCertificateAsync(cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -36,7 +36,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\FastTunnel.Api\FastTunnel.Api.csproj" />
|
<ProjectReference Include="..\FastTunnel.Api\FastTunnel.Api.csproj" />
|
||||||
<ProjectReference Include="..\FastTunnel.Core\FastTunnel.Core.csproj" />
|
<ProjectReference Include="..\FastTunnel.Hosting\FastTunnel.Hosting.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -53,6 +53,9 @@ public class Program
|
||||||
.WriteTo.Console())
|
.WriteTo.Console())
|
||||||
.ConfigureWebHost(webHostBuilder =>
|
.ConfigureWebHost(webHostBuilder =>
|
||||||
{
|
{
|
||||||
|
webHostBuilder.UseKestrel();
|
||||||
|
webHostBuilder.UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "FastTunnel.Hosting");
|
||||||
|
|
||||||
webHostBuilder.ConfigureAppConfiguration((hostingContext, config) =>
|
webHostBuilder.ConfigureAppConfiguration((hostingContext, config) =>
|
||||||
{
|
{
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
|
@ -60,15 +63,6 @@ public class Program
|
||||||
.AddJsonFile($"config/appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"config/appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
webHostBuilder.UseKestrel((context, options) =>
|
|
||||||
{
|
|
||||||
var basePort = context.Configuration.GetValue<int?>("BASE_PORT") ?? 1270;
|
|
||||||
options.ListenAnyIP(basePort, listenOptions =>
|
|
||||||
{
|
|
||||||
listenOptions.UseConnectionFastTunnel();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
webHostBuilder.UseStartup<Startup>();
|
webHostBuilder.UseStartup<Startup>();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,10 +80,6 @@ public class Startup
|
||||||
c.SwaggerDoc("v2", new OpenApiInfo { Title = "FastTunel.Api", Version = "v2" });
|
c.SwaggerDoc("v2", new OpenApiInfo { Title = "FastTunel.Api", Version = "v2" });
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// -------------------FastTunnel STEP1 OF 3------------------
|
|
||||||
services.AddFastTunnelServer(Configuration.GetSection("FastTunnel"));
|
|
||||||
// -------------------FastTunnel STEP1 END-------------------
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
|
@ -98,10 +94,6 @@ public class Startup
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------FastTunnel STEP2 OF 3------------------
|
|
||||||
app.UseFastTunnelServer();
|
|
||||||
// -------------------FastTunnel STEP2 END-------------------
|
|
||||||
|
|
||||||
app.UseRouting();
|
app.UseRouting();
|
||||||
|
|
||||||
// --------------------- Custom UI ----------------
|
// --------------------- Custom UI ----------------
|
||||||
|
@ -113,9 +105,6 @@ public class Startup
|
||||||
app.UseEndpoints(endpoints =>
|
app.UseEndpoints(endpoints =>
|
||||||
{
|
{
|
||||||
endpoints.MapControllers();
|
endpoints.MapControllers();
|
||||||
// -------------------FastTunnel STEP3 OF 3------------------
|
});
|
||||||
//endpoints.MapFastTunnelServer();
|
|
||||||
// -------------------FastTunnel STEP3 END-------------------
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
// Http&客户端通讯端口
|
|
||||||
"BASE_PORT": 1270,
|
|
||||||
// 是否启用文件日志输出
|
// 是否启用文件日志输出
|
||||||
"EnableFileLog": false,
|
"EnableFileLog": false,
|
||||||
"FastTunnel": {
|
"FastTunnel": {
|
||||||
|
// Http&客户端通讯端口
|
||||||
|
"BASE_PORT": 1270,
|
||||||
// 可选,绑定的根域名,
|
// 可选,绑定的根域名,
|
||||||
// 客户端需配置SubDomain,实现 ${SubDomain}.${WebDomain}访问内网的站点,注意:需要通过域名访问网站时必选。
|
// 客户端需配置SubDomain,实现 ${SubDomain}.${WebDomain}访问内网的站点,注意:需要通过域名访问网站时必选。
|
||||||
"WebDomain": "test.cc",
|
"WebDomain": "test.cc",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user