我是靠谱客的博主 名字长了才好记,最近开发中收集的这篇文章主要介绍golang实现了一个使用Gin框架的通用代理服务,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

这段代码实现了一个使用Gin框架的通用代理服务。这个代理服务根据请求的类型(GET或POST)将请求转发到不同的主机,同时附加上API key参数。以下是详细的代码解释及如何使用该代理服务的指南:

  1. 初始化与命令行参数

    • 使用flag包来解析命令行参数apikeyport

    • 检查是否提供了API key,如果未提供则退出程序。

  2. CORS中间件

    • 定义了一个CORS中间件,允许所有来源,处理跨域请求。

  3. 转发请求

    • 根据请求类型(GET或POST)将请求转发到相应的主机。

    • 对于POST请求,读取请求体并转发。

    • 在所有请求中添加api-key参数。

  4. 启动服务器

    • 使用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()
	}
}

使用指南:

  1. 编译并运行代码: 在终端中运行以下命令以编译并运行代理服务:

go build -o proxy
./proxy -apikey=YOUR_API_KEY -port=8080


  1. 发送请求

    • GET 请求:将被转发到https://api.helius.xyz,并附加api-key参数。

    • POST 请求:将被转发到https://mainnet.helius-rpc.com,并附加api-key参数,且包含请求体。

这样,你的代理服务就可以根据请求的类型和路径,将请求转发到不同的目标主机,并附加API key以进行身份验证。


最后

以上就是名字长了才好记为你收集整理的golang实现了一个使用Gin框架的通用代理服务的全部内容,希望文章能够帮你解决golang实现了一个使用Gin框架的通用代理服务所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(263)

评论列表共有 0 条评论

立即
投稿
返回
顶部