【问题标题】:golang force http request to specific ip (similar to curl --resolve)golang 强制对特定 ip 的 http 请求(类似于 curl --resolve)
【发布时间】:2017-03-30 04:27:53
【问题描述】:

如何强制 golang https get 请求使用特定的 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"

【问题讨论】:

    标签: go https request ip-address resolve


    【解决方案1】:

    您可以提供自定义的Transport.DialContext 函数。

    func main() {
        dialer := &net.Dialer{
            Timeout:   30 * time.Second,
            KeepAlive: 30 * time.Second,
            // DualStack: true, // this is deprecated as of go 1.16
        }
        // 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)
    }
    

    【讨论】:

    • 谢谢,效果很好,我不得不进行一项调整,将“addr”中的“https”转换为“443”
    • @OneOfOne 我在指定 IPv6 地址 addr="2001:558:fe0d:23::2:443" 时遇到了一个问题,我猜是因为冒号分隔符“:”周围的混淆.我以为我看到了一个示例,他们将 [] 放在 ipv6 地址周围,例如“[2001:558:fe0d:23::2]:443”,我认为我已经完成了这项工作,但它也失败了。努力寻找 IPv6 示例。有什么想法吗?
    • 我解决了。 “[]”确实适用于 IPv6。我忘记了我在测试时使用的 VPN 不支持 IPv6。我把“ip”和“port”变成了变量,这样我就可以在服务器之间切换了。 addr = "[" + ip + "]" + ":" + port 现在适用于 IPv4 和 IPv6
    • @RyanD。您应该用它来更新您的答案,以便将来参考。
    • DualStack 现已弃用。 (我的 Go 版本是 1.16)
    【解决方案2】:

    OneOfOne 的上述回答非常好。我在这里发布完整的工作包代码,以便像我这样的菜鸟更容易。我添加了几个 println 以便您可以看到修改前后的 addr 值。

    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)
    }
    

    【讨论】:

      猜你喜欢
      • 2015-06-05
      • 2015-04-27
      • 2019-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-13
      相关资源
      最近更新 更多