这段代码实现了一个使用Gin框架的通用代理服务。这个代理服务根据请求的类型(GET或POST)将请求转发到不同的主机,同时附加上API key参数。以下是详细的代码解释及如何使用该代理服务的指南:
初始化与命令行参数:
使用
flag包来解析命令行参数apikey和port。检查是否提供了API key,如果未提供则退出程序。
CORS中间件:
定义了一个CORS中间件,允许所有来源,处理跨域请求。
转发请求:
根据请求类型(GET或POST)将请求转发到相应的主机。
对于POST请求,读取请求体并转发。
在所有请求中添加
api-key参数。启动服务器:
使用Gin框架启动服务器并监听指定端口。
以下是完整的代码,附加了详细的注释以便于理解:
package main
import (
"bytes"
"flag"
"fmt"
"github.com/gin-gonic/gin"
"io"
"net/http"
"net/url"
"os"
)
var apiKey string
var port string
// 初始化函数,用于解析命令行参数
func init() {
flag.StringVar(&apiKey, "apikey", "", "API key for the Helius service")
flag.StringVar(&port, "port", "8080", "Port to run the server on")
flag.Parse()
// 检查是否提供了 apiKey
if apiKey == "" {
println("Error: API key is required")
os.Exit(1)
}
}
func main() {
r := gin.Default()
r.Use(corsMiddleware())
// 处理 GET 请求
r.GET("/*path", func(c *gin.Context) {
forwardRequest(c, http.MethodGet)
})
// 处理 POST 请求
r.POST("/*path", func(c *gin.Context) {
forwardRequest(c, http.MethodPost)
})
if err := r.Run(":" + port); err != nil {
println("Error: API key is required")
os.Exit(1)
}
}
// 转发请求函数
func forwardRequest(c *gin.Context, method string) {
path := c.Param("path")
rawQuery := c.Request.URL.RawQuery
// 根据请求方法选择主机
host := "https://api.helius.xyz"
if method != http.MethodGet {
host = "https://mainnet.helius-rpc.com"
}
// 构建基本 URL
base, err := url.Parse(host + path)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to parse URL"})
return
}
// 解析查询参数
var params url.Values
if params, err = url.ParseQuery(rawQuery); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to parse query parameters"})
return
}
// 添加 api-key 参数
params.Add("api-key", apiKey)
// 构建最终 URL
base.RawQuery = params.Encode()
fullURL := base.String()
fmt.Println("fullURL", fullURL)
// 创建请求
var req *http.Request
if method == http.MethodGet {
req, err = http.NewRequest(method, fullURL, nil)
} else if method == http.MethodPost {
body, err := io.ReadAll(c.Request.Body)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to read request body"})
return
}
req, err = http.NewRequest(method, fullURL, io.NopCloser(bytes.NewBuffer(body)))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to new request"})
return
}
req.Header.Set("Content-Type", c.Request.Header.Get("Content-Type"))
}
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create request"})
return
}
// 执行请求
var resp *http.Response
if resp, err = http.DefaultClient.Do(req); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to execute request"})
return
}
defer resp.Body.Close()
// 读取响应
var body []byte
if body, err = io.ReadAll(resp.Body); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to read response"})
return
}
c.Data(resp.StatusCode, resp.Header.Get("Content-Type"), body)
}
// CORS 中间件函数
func corsMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
c.Writer.Header().Set("Access-Control-Allow-Headers", "*")
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE, PATCH")
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}
c.Next()
}
}使用指南:
编译并运行代码: 在终端中运行以下命令以编译并运行代理服务:
go build -o proxy ./proxy -apikey=YOUR_API_KEY -port=8080
发送请求:
GET 请求:将被转发到
https://api.helius.xyz,并附加api-key参数。POST 请求:将被转发到
https://mainnet.helius-rpc.com,并附加api-key参数,且包含请求体。
这样,你的代理服务就可以根据请求的类型和路径,将请求转发到不同的目标主机,并附加API key以进行身份验证。
最后
以上就是名字长了才好记最近收集整理的关于golang实现了一个使用Gin框架的通用代理服务的全部内容,更多相关golang实现了一个使用Gin框架内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复