访问http://localhost:2002可代理"www.example.com"这个网站,为使实现效果明显,这里将http响应的body直接改成“hello,world”,如果不想修改响应内容,只做代理,可以修改proxy.ModifyResponse方法。需要注意:如果修改http响应的body,需要考虑是否需要将修改后的body压缩,其次要修改content-length。
代码:
var proxy_addr = "www.example.com"
var port = "2002"
func ReverseProxyHandler(w http.ResponseWriter, r *http.Request) {
fmt.Printf("receive a request from %s,request header: %s: \n", r.RemoteAddr, r.Header)
director := func(req *http.Request) {
req.URL.Scheme = "http"
req.URL.Host = proxy_addr
req.Host = proxy_addr
}
proxy := &httputil.ReverseProxy{Director: director}
proxy.ModifyResponse = func(resp *http.Response) error {
fmt.Printf("start ModifyResponse\n")
var b bytes.Buffer
gz := gzip.NewWriter(&b)
if _, err := gz.Write([]byte("hello, world")); err != nil {
panic(err)
}
if err := gz.Flush(); err != nil {
panic(err)
}
if err := gz.Close(); err != nil {
panic(err)
}
resp.Header.Set("Content-Length", fmt.Sprint(len(b.Bytes())))
resp.Body = ioutil.NopCloser(bytes.NewBuffer(b.Bytes()))
resp.ContentLength = int64(len(b.Bytes()))
return nil
}
proxy.ServeHTTP(w, r)
fmt.Printf("receive the destination website response header: %s\n", w.Header())
}
func TestProxy(t *testing.T) {
// handle all requests to your server using the proxy
// 测试代理流程
fmt.Println("Start serving on port " + port)
err := http.ListenAndServe(":"+port, http.HandlerFunc(ReverseProxyHandler))
if err != nil {
fmt.Printf("%+v", err)
}
}
访问 http://localhost:2002就能看见: