Go语言正/反向代理的姿势

先重温一下什么叫反向代理,正向代理 。
鹅厂二面 , nginx回忆录
所谓正向,反向代理取决于代理的是出站请求 , 还是入站请求 。
正向代理: 代理的出站请求 ,  客户端能感知到代理程序,架构上距离客户端更近 。反向代理: 代理的是入站请求,客户端认为代理程序就是服务器,客户端感知不到代理逻辑,架构上距离服务端更近 。

Go语言正/反向代理的姿势

文章插图
前几天利用golang实现了反向代理程序,引出了Host请求头在反代中的关键作用 。
Go语言正/反向代理的姿势

文章插图
对于proxy.com的请求,都被透明无感代理到A.com
package mainimport ( "fmt" "log" "net/http" "net/http/httputil")func ReverseProxyHandler(w http.ResponseWriter, r *http.Request) { fmt.Println("receive a request from:", r.RemoteAddr, r.Header) target := "www.baidu.com" director := func(req *http.Request) {req.URL.Scheme = "https"req.URL.Host = targetreq.Host = target } proxy := &httputil.ReverseProxy{Director: director} proxy.ServeHTTP(w, r)}func main() { fmt.Printf("Starting server at port 8080\n") if err := http.ListenAndServe(":8080", http.HandlerFunc(ReverseProxyHandler)); err != nil {log.Fatal(err) }}这几天刚好遇到了一个正常代理的case,简单记录一下 。
Go语言正/反向代理的姿势

文章插图
package mainimport ( "fmt" "log" "net/http" "net/http/httputil")func ProxyHandler(w http.ResponseWriter, r *http.Request) { fmt.Printf("receive a request from {0}{1}: \n", r.RemoteAddr, r.Header) if r.Host != "localhost:8080" {director := func(req *http.Request) {req.URL.Scheme = "http"req.URL.Host = r.Hostreq.Host = r.Host}proxy := &httputil.ReverseProxy{Director: director}proxy.ServeHTTP(w, r) } else {http.NotFound(w, r) }}func main() { if err := http.ListenAndServe(":8080", http.HandlerFunc(ProxyHandler)); err != nil {log.Fatal(err) }}
其中要注意的就是,正向代理式要规避死循环代理 。
使用该服务作为代理程序,将可以出站访问任何地址 。
使用时,针对httpclient设置proxy
//adding the proxy settings to the Transport object transport := &http.Transport{Proxy: http.ProxyURL(proxyURL), } //adding the Transport object to the http Client client := &http.Client{Transport: transport, }下面使用curl指令演示(-x 后接代理地址)curl -x 127.0.0.1:8080www.baidu.com
Go语言正/反向代理的姿势

文章插图
GO快闪#本文总结了go语言正反向代理的姿势 。
【Go语言正/反向代理的姿势】

    推荐阅读