zoukankan      html  css  js  c++  java
  • golang gin 代理和改包

    说明

    目前仅支持http协议,其他协议需要用socket
    使用 gin 做客户端和服务端的中间代理

    快速搭建环境

    • 创建项目文件夹

    创建 ginProxy 文件夹后,进入该文件夹

    mkdir ginProxy
    cd ginProxy
    
    • 初始化mod

    ginProxy 为包的名称,在该目录下会生成 go.mod 文件

    go mod init ginProxy
    
    • 下载安装 gin 框架

    参数 -u 为本地有该包就更新,没有则下载

    go get -u github.com/gin-gonic/gin
    
    • 实现 gin 的 hello world

    参考gin文档

    gin 实现代理

    代理实现有多种方式

    • 直接代理

    不做任何修改,直接发往目标服务器
    client --> request --> gin --> gin_request --> service --> gin_response --> gin --> response --> client

    • 修改代理

    修改请求内容再发往目标服务器,收到返回内容修改后再返回给客户端
    client --> request --> gin --> modify_request --> gin_request --> service --> gin_response --> gin --> modify_response --> response --> client

    • 返回代理

    直接返回给客户端,不经过目标服务器,类似私服模式
    这个就是传统的请求和回应,把代理当目标服务器
    client --> request --> gin --> response --> client

    直接代理

    不做任何修改,直接把原始请求给代理请求 request = c.Request
    c.Request 为 客户端发给 gin 的请求
    request为 gin 向目标服务器的请求

    router.POST("/test01", func(c *gin.Context) {
          proxy := httputil.ReverseProxy{Director: func(request *http.Request) {
    		request = c.Request
    	}}
    	proxy.ServeHTTP(c.Writer, c.Request)
    })
    

    修改代理

    • 修改请求头

    获取请求头

    c.GetHeader("sn")
    

    修改请求头

    c.Request.Header.Set("sn","123456789")
    
    • 修改请求体

    如果加密了需要先解密,修改后再加密
    首先需要查看 body 的类型为 io.ReadCloser类型

    Body io.ReadCloser
    

    这里有个知识点:post 的 body 数据不是和 header 一起发送的,是分开来发送的。get 是一起发送的
    所以需要把 body 数据给读取过来,存到内存中
    接着对 body 数据进行操作,读完就可以关闭了

    body,err := ioutil.ReadAll(c.Request.Body)
    if err != nil{
    	panic(err)
    }
    
    if err := c.Request.Body.Close(); err != nil{
          panic(err)
    }
    
    // 对 body 数据进行操作
    

    对数据操作完之后,需要把数据发送给目标服务器,即创建 io.ReadCloser
    等待服务端读取内存中的数据
    也就是说每次请求响应的数据都要存到内存中,比较费内存

    c.Request.Body = ioutil.NopCloser(bytes.NewReader(body))
    
    • 修改响应头

    如果加密了需要先解密,修改后再加密
    目标服务器返回后的回调,response 即为目标服务器的响应

    proxy.ModifyResponse = func(response *http.Response) error {
          // 修改返回给客户端的 response
          return nil
    }
    

    响应头和响应体的修改和上面请求的一样,把请求改为响应
    比如获取响应头

    response.Header.Get("k")
    

    比如设置响应头

    response.Header.Set("sn","123456789")
    

    返回代理

    标准的请求返回,查看 gin 文档
    主要就是返回的内容要符合客户端的加密解密操作

    git项目地址

  • 相关阅读:
    iMac中的GoLand中报错: Unresolved reference 错误解决方法
    设置初次ssh登录linux的时候无需yes确认登陆
    docker命令常用总结
    阿里巴巴-菜鸟网络高级java开发工程师/技术专家招聘
    mysql8.0.22 设置sql_mode后不能启动解决
    《事实》读后感
    VPS是什么?
    做了一个小程序,欢迎关注
    [Linux] Tomcat java.lang.OutOfMemoryError: Java heap space
    [Linux] Nginx 反向代理配置 http headers 带下划线fields转发
  • 原文地址:https://www.cnblogs.com/GH-123/p/13566789.html
Copyright © 2011-2022 走看看