gf-common/server/gateway.go

77 lines
2.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package server
import (
"fmt"
"io"
"net/http"
"net/http/httputil"
"net/url"
"time"
"git.magicany.cc/black1552/gf-common/log"
"github.com/gogf/gf/v2/net/gclient"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gcache"
"github.com/gogf/gf/v2/os/gctx"
)
func BuildRequest(r *ghttp.Request, host string) {
client := gclient.New()
// 构建目标URL而不是直接复制RequestURI
targetURL := host + r.URL.Path
if r.URL.RawQuery != "" {
targetURL += "?" + r.URL.RawQuery
}
// 复制请求头
for key, values := range r.Header {
for _, value := range values {
client.SetHeader(key, value)
}
}
response, err := client.DoRequest(gctx.New(), r.Method, targetURL, r.GetBody())
if err != nil {
log.Error(gctx.New(), "request error:", err)
panic(fmt.Sprintf("request error: %v", err))
}
defer response.Body.Close()
// 读取响应体
respBody, err := io.ReadAll(response.Body)
if err != nil {
log.Error(gctx.New(), "read response body error:", err)
panic(fmt.Sprintf("read response body error: %v", err))
}
// 复制响应头
for key, values := range response.Header {
for _, value := range values {
r.Response.Header().Add(key, value)
}
}
gcache.Set(gctx.New(), "host", host, 1*time.Second)
// 设置响应状态码并写入响应体
r.Response.Status = response.StatusCode
r.Response.Write(respBody)
}
// ProxyWebSocket 处理 WebSocket 连接的代理
func ProxyWebSocket(r *ghttp.Request, targetHost string) {
// 解析目标主机 URL
targetURL, err := url.Parse(targetHost)
if err != nil {
log.Error(gctx.New(), "parse target host error:", err)
r.Response.WriteStatus(http.StatusInternalServerError)
r.Response.Write([]byte("Invalid target host"))
return
}
// 创建反向代理
proxy := httputil.NewSingleHostReverseProxy(targetURL)
// 修改请求 URL保留原始路径和查询参数
r.URL.Scheme = targetURL.Scheme
r.URL.Host = targetURL.Host
log.Info(gctx.New(), r.GetBodyString())
// 处理 WebSocket 连接
proxy.ServeHTTP(r.Response.Writer, r.Request)
}