如何使用golang net / http在服务器中获取服务器自己的地址?
发布时间:2020-12-16 09:23:18 所属栏目:大数据 来源:网络整理
导读:我想使用Golang的net / http包写一个HTTP服务器,其反应取决于HTTP连接的服务器端IP地址. 换句话说,我要找的是CGI的“SERVER_ADDR”变量. http.Request中最接近的字段是“Host” – 但是如果请求使用文字地址,它只会等于地址,我不能使用它(服务器可能按名称使
我想使用Golang的net / http包写一个HTTP服务器,其反应取决于HTTP连接的服务器端IP地址.
换句话说,我要找的是CGI的“SERVER_ADDR”变量. http.Request中最接近的字段是“Host” – 但是如果请求使用文字地址,它只会等于地址,我不能使用它(服务器可能按名称使用). 查看https://golang.org/src/net/http/server.go的源代码,似乎获取服务器地址的唯一方法是Hijack()处理程序内的连接,并为同一连接上的后续请求实现后续HTTP解析,但至少可以说它非常不优雅… 看起来理想的解决方案是将golang标准库中的http / request和http / server修改如下: diff -u go-stock-library/request.go ./request.go --- go-stock-library/request.go 2016-04-13 17:31:48.000000000 +0200 +++ ./request.go 2016-04-13 17:32:40.000000000 +0200 @@ -227,6 +227,15 @@ // This field is ignored by the HTTP client. RemoteAddr string + // LocalAddr allows HTTP servers and other software to record + // the network address that the request was sent to,usually for + // logging. This field is not filled in by ReadRequest and + // has no defined format. The HTTP server in this package + // sets LocalAddr to an "IP:port" address before invoking a + // handler. + // This field is ignored by the HTTP client. + LocalAddr string + // RequestURI is the unmodified Request-URI of the // Request-Line (RFC 2616,Section 5.1) as sent by the client // to a server. Usually the URL field should be used instead. diff -u go-stock-library/server.go ./server.go --- go-stock-library/server.go 2016-04-13 17:29:19.000000000 +0200 +++ ./server.go 2016-04-13 17:31:38.000000000 +0200 @@ -161,6 +161,13 @@ // This is the value of a Handler's (*Request).RemoteAddr. remoteAddr string + // serverAddr is rwc.LocalAddr().String(). It is not populated synchronously + // inside the Listener's Accept goroutine,as some implementations block. + // It is populated immediately inside the (*conn).serve goroutine. + // This is the value of a Handler's (*Request).LocalAddr. + localAddr string + + // tlsState is the TLS connection state when using TLS. // nil means not TLS. tlsState *tls.ConnectionState @@ -736,6 +743,7 @@ delete(req.Header,"Host") req.RemoteAddr = c.remoteAddr + req.LocalAddr = c.localAddr req.TLS = c.tlsState if body,ok := req.Body.(*body); ok { body.doEarlyClose = true @@ -1382,6 +1390,7 @@ // Serve a new connection. func (c *conn) serve() { c.remoteAddr = c.rwc.RemoteAddr().String() + c.localAddr = c.rwc.LocalAddr().String() defer func() { if err := recover(); err != nil { const size = 64 << 10 然后以一种干净利落的方式在代码中使用新的LocalAddr. 我错过了什么,有更清洁的方法吗? 解决方法
我个人不会修改标准库中的任何内容,因为我可以通过其他方式获得.从每个连接解析它有一些优势吗?
可能有一种更简单的方法,但我有以下几点. func getMyInterfaceAddr() (net.IP,error) { ifaces,err := net.Interfaces() if err != nil { return nil,err } addresses := []net.IP{} for _,iface := range ifaces { if iface.Flags&net.FlagUp == 0 { continue // interface down } if iface.Flags&net.FlagLoopback != 0 { continue // loopback interface } addrs,err := iface.Addrs() if err != nil { continue } for _,addr := range addrs { var ip net.IP switch v := addr.(type) { case *net.IPNet: ip = v.IP case *net.IPAddr: ip = v.IP } if ip == nil || ip.IsLoopback() { continue } ip = ip.To4() if ip == nil { continue // not an ipv4 address } addresses = append(addresses,ip) } } if len(addresses) == 0 { return nil,fmt.Errorf("no address Found,net.InterfaceAddrs: %v",addresses) } //only need first return addresses[0],nil } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |