优化反向代理的实现

This commit is contained in:
白茶清欢 2021-12-26 13:55:10 +08:00
parent 4b62cd2d57
commit daae6a16d4

View File

@ -8,13 +8,11 @@
package proxy package proxy
import ( import (
"bytes"
"compress/gzip" "compress/gzip"
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"net"
"net/http" "net/http"
"net/http/httputil"
"strings" "strings"
) )
@ -24,72 +22,30 @@ import (
// //
// Date : 2:08 下午 2021/8/6 // Date : 2:08 下午 2021/8/6
func Forward(rw http.ResponseWriter, req *http.Request, serverConfig *Server) { func Forward(rw http.ResponseWriter, req *http.Request, serverConfig *Server) {
fmt.Printf("Received request %s %s %s\n", req.Method, req.Host, req.RemoteAddr)
transport := http.DefaultTransport if !strings.HasPrefix(serverConfig.URI, "/") {
serverConfig.URI = "/" + serverConfig.URI
// step 1
outReq := new(http.Request)
*outReq = *req // this only does shallow copies of maps
if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
if prior, ok := outReq.Header["X-Forwarded-For"]; ok {
clientIP = strings.Join(prior, ", ") + ", " + clientIP
}
outReq.Header.Set("X-Forwarded-For", clientIP)
} }
// 请求重写方法
// 写入重写的请求Header director := func(req *http.Request) {
for k, v := range serverConfig.RewriteRequestHeader { req.URL.Scheme = serverConfig.Scheme
outReq.Header.Set(k, v) // req.URL.Host = projectDetail.GetProjectDetail().Domain + ":" + fmt.Sprintf("%v", projectDetail.GetProjectDetail().Port)
} // req.Host = projectDetail.GetProjectDetail().Domain + ":" + fmt.Sprintf("%v", projectDetail.GetProjectDetail().Port)
req.Host = serverConfig.Host
// 重写请求地址 req.URL.Host = serverConfig.Host
outReq.Host = serverConfig.Host req.URL.Path = serverConfig.URI
outReq.URL.Path = serverConfig.URI req.RequestURI = serverConfig.URI
outReq.URL.Scheme = serverConfig.Scheme // 写入重写的请求Header
outReq.URL.Host = serverConfig.Host for k, v := range serverConfig.RewriteRequestHeader {
req.Header.Set(k, v)
// step 2
res, err := transport.RoundTrip(outReq)
if err != nil {
rw.WriteHeader(http.StatusBadGateway)
return
}
// step 3
for key, value := range res.Header {
for _, v := range value {
if strings.ToLower(key) == "content-encoding" {
continue
}
rw.Header().Add(key, v)
} }
} }
// TODO : 重写响应数据
rw.WriteHeader(res.StatusCode) modifyResponseFunc := func(rep *http.Response) error {
return nil
// 重写请求header
for k, v := range serverConfig.RewriteResponseHeader {
rw.Header().Set(k, v)
} }
p := &httputil.ReverseProxy{Director: director, ModifyResponse: modifyResponseFunc}
defer res.Body.Close() p.ServeHTTP(rw, req)
// 重写响应数据
if !strings.Contains(strings.ToLower(res.Header.Get("Content-Type")), "application/json") || nil == serverConfig.RewriteResponseData || len(serverConfig.RewriteResponseData) == 0 {
_, _ = io.Copy(rw, res.Body)
return
}
var (
responseData []byte
)
responseData, err = getResponseData(res)
fmt.Println(string(responseData), err)
bytesBuffer := bytes.NewReader([]byte(`{"data":{"permission":true}}`))
_, _ = io.Copy(rw, bytesBuffer)
} }
// getResultCompressType 获取返回结果的压缩方式 // getResultCompressType 获取返回结果的压缩方式