web-dev-qa-db-ja.com

golangはhttpリクエストを特定のIPに強制します(curl --resolveと同様)

Golang httpsgetリクエストに特定のIPアドレスを使用させるにはどうすればよいですか。 DNS解決をスキップして、自分でIPを提供したいと思います。 curlでの同等のものは、以下に示すように--resolveになります。

curl https://domain.com/dir/filename --resolve "domain.com:443:10.10.10.10"

これはSSLなので、次の例のようにドメインをIPに置き換えることは避けたいと思います。

curl https://10.10.10.10/dir/filename --header "Host:domain.com"

15
Ryan D.

カスタムを提供できます Transport.DialContext 関数。

func main() {
    dialer := &net.Dialer{
        Timeout:   30 * time.Second,
        KeepAlive: 30 * time.Second,
        DualStack: true,
    }
    // or create your own transport, there's an example on godoc.
    http.DefaultTransport.(*http.Transport).DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
        if addr == "google.com:443" {
            addr = "216.58.198.206:443"
        }
        return dialer.DialContext(ctx, network, addr)
    }
    resp, err := http.Get("https://google.com")
    log.Println(resp.Header, err)
}
20
OneOfOne

上記のOneOfOneの答えは素晴らしいです。私のような初心者が簡単に使えるように、ここに完全な作業パッケージコードを投稿しています。変更の前後のaddr値を確認できるように、printlnをいくつか追加しました。

package main

import (
    "context"
    "fmt"
    "log"
    "net"
    "net/http"
    "time"
)

func main() {
    dialer := &net.Dialer{
        Timeout:   30 * time.Second,
        KeepAlive: 30 * time.Second,
        DualStack: true,
    }
    // or create your own transport, there's an example on godoc.
    http.DefaultTransport.(*http.Transport).DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
        fmt.Println("address original =", addr)
        if addr == "google.com:443" {
            addr = "216.58.198.206:443"
            fmt.Println("address modified =", addr)
        }
        return dialer.DialContext(ctx, network, addr)
    }
    resp, err := http.Get("https://google.com")
    log.Println(resp.Header, err)
}
3
Ryan D.