GO配置反向代理

// 定义路由
admin.POST("/sms/query", ReverseProxy)

// 被指向的函数
func ReverseProxy(c *gin.Context) {
  // 拦截请求参数,body读取一次会自动close,需要重新赋值
  buf, _ := ioutil.ReadAll(c.Request.Body)
	c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(buf))

	// 为了通过request.FormValue() 获取参数,需要重新构建一个Request
	sourceRequest := http.Request{Method: "POST", Body: ioutil.NopCloser(bytes.NewBuffer(buf)),}
	sourceRequest.Header = http.Header{}
	sourceRequest.Header.Set("Content-Type", c.Request.Header.Get("Content-Type"))

	// request.FormValue() 会进行解析参数,如果需要调用Request.PostForm.Encode(),
  // 则需要调用此方法进行强行解析
	sourceRequest.ParseMultipartForm(32 << 20)

  // 设置反向代理参数
	var proxy = &httputil.ReverseProxy{
		Director: func(req *http.Request) {
			req.Header.Set("token", utils.GetProxyToken())
			req.URL.Scheme = utils.Config("proxy.url.scheme")
			req.URL.Host = utils.Config("proxy.url.host")
		},
	}

  // 修改返回信息
	proxy.ModifyResponse = func(response *http.Response) error {
		buf, err := ioutil.ReadAll(response.Body)
    //  body读取一次会自动close,需要重新赋值
		response.Body = ioutil.NopCloser(bytes.NewBuffer(buf))
		if err == nil {
      // 自己按自己的格式解析
			resp := &models.Response{}
			json.Unmarshal(buf, resp)

			if resp.RespCode == "1005" {
				response.StatusCode = 403
				response.Status = http.StatusText(403)

				str := "change after date"
				response.Body = ioutil.NopCloser(bytes.NewBufferString(str))
        // 新的Body与原body不一致,需要重新写入【重要,否则会出现:ERR_CONTENT_LENGTH_MISMATCH】
				response.Header.Set("Content-Length",strconv.Itoa(bytes.NewBufferString(str).Len()))
			}
		}
		return nil
	}
	proxy.ServeHTTP(c.Writer, c.Request)
}