Maison > développement back-end > Golang > Comment puis-je accéder au socket sous-jacent d'une réponse HTTP dans Go ?

Comment puis-je accéder au socket sous-jacent d'une réponse HTTP dans Go ?

Linda Hamilton
Libérer: 2024-11-04 22:39:02
original
760 Les gens l'ont consulté

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

Accès au socket sous-jacent d'une réponse HTTP

Dans Go, vous pouvez rencontrer des situations dans lesquelles vous devez accéder au socket sous-jacent d'une réponse HTTP réponse. En règle générale, l'accès au socket est requis lorsque vous souhaitez y effectuer des opérations spécifiques à la plate-forme, telles que TCP_INFO. Bien qu'il n'existe aucun moyen simple d'obtenir le socket directement à partir de la réponse HTTP, vous pouvez explorer plusieurs approches :

1. Utilisation de la clé de contexte (Go 1.13) :
Une fois Go 1.13 publié, il est prévu de prendre en charge le stockage de net.Conn dans le contexte de requête. Cela fournit une méthode propre et simple :

<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>
Copier après la connexion

2. Mappage de connexion par adresse distante (TCP) :
Pour les serveurs écoutant sur TCP, chaque connexion a une valeur net.Conn.RemoteAddr().String() unique. Cette valeur peut être utilisée comme clé d'une carte globale des connexions :

<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>
Copier après la connexion

3. Remplacement de l'adresse distante pour les sockets UNIX :
Pour les sockets UNIX, net.Conn.RemoteAddr().String() renvoie toujours "@", ce qui le rend impropre au mappage. Pour surmonter cela :

  • Remplacez net.Listener.Accept()
  • Utilisez ce remplacement pour attribuer une chaîne unique à chaque connexion via net.UnixConn.File()
<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>
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal