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快速创建简单反向代理服务
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.