最近有一個需求,就是需要從內網服務器的一個端口請求數據,問題是這個內網端口不能被外網訪問到,所以需要做一個轉發代理服務。原理就是當請求到達時,將本機的地址替換成目標地址,然后其他格式不變,待目標請求返回后,又將目標的報文頭及報文返回給客戶端。具體代碼如下:
func main() {
localHost := "127.0.0.1:9001"
targetHost := "127.0.0.1:8001"
httpsServer(localHost, targetHost)
log.Error("http server down!!!")
}
func httpsServer(addr string, remote_addr string) {
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
cli := &http.Client{}
body := make([]byte, 0)
n, err := io.ReadFull(req.Body, body)
if err != nil {
io.WriteString(w, "Request Data Error")
return
}
reqUrl := "http://" + remote_addr + req.URL.Path
req2, err := http.NewRequest(req.Method, reqUrl, strings.NewReader(string(body)))
if err != nil {
io.WriteString(w, "Request Error")
return
}
// set request content type
contentType := req.Header.Get("Content-Type")
req2.Header.Set("Content-Type", contentType)
// request
rep2, err := cli.Do(req2)
if err != nil {
io.WriteString(w, "Not Found!")
return
}
defer rep2.Body.Close()
n, err = io.ReadFull(rep2.Body, body)
if err != nil {
io.WriteString(w, "Request Error")
return
}
// set response header
for k, v := range rep2.Header {
w.Header().Set(k, v[0])
}
io.WriteString(w, string(body[:n]))
})
var err error = nil
err = http.ListenAndServe(":12307", nil)
if err != nil {
log.Fatal("server down!!!")
}
}
至此,一個簡單的代理服務完成。
