[英]How to capture IP address of server providing HTTP response
Using Go's default HTTP client , I am unable to directly determine the IP address of the server that processed the request.使用 Go 的默认 HTTP 客户端,我无法直接确定处理请求的服务器的 IP 地址。 For instance, when requesting
example.com
, what is the IP address that example.com
resolved to at the time of the request?例如,当请求
example.com
,什么是IP地址example.com
在要求的时间分辨什么?
import "net/http"
resp, err := http.Get("http://example.com/")
The resp
object contains the resp.RemoteAddr
property, but as detailed below it is not utilized during client operations. 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
Is there a straightforward way to accomplish this?有没有一种直接的方法来实现这一点? My initial thought would be to:
我最初的想法是:
http
transport using returned A/AAAA recordshttp
传输RemoteAddr
property on the response objectRemoteAddr
属性Is there a better way?有更好的方法吗?
UPDATED - to use @flimzy's suggestion.更新 - 使用@flimzy 的建议。 This method stores the remote IP:PORT into the
request.RemoteAddr
property.此方法将远程 IP:PORT 存储到
request.RemoteAddr
属性中。 I've also added support for multiple redirects so that each subsequent request has its RemoteAddr
populated.我还添加了对多个重定向的支持,以便每个后续请求都填充其
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)
As far as I can tell, the only way to accomplish this with the standard library is with a custom http.Transport that records the remote IP address, for example in the DialContext
function.据我所知,使用标准库完成此操作的唯一方法是使用自定义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")
Tying the connection IP to the response is left as an exercise for the reader.将连接 IP 绑定到响应留给读者作为练习。
you also can build a request with trace:您还可以使用跟踪构建请求:
request = request.WithContext(httptrace.WithClientTrace(request.Context(), &httptrace.ClientTrace{
GotConn: func(connInfo httptrace.GotConnInfo) {
fmt.Printf("target ip:%+v\n", connInfo.Conn.RemoteAddr().String())
},
}))
response, _:= client.Do(request)
httptrace form https://golang.org/pkg/net/http/httptrace/ httptrace 表单https://golang.org/pkg/net/http/httptrace/
req, err := http.NewRequest(method, url, strings.NewReader(body))
trace := &httptrace.ClientTrace{
GotConn: func(connInfo httptrace.GotConnInfo) {
fmt.Printf("Got Conn: %+v\n", connInfo)
},
DNSDone: func(dnsInfo httptrace.DNSDoneInfo) {
fmt.Printf("DNS Info: %+v\n", dnsInfo)
},
}
req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.