如何获取服务器';在使用net/http的服务器中,用户自己的地址是多少?

如何获取服务器';在使用net/http的服务器中,用户自己的地址是多少?,http,go,Http,Go,我想使用Go的net/HTTP包编写一个HTTP服务器,其反应取决于HTTP连接的服务器端IP地址 换句话说,我要寻找的是CGI的“SERVER\u ADDR”变量的等价物 http.Request中最近的字段是“Host”-但由于只有在请求使用文本地址时,它才等于地址,所以我不能使用它(服务器可能按名称使用) 查看上的源代码,找到服务器地址的唯一方法似乎是劫持()处理程序中的连接,并对同一连接上的后续请求执行后续HTTP解析,但至少可以说这看起来很不雅观 理想的解决方案似乎是将golang标准

我想使用Go的net/HTTP包编写一个HTTP服务器,其反应取决于HTTP连接的服务器端IP地址

换句话说,我要寻找的是CGI的“SERVER\u ADDR”变量的等价物

http.Request中最近的字段是“Host”-但由于只有在请求使用文本地址时,它才等于地址,所以我不能使用它(服务器可能按名称使用)

查看上的源代码,找到服务器地址的唯一方法似乎是劫持()处理程序中的连接,并对同一连接上的后续请求执行后续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
diff-u-go库/request.go./request.go
---go股票库/request.go 2016-04-13 17:31:48.000000000+0200
+++/request.go 2016-04-13 17:32:40.000000000+0200
@@ -227,6 +227,15 @@
//HTTP客户端将忽略此字段。
远程地址字符串
+//LocalAddr允许HTTP服务器和其他软件记录
+//请求发送到的网络地址,通常用于
+//日志记录。此字段不是由ReadRequest和
+//没有定义的格式。此包中的HTTP服务器
+//在调用
+//处理器。
+//此字段被HTTP客户端忽略。
+LocalAddr字符串
+
//RequestURI是服务器的未修改请求URI
//客户发送的请求行(RFC 2616,第5.1节)
//连接到服务器。通常应该使用URL字段。
diff-u go库/server.go./server.go
---go股票库/server.go 2016-04-13 17:29:19.000000000+0200
+++./server.go 2016-04-13 17:31:38.000000000+0200
@@ -161,6 +161,13 @@
//这是处理程序(*请求)的值。RemoteAddr。
远程地址字符串
+//serverAddr是rwc.LocalAddr().String()。它不是同步填充的
+//在侦听器的Accept goroutine中,因为某些实现会阻塞。
+//它立即填充在(*conn).serve goroutine中。
+//这是处理程序(*请求)的值。LocalAddr。
+localAddr字符串
+   
+
//tlsState是使用TLS时的TLS连接状态。
//nil的意思不是TLS。
tls状态*tls.ConnectionState
@@ -736,6 +743,7 @@
删除(请求标题“主机”)
req.RemoteAddr=c.RemoteAddr
+req.LocalAddr=c.LocalAddr
req.TLS=c.TLS状态
如果是正文,则ok:=要求正文。(*body);嗯{
body.doEarlyClose=true
@@ -1382,6 +1390,7 @@
//提供一个新的连接。
func(c*conn)发球(){
c、 remoteAddr=c.rwc.remoteAddr().String()
+c.localAddr=c.rwc.localAddr().String()
延迟函数(){
如果错误:=recover();错误!=nil{

const size=64我个人不会修改标准库中的任何内容,因为我可以通过其他方式获得。从每个连接解析它有什么好处吗

可能有一种更简单的方法,但我有以下几点

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
}

在我的使用案例中,单个地址不起作用-因为每个连接的地址可能不同。想象一个应用了大量IPv6地址的单一接口。然后可以在其中任何一个上终止连接,我需要知道它是哪一个。。。