package main
import (
"flag"
"fmt"
"net/http"
"net/http/httputil"
"net/url"
"strings"
)
//代理對象
var proxyObj *httputil.ReverseProxy
//代理的服務器url
var proxyUrl string
var proxyUrlObj *url.URL
func serveReverseProxy(res http.ResponseWriter, req *http.Request) {
host := req.Host
req.URL.Host = proxyUrlObj.Host
req.URL.Scheme = proxyUrlObj.Scheme
req.Header.Set("X-Forwarded-Host", host)
if len(req.Header.Get("X-Real-IP")) <= 0 {
//服務器直接請求的host,如果已經設置就不重複設置
req.Header.Set("X-Real-IP", host)
}
//req.Host = proxyUrlObj.Host
//將代理髮送請求header中的Host指定爲原始host,雖然這個個Header,但存儲的位置在req.Host
req.Host = host
proxyObj.ServeHTTP(res, req)
}
//創建代理對象
func creatProxy() {
proxyUrlObj, _ = url.Parse(proxyUrl)
proxyObj = httputil.NewSingleHostReverseProxy(proxyUrlObj)
}
func isDoProxy(res http.ResponseWriter, req *http.Request) bool {
path := req.URL.Path
//當請求path爲/__p_set__時動態設置代理的目標url
if strings.EqualFold(path, "/__p_set__") {
query := req.URL.Query()
u := query.Get("url")
if len(u) > 0 {
proxyUrl = u
creatProxy()
}
res.WriteHeader(http.StatusOK)
fmt.Fprintf(res, "{\"message\":\"proxyUrl:%s\"}", proxyUrl)
return true
} else if nil == proxyObj {
creatProxy()
}
return true
}
//代理服務
func handleRequestAndRedirect(res http.ResponseWriter, req *http.Request) {
if isDoProxy(res, req) {
serveReverseProxy(res, req)
}
}
func main() {
var port string
flag.StringVar(&proxyUrl, "url", "http://10.200.193.68/", "")
flag.StringVar(&port, "port", "80", "")
flag.Parse()
fmt.Println("server is starting\nlisten: " + port + "\nproxyUrl: " + proxyUrl)
http.HandleFunc("/", handleRequestAndRedirect)
if err := http.ListenAndServe(":"+port, nil); err != nil {
panic(err)
}
}
使用Go快速創建簡單反向代理服務
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.