存取HTTP 回應的底層套接字
在Go 中,你可能會遇到需要存取HTTP 底層套接字的情況回覆.通常,當您想要對其執行特定於平台的操作(例如 TCP_INFO)時,需要存取套接字。雖然沒有直接從HTTP 回應取得套接字的簡單方法,但您可以探索以下幾種方法:
1.使用Context Key (Go 1.13 ):
Go 1.13發布後,預計將支援在請求上下文中儲存net.Conn。這提供了一種乾淨且簡單的方法:
<code class="go">package main import ( "net/http" "context" "net" "log" ) type contextKey struct { key string } var ConnContextKey = &contextKey{"http-conn"} func SaveConnInContext(ctx context.Context, c net.Conn) (context.Context) { return context.WithValue(ctx, ConnContextKey, c) } func GetConn(r *http.Request) (net.Conn) { return r.Context().Value(ConnContextKey).(net.Conn) } func main() { http.HandleFunc("/", myHandler) server := http.Server{ Addr: ":8080", ConnContext: SaveConnInContext, } server.ListenAndServe() } func myHandler(w http.ResponseWriter, r *http.Request) { conn := GetConn(r) ... }</code>
2.透過遠端位址(TCP) 映射連接:
對於偵聽TCP 的伺服器,每個連接都有一個唯一的net.Conn.RemoteAddr().String() 值。該值可以用作全域連接映射的鍵:
<code class="go">package main import ( "net/http" "net" "fmt" "log" ) var conns = make(map[string]net.Conn) func ConnStateEvent(conn net.Conn, event http.ConnState) { if event == http.StateActive { conns[conn.RemoteAddr().String()] = conn } else if event == http.StateHijacked || event == http.StateClosed { delete(conns, conn.RemoteAddr().String()) } } func GetConn(r *http.Request) (net.Conn) { return conns[r.RemoteAddr] } func main() { http.HandleFunc("/", myHandler) server := http.Server{ Addr: ":8080", ConnState: ConnStateEvent, } server.ListenAndServe() } func myHandler(w http.ResponseWriter, r *http.Request) { conn := GetConn(r) ... }</code>
3。覆蓋 UNIX 套接字的遠端位址:
對於 UNIX 套接字,net.Conn.RemoteAddr().String() 總是傳回“@”,使其不適合對應。要克服這個問題:
<code class="go">package main import ( "net/http" "net" "os" "golang.org/x/sys/unix" "fmt" "log" ) // ... (code omitted for brevity) func main() { http.HandleFunc("/", myHandler) listenPath := "/var/run/go_server.sock" l, err := NewUnixListener(listenPath) if err != nil { log.Fatal(err) } defer os.Remove(listenPath) server := http.Server{ ConnState: ConnStateEvent, } server.Serve(NewConnSaveListener(l)) } // ... (code omitted for brevity)</code>
以上是如何在Go中存取HTTP回應的底層套接字?的詳細內容。更多資訊請關注PHP中文網其他相關文章!