栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

访问net / http响应的基础套接字

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

访问net / http响应的基础套接字

在问题#30694完成之后,Go
1.13可能将支持在请求上下文中存储net.Conn,这使它相当干净和简单:

package mainimport (  "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)  ...}

直到那时…对于在TCP端口上侦听的服务器,net.Conn.RemoteAddr()。String()对于每个连接都是唯一的,并且可以作为r.RemoteAddr在http.Handler中使用,因此可以用作康恩斯全球地图的关键:

package mainimport (  "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)  ...}

对于在UNIX套接字上侦听的服务器,net.Conn.RemoteAddr()。String()始终为“
@”,因此上述操作无效。为此,我们可以覆盖net.Listener.Accept(),并使用它覆盖net.Conn.RemoteAddr()。String(),以便为每个连接返回唯一的字符串:

package mainimport (  "net/http"  "net"  "os"  "golang.org/x/sys/unix"  "fmt"  "log")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))}func myHandler(w http.ResponseWriter, r *http.Request) {  conn := GetConn(r)  if unixConn, isUnix := conn.(*net.UnixConn); isUnix {    f, _ := unixConn.File()    pcred, _ := unix.GetsockoptUcred(int(f.Fd()), unix.SOL_SOCKET, unix.SO_PEERCRED)    f.Close()    log.Printf("Remote UID: %d", pcred.Uid)  }}var conns = make(map[string]net.Conn)type connSaveListener struct {  net.Listener}func NewConnSaveListener(wrap net.Listener) (net.Listener) {  return connSaveListener{wrap}}func (self connSaveListener) Accept() (net.Conn, error) {  conn, err := self.Listener.Accept()  ptrStr := fmt.Sprintf("%d", &conn)  conns[ptrStr] = conn  return remoteAddrPtrConn{conn, ptrStr}, err}func GetConn(r *http.Request) (net.Conn) {  return conns[r.RemoteAddr]}func ConnStateEvent(conn net.Conn, event http.ConnState) {  if event == http.StateHijacked || event == http.StateClosed {    delete(conns, conn.RemoteAddr().String())  }}type remoteAddrPtrConn struct {  net.Conn  ptrStr string}func (self remoteAddrPtrConn) RemoteAddr() (net.Addr) {  return remoteAddrPtr{self.ptrStr}}type remoteAddrPtr struct {  ptrStr string}func (remoteAddrPtr) Network() (string) {  return ""}func (self remoteAddrPtr) String() (string) {  return self.ptrStr}func NewUnixListener(path string) (net.Listener, error) {  if err := unix.Unlink(path); err != nil && !os.IsNotExist(err) {    return nil, err  }  mask := unix.Umask(0777)  defer unix.Umask(mask)  l, err := net.Listen("unix", path)  if err != nil {    return nil, err  }  if err := os.Chmod(path, 0660); err != nil {    l.Close()    return nil, err  }  return l, nil}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/573508.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号