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)
}