cloudwego / hertz

Go HTTP framework with high-performance and strong-extensibility for building micro-services.
https://www.cloudwego.io
Apache License 2.0
5.28k stars 515 forks source link

支持CONNECT方法 #1170

Open laixiaohuai opened 2 months ago

laixiaohuai commented 2 months ago

Is your feature request related to a problem? Please describe. 1、api.proto不支持 connect方法 2、server.Hertz不支持 connect方法 3、adaptor不支持 connect方法,报错:interface conversion: *adaptor.compatResponse is not http.Hijacker: missing method Hijack

A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like

A clear and concise description of what you want to happen.

Describe alternatives you've considered

A clear and concise description of any alternative solutions or features you've considered.

Additional context

Add any other context or screenshots about the feature request here.

welkeyever commented 1 month ago

对,Connect 不是原生支持,不过可以自己搞,fyi:

在 Hertz 中,如果你需要处理 HTTP CONNECT 方法,可以遵循以下步骤:

  1. 检查请求方法是否为 CONNECT:使用 RequestHeader.IsConnect 方法检查请求方法。
  2. 处理 CONNECT 方法:如果请求方法是 CONNECT,则执行相应的处理逻辑,如建立隧道连接。

示例代码

以下是一个完整的示例代码,展示了如何在 Hertz 中处理 HTTP CONNECT 方法:

package main

import (
    "context"
    "github.com/cloudwego/hertz/pkg/app"
    "github.com/cloudwego/hertz/pkg/app/server"
    "github.com/cloudwego/hertz/pkg/common/hlog"
)

func main() {
    h := server.Default(server.WithHostPorts("127.0.0.1:8080"))

    h.NoRoute(func(c context.Context, ctx *app.RequestContext) {
        if ctx.Request.Header.IsConnect() {
            handleConnect(c, ctx)
        } else {
            ctx.JSON(404, map[string]string{"message": "Not Found"})
        }
    })

    h.Spin()
}

func handleConnect(c context.Context, ctx *app.RequestContext) {
    hlog.Info("Handling CONNECT method")

    // 获取目标地址
    target := string(ctx.Request.RequestURI())
    hlog.Infof("Target address: %s", target)

    // 你可以在这里添加自定义的连接处理逻辑,比如建立隧道连接
    // 以下是一个简单的响应示例
    ctx.Response.SetStatusCode(200)
    ctx.Response.Header.Set("Content-Type", "text/plain")
    ctx.Response.SetBody([]byte("CONNECT method handled"))
}

关键点

  1. h.NoRoute:用于处理未匹配到任何路由的请求。
  2. ctx.Request.Header.IsConnect():检查请求方法是否为 CONNECT
  3. handleConnect 函数:处理 CONNECT 方法的逻辑,包括获取目标地址和自定义连接处理逻辑。