Heim > Artikel > Backend-Entwicklung > Wie kann ich in Go auf den zugrunde liegenden Socket einer HTTP-Antwort zugreifen?
Zugriff auf den zugrunde liegenden Socket einer HTTP-Antwort
In Go kann es vorkommen, dass Sie auf den zugrunde liegenden Socket eines HTTP zugreifen müssen Antwort. Normalerweise ist der Zugriff auf den Socket erforderlich, wenn Sie plattformspezifische Vorgänge wie TCP_INFO darauf ausführen möchten. Obwohl es keine einfache Möglichkeit gibt, den Socket direkt aus der HTTP-Antwort abzurufen, gibt es mehrere Ansätze, die Sie erkunden können:
1. Verwendung des Kontextschlüssels (Go 1.13):
Sobald Go 1.13 veröffentlicht wird, wird erwartet, dass es das Speichern von net.Conn im Anforderungskontext unterstützt. Dies bietet eine saubere und unkomplizierte Methode:
<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. Verbindung nach Remote-Adresse (TCP) zuordnen:
Für Server, die TCP überwachen, hat jede Verbindung einen eindeutigen net.Conn.RemoteAddr().String()-Wert. Dieser Wert kann als Schlüssel für eine globale Karte von Verbindungen verwendet werden:
<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. Überschreiben der Remote-Adresse für UNIX-Sockets:
Für UNIX-Sockets gibt net.Conn.RemoteAddr().String() immer „@“ zurück, wodurch es für die Zuordnung ungeeignet ist. Um dies zu umgehen:
<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>
Das obige ist der detaillierte Inhalt vonWie kann ich in Go auf den zugrunde liegenden Socket einer HTTP-Antwort zugreifen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!