やりたいこと
Goでドメインの名前解決を強制的に行う。
ドメインの名前解決を外部DNSを通して行うのではなくて自分でIPアドレスを指定して解決したい場合は、通常はローカルマシンのhostsファイルに以下のように記述すればよい。
203.0.113.0 google.com # google.comを 203.0.113.0 に解決させる例
hostsファイルを使用する以外だと、curl
コマンドに--resolve
オプションというのがあり、以下のように指定することでコマンド実行時に直接名前解決を行わせることが可能だ。
curl https://google.com --resolve "google.com:443:203.0.113.0"
今回はこのcurlの場合と同様に、hostsファイルを使わずにリクエスト実行時に強制的にドメインにIPアドレスを与えるということをGoでやりたかった。
そもそも可能なのか、可能だとしたらどういう方法でできるのか分からず色々と検索していたら、まさに同じことをやろうとしてた人のstack overflowの質問ページを見つけて無事解決した。
方法
上記のリンク先に投稿されている回答の通りなのだが、http接続時に使用するhttp.Transport.DialContext
をカスタマイズすることで実現できた。
func main() {
dialer := &net.Dialer{
Timeout: 30 * time.Second, // このへんのタイムアウト設定はこれがデフォルト値
KeepAlive: 30 * time.Second,
DualStack: true,
}
http.DefaultTransport.(*http.Transport).DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
if addr == "google.com:443" { // 接続先が google.com:443 の場合に、203.0.113.0:443 に解決する。ドメインだけでなく、「:443」とport番号の指定が必要な事に注意。
addr = "203.0.113.0:443"
}
return dialer.DialContext(ctx, network, addr)
}
resp, err := http.Get("https://google.com")
log.Println(resp.Header, err)
}