2017-02-17 212 views
3

该http.Request结构包括请求的发送者的远程IP地址和端口:如何找到Go http.Response的远程IP地址?

// RemoteAddr allows HTTP servers and other software to record 
    // the network address that sent the request, usually for 
    // logging. This field is not filled in by ReadRequest and 
    // has no defined format. The HTTP server in this package 
    // sets RemoteAddr to an "IP:port" address before invoking a 
    // handler. 
    // This field is ignored by the HTTP client. 
    **RemoteAddr string** 

的http.Response对象没有这样的字段。

我想知道对我发送的请求作出响应的IP地址,即使我将它发送到DNS地址也是如此。

我认为net.LookupHost()可能会有帮助,但1)它可以为单个主机名返回多个IP,并且2)它会忽略主机文件,除非cgo可用,它不在我的情况中。

是否可以检索http.Response的远程IP地址?

+0

@ B.Adler这个问题是问一个HTTP 。请求。我在询问一个http.Response。 –

+1

最好的方法是让服务器将它包含在标题中。在很多情况下,您甚至不会直接连接到服务器,只能通过代理或负载平衡器获知地址。 – JimB

+0

您应该在问题的早期澄清您正在编写HTTP *客户端*。 – dolmen

回答

3

使用net/http/httptrace程序包并使用GotConnInfo钩子来捕获net.Conn及其相应的Conn.RemoteAddr()

这会给你的地址Transport实际拨出,而不是什么在DNSDoneInfo解决:

package main 

import (
    "log" 
    "net/http" 
    "net/http/httptrace" 
) 

func main() { 
    req, err := http.NewRequest("GET", "https://example.com/", nil) 
    if err != nil { 
     log.Fatal(err) 
    } 

    trace := &httptrace.ClientTrace{ 
     GotConn: func(connInfo httptrace.GotConnInfo) { 
      log.Printf("resolved to: %s", connInfo.Conn.RemoteAddr()) 
     }, 
    } 

    req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace)) 

    client := &http.Client{} 
    _, err := client.Do(req) 
    if err != nil { 
     log.Fatal(err) 
    } 
} 

输出:

~ go run ip.go 
2017/02/18 19:38:11 resolved to: 104.16.xx.xxx:443 
相关问题