先重温一下什么叫反向代理,正向代理。
鹅厂二面,nginx回忆录
所谓正向,反向代理取决于代理的是出站请求,还是入站请求。
正向代理: 代理的出站请求, 客户端能感知到代理程序,架构上距离客户端更近。
反向代理: 代理的是入站请求,客户端认为代理程序就是服务器,客户端感知不到代理逻辑,架构上距离服务端更近。
前几天利用 golang 实现了反向代理程序,引出了 Host 请求头在反代中的关键作用。
对于 proxy.com 的请求,都被透明无感代理到 A.com
package main
import ( "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 = target req.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, 简单记录一下。
package main
import ( "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.Host req.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:8080 www.baidu.com
评论