diff --git a/proxy/config.go b/proxy/config.go new file mode 100644 index 0000000..925b206 --- /dev/null +++ b/proxy/config.go @@ -0,0 +1,20 @@ +// Package proxy ... +// +// Description : 代理转发的配置 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-08-06 3:34 下午 +package proxy + +// Server 服务器配置 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 3:34 下午 2021/8/6 +type Server struct { + Scheme string // 转发scheme + Host string // 服务器地址 + URI string // 转发接口 + RewriteHeader map[string]string // 重写header +} diff --git a/proxy/forward.go b/proxy/forward.go new file mode 100644 index 0000000..e0a531f --- /dev/null +++ b/proxy/forward.go @@ -0,0 +1,66 @@ +// Package proxy... +// +// Description : 正向代理的实现 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-08-06 2:07 下午 +package proxy + +import ( + "fmt" + "io" + "net" + "net/http" + "strings" +) + +// Forward 正向代理的实现 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2:08 下午 2021/8/6 +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 + + // 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 + for k, v := range serverConfig.RewriteHeader { + outReq.Header.Set(k, v) + } + + // 重写请求地址 + outReq.Host = serverConfig.Host + outReq.URL.Path = serverConfig.URI + outReq.URL.Scheme = serverConfig.Scheme + outReq.URL.Host = serverConfig.Host + // 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 { + rw.Header().Add(key, v) + } + } + + rw.WriteHeader(res.StatusCode) + io.Copy(rw, res.Body) + res.Body.Close() +}