Go語言正/反向代理的姿勢
先重溫一下什麼叫反向代理,正向代理。
所謂正向,反向代理取決於代理的是出站請求,還是入站請求。
正向代理: 代理的出站請求, 客戶端能感知到代理程式,架構上距離客戶端更近。
反向代理: 代理的是入站請求,客戶端認為代理程式就是伺服器,客戶端感知不到代理邏輯,架構上距離服務端更近。
前幾天利用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
GO快閃#
本文總結了go語言正反向代理的姿勢。