目录:
- 一、创建资源服务器(RealServer)
- 二、创建代理服务器(Proxy)
- 三、测试
** 一、创建资源服务器(RealServer)**
type RealServer struct {
Addr string
}
func (r *RealServer) Run() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
req.Header.Set("X-Forwarded-For", req.RemoteAddr)
backend := fmt.Sprintf("Backend=http://%s%s?%s\n", r.Addr, req.URL.Path, req.URL.RawQuery)
realIP := fmt.Sprintf("RemoteAddr=%s,X-Forwarded-For=%v,X-Real-Ip=%v\n", req.RemoteAddr, req.Header.Get("X-Forwarded-For"), req.Header.Get("X-Real-Ip"))
header := fmt.Sprintf("Headers =%v\n", req.Header)
io.WriteString(rw, backend)
io.WriteString(rw, realIP)
io.WriteString(rw, header)
})
mux.HandleFunc("/error", func(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(500)
io.WriteString(rw, "error handler")
})
server := &http.Server{Addr: r.Addr, Handler: mux, WriteTimeout: time.Second * 3}
go func() {
log.Fatal(server.ListenAndServe())
}()
log.Println("Starting httpserver at " + r.Addr)
}
func main() {
server1 := &RealServer{Addr: "172.*.*.249:8081"}
server2 := &RealServer{Addr: "172.*.*.249:6061"}
server1.Run()
server2.Run()
//监听关闭信号
quit := make(chan os.Signal)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
}
二、创建代理服务器(Proxy)
var realAddr, proxyAddr = "http://172.*.*.248:8081", "172.*.*.249:3000"
func ProxyHandler(rw http.ResponseWriter, req *http.Request) {
// 0.浅拷贝请求对象组装新请求体
var newReq = new(http.Request)
*newReq = *req
proxy, _ := url.Parse(realAddr)
newReq.URL.Scheme = proxy.Scheme
newReq.URL.Host = proxy.Host
newReq.Header.Set("X-Real-Ip", proxy.Host)
// 1.请求后端资源
transport := http.DefaultTransport
resp, err := transport.RoundTrip(newReq)
// 2.回写客户端
if err != nil {
rw.WriteHeader(http.StatusBadGateway)
log.Println(err)
return
}
defer resp.Body.Close()
for k, v := range resp.Header {
for _, vv := range v {
rw.Header().Add(k, vv)
}
}
io.Copy(rw, resp.Body) // 或者bufio.NewReader(resp.Body).WriteTo(rw)
}
func main() {
http.HandleFunc("/", ProxyHandler)
log.Print("start proxy server on: ", proxyAddr)
log.Fatal(http.ListenAndServe(proxyAddr, nil))
}
三、测试