Heim  >  Artikel  >  Backend-Entwicklung  >  Wie kann ich in Go auf den zugrunde liegenden Socket einer HTTP-Antwort zugreifen?

Wie kann ich in Go auf den zugrunde liegenden Socket einer HTTP-Antwort zugreifen?

Linda Hamilton
Linda HamiltonOriginal
2024-11-04 22:39:02591Durchsuche

How Can I Access the Underlying Socket of an HTTP Response in Go?

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:

  • net.Listener.Accept() überschreiben
  • Verwenden Sie diese Überschreibung, um jeder Verbindung über net.UnixConn.File() eine eindeutige Zeichenfolge zuzuweisen
<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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn