http - 如何捕获提供 HTTP 响应的服务器的 IP 地址

标签 http go ip

使用 Go 的 default HTTP client ,我无法直接确定处理请求的服务器的 IP 地址。例如,当请求 example.com 时,example.com 在请求时解析到的 IP 地址是什么?

import "net/http"

resp, err := http.Get("http://example.com/")

resp 对象包含 resp.RemoteAddr 属性,但如下所述,在客户端操作期间不会使用它。

 // 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

有没有一种简单的方法可以做到这一点?我最初的想法是:

  1. 启动对远程域的 DNS 查找
  2. 使用返回的 A/AAAA 记录创建新的 http 传输
  3. 提出要求
  4. 在响应对象上设置 RemoteAddr 属性

有没有更好的办法?


已更新 - 使用@flimzy 的建议。此方法将远程 IP:PORT 存储到 request.RemoteAddr 属性中。我还添加了对多个重定向的支持,以便每个后续请求都填充其 RemoteAddr

request, _ := http.NewRequest("GET", "http://www.google.com", nil)
client := &http.Client{
    Transport:&http.Transport{
        DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
            conn, err := net.Dial(network, addr)
            request.RemoteAddr = conn.RemoteAddr().String()
            return conn, err
        },
    },
    CheckRedirect: func(req *http.Request, via []*http.Request) error {
        request = req
        return nil
    },
}
resp, _ := client.Do(request)

最佳答案

据我所知,使用标准库实现此目的的唯一方法是使用自定义 http.Transport记录远程 IP 地址,例如在 DialContext 函数中。

client := &http.Client{
    Transport: &http.Transport{
        DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
            conn, err := net.Dial(network, addr)
            fmt.Printf("Remote IP: %s\n", conn.RemoteAddr())
            return conn, err
        },
    },
}
resp, _ := client.Get("http://www.google.com")

将连接 IP 绑定(bind)到响应留给读者作为练习。

关于http - 如何捕获提供 HTTP 响应的服务器的 IP 地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49384786/

相关文章:

python - 如何以 'smarter' 的方式使用 python 下载文件?

android - 网址打开连接

mongodb - mgo/txn 断言集合中的唯一性

c++ - 在 C++ 中获取 IP 地址的独立于平台的方法

ip - 如何使用 Ghostdriver 分配私有(private) IP 地址和端口

iphone - iPhone 上的同步 NSURLConnection 线程

angular - http get请求Angular 6中的返回字符串

multithreading - golang可以启动多线程来处理网络IO吗

go - 为什么 [容量] 字符串断言到 [] 字符串会在 Golang 中失败?

docker - 创建后如何更改docker的IP地址?