首页 > 后端开发 > Golang > 正文

如何在Go中访问HTTP响应的底层套接字?

Linda Hamilton
发布: 2024-11-04 22:39:02
原创
589 人浏览过

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

访问 HTTP 响应的底层套接字

在 Go 中,你可能会遇到需要访问 HTTP 底层套接字的情况回复。通常,当您想要对其执行特定于平台的操作(例如 TCP_INFO)时,需要访问套接字。虽然没有直接从 HTTP 响应获取套接字的简单方法,但您可以探索以下几种方法:

1.使用 Context Key (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中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!