Bagaimanakah Saya Boleh Mengakses Soket Dasar Respons HTTP dalam Go?

Linda Hamilton
Lepaskan: 2024-11-04 22:39:02
asal
641 orang telah melayarinya

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

Mengakses Soket Dasar Respons HTTP

Dalam Go, anda mungkin menghadapi situasi di mana anda perlu mengakses soket asas HTTP tindak balas. Biasanya, mengakses soket diperlukan apabila anda ingin melakukan operasi khusus platform padanya, seperti TCP_INFO. Walaupun tiada cara mudah untuk mendapatkan soket terus daripada respons HTTP, terdapat beberapa pendekatan yang boleh anda terokai:

1. Menggunakan Kunci Konteks (Go 1.13 ):
Setelah Go 1.13 dikeluarkan, ia dijangka menyokong penyimpanan net.Conn dalam Konteks Permintaan. Ini menyediakan kaedah yang bersih dan mudah:

<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>
Salin selepas log masuk

2. Pemetaan Sambungan melalui Alamat Jauh (TCP):
Untuk pelayan mendengar pada TCP, setiap sambungan mempunyai nilai net.Conn.RemoteAddr().String() yang unik. Nilai ini boleh digunakan sebagai kunci kepada peta global sambungan:

<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>
Salin selepas log masuk

3. Mengatasi Alamat Jauh untuk Soket UNIX:
Untuk soket UNIX, net.Conn.RemoteAddr().String() sentiasa mengembalikan "@", menjadikannya tidak sesuai untuk pemetaan. Untuk mengatasinya:

  • Override net.Listener.Accept()
  • Gunakan override itu untuk menetapkan rentetan unik kepada setiap sambungan melalui 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>
Salin selepas log masuk

Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Mengakses Soket Dasar Respons HTTP dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan