Using Go's default HTTP client, I am unable to directly determine the IP address of the server that processed the request. For instance, when requesting example.com, what is the IP address that example.com resolved to at the time of the request?
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.
// 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:
- Initiate a DNS lookup to remote domain
- Create new
httptransport using returned A/AAAA records - Make the request
- Set the
RemoteAddrproperty on the response object
Is there a better way?
UPDATED - to use @flimzy's suggestion. This method stores the remote IP:PORT into the request.RemoteAddr property. I've also added support for multiple redirects so that each subsequent request has its RemoteAddr populated.
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)