Go语言从HTTP请求中获取服务端IP地址
如果一个域名可以解析出多个IP地址,那想在http请求过程中知道程序实际请求的是哪个IP地址该怎么办?带着这个疑问我找到了两个方法来解决这个问题。
一个是通过httptrace.ClientTrace获取服务IP;
另一个是通过http.Transport中的DialContext获取服务IP;
具体代码如下:
package main
import (
"context"
"crypto/tls"
"fmt"
"log"
"net"
"net/http"
"net/http/httptrace"
)
// 方法一:通过httptrace.ClientTrace获取服务IP地址
func m1() {
trace := &httptrace.ClientTrace{
DNSStart: func(_ httptrace.DNSStartInfo) {},
DNSDone: func(_ httptrace.DNSDoneInfo) {},
ConnectStart: func(net, addr string) {
fmt.Printf("ConnectStart addr=%s\n", addr)
},
ConnectDone: func(net, addr string, err error) {
fmt.Printf("ConnectDone addr=%s\n", addr)
},
GotConn: func(_ httptrace.GotConnInfo) {},
GotFirstResponseByte: func() {},
TLSHandshakeStart: func() {},
TLSHandshakeDone: func(_ tls.ConnectionState, _ error) {},
}
req, err := http.NewRequest(http.MethodGet, "http://www.baidu.com", nil)
if err != nil {
log.Fatal(err)
}
req = req.WithContext(httptrace.WithClientTrace(context.Background(), trace))
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
}
// 方法二:通过DialContext获取服务IP地址
func m2() {
req, err := http.NewRequest(http.MethodGet, "http://www.baidu.com", nil)
if err != nil {
log.Fatal(err)
}
client := http.Client{
Transport: &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
conn, err := net.Dial(network, addr)
req.RemoteAddr = conn.RemoteAddr().String()
return conn, err
},
},
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
fmt.Println("RemoteAddr:", req.RemoteAddr)
}
func main() {
m1()
m2()
}

浙公网安备 33010602011771号