1 回答

TA貢獻1860條經驗 獲得超9個贊
TCP轉發就是實現隧道代理不需要解析數據。反向代理可以使用標準庫。
實現隧道代理以分離 http 和 https 協議。客戶端一般使用隧道發送https,發送Connect方法。發送http是Get方法。對于https請求服務,只有dail創建連接tcp轉換,http請求使用反向代理實現。
func(w http.ResponseWriter, r *http.Request) {
// check url host
if r.URL.Host != "" {
if r.Method == eudore.MethodConnect {
// tunnel proxy
conn, err := net.Dial("tcp", r.URL.Host)
if err != nil {
w.WriteHeader(502)
return
}
client, _, err := w.Hijack()
if err != nil {
w.WriteHeader(502)
conn.Close()
return
}
client.Write([]byte("HTTP/1.0 200 OK\r\n\r\n"))
go func() {
io.Copy(client, conn)
client.Close()
conn.Close()
}()
go func() {
io.Copy(conn, client)
client.Close()
conn.Close()
}()
} else {
// reverse proxy
httputil.NewSingleHostReverseProxy(r.URL).ServeHTTP(w, r)
}
}
}
實現反向代理會解析客戶端請求,代理會將請求發送到目標服務器。
反向代理轉換請求,未經測試:
func(w http.ResponseWriter, r *http.Request) {
// set host
r.URL.Scheme = "http"
r.URL.Path = "example.com"
// send
resp,err := http.DefaultClient.Do(r)
if err != nil {
w.WriteHeader(502)
return
}
// write respsonse
defer resp.Body.Close()
w.WriteHeader(resp.StatusCode)
h := w.Header()
for k,v := range resp.Header {
h[k]=v
}
io.Copy(w, resp.Body)
}
但是,直接轉發請求不處理跳到跳標頭。跳到跳標頭在rfc中明確說明。hop-to-hop header是兩個連接之間的傳輸信息。例如,客戶端到代理和代理到服務器是兩個??蛻舳说椒掌魇嵌说蕉说摹?/p>
反向代理請直接使用標準庫,它已經為您處理了跳到跳標頭和升級。
帶有過濾器的示例 NewSingleHostReverseProxy:
package main
import (
"net/http"
"strings"
"net/http/httputil"
"net/url"
)
func main() {
addr, _ := url.Parse("http://localhost:8088")
proxy := httputil.NewSingleHostReverseProxy(addr)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if strings.HasPrefix(r.URL.Path, "/api/") {
proxy.ServeHTTP(w, r)
} else {
w.WriteHeader(404)
}
})
// Listen Server
}
- 1 回答
- 0 關注
- 121 瀏覽
添加回答
舉報