>  기사  >  백엔드 개발  >  Go에서 HTTP 응답의 기본 소켓에 어떻게 액세스할 수 있나요?

Go에서 HTTP 응답의 기본 소켓에 어떻게 액세스할 수 있나요?

Linda Hamilton
Linda Hamilton원래의
2024-11-04 22:39:02643검색

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

HTTP 응답의 기본 소켓에 액세스

Go에서는 HTTP의 기본 소켓에 액세스해야 하는 상황이 발생할 수 있습니다. 응답. 일반적으로 TCP_INFO와 같은 플랫폼별 작업을 수행하려면 소켓에 액세스해야 합니다. HTTP 응답에서 직접 소켓을 얻는 간단한 방법은 없지만 탐색할 수 있는 몇 가지 접근 방식이 있습니다.

1. 컨텍스트 키 사용(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()은 항상 "@"를 반환하므로 매핑에 적합하지 않습니다. 이 문제를 극복하려면:

  • net.Listener.Accept() 재정의
  • 해당 재정의를 사용하여 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>

위 내용은 Go에서 HTTP 응답의 기본 소켓에 어떻게 액세스할 수 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.