看到一个文章[Go] 不到 100 行代码实现一个支持 CONNECT 动词的 HTTP 服务器
在NET8中如何实现
创建项目为MiniApi
编辑Program.cs
文件。
var builder = WebApplication.CreateSlimBuilder(args);
var app = builder.Build();
// 将HTTP请求通过协议升级机制转为远程TCP请求(WebSocket分支,Nginx支持)
app.Map("/http2tcp", async (context) =>
{
var upgradeFeature = context.Features.Get<Microsoft.AspNetCore.Http.Features.IHttpUpgradeFeature>();
if (upgradeFeature != null)
{
context.Features.Get<Microsoft.AspNetCore.Http.Timeouts.IHttpRequestTimeoutFeature>()?.DisableTimeout();
context.Response.Headers.Connection = Microsoft.Net.Http.Headers.HeaderNames.Upgrade;
context.Response.Headers.Upgrade = "http2tcp/1.0";
Stream stream = await upgradeFeature.UpgradeAsync();
using System.Net.Sockets.TcpClient tcpClient = new System.Net.Sockets.TcpClient();
await tcpClient.ConnectAsync(System.Net.IPEndPoint.Parse("127.0.0.1:1000"));
using System.Net.Sockets.NetworkStream network = tcpClient.GetStream();
var taskX = network.CopyToAsync(stream);
var tsakY = stream.CopyToAsync(network);
Task.WaitAny(taskX, tsakY);
}
});
// 将HTTP请求通过CONNECT方法转为TCP请求(CONNECT分支)主流浏览器都支持 https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/CONNECT
app.MapMethods("", new[] { HttpMethods.Connect }, async (context) =>
{
var auth = context.Request.Headers["Proxy-Authorization"];
await context.Response.Body.FlushAsync();
var socket = context.Features.Get<Microsoft.AspNetCore.Connections.Features.IConnectionSocketFeature>()!.Socket;
var stream = new System.Net.Sockets.NetworkStream(socket);
using var tcpClient = new System.Net.Sockets.TcpClient();
await tcpClient.ConnectAsync(System.Net.IPEndPoint.Parse(context.Request.Host.Value));
using var network = tcpClient.GetStream();
var taskX = network.CopyToAsync(stream);
var tsakY = stream.CopyToAsync(network);
Task.WaitAny(taskX, tsakY);
});
app.Run();