英文:
golang force http request to specific ip (similar to curl --resolve)
问题
如何强制使用特定的IP地址进行golang的https get请求?我想跳过DNS解析并自己提供IP地址。在curl中,相当于使用--resolve参数,示例如下:
curl https://domain.com/dir/filename --resolve "domain.com:443:10.10.10.10"
由于这是SSL连接,我想避免在URL中替换域名为IP地址,示例如下:
curl https://10.10.10.10/dir/filename --header "Host: domain.com"
英文:
How can I force a golang https get request to use a specific IP address. I want to skip DNS resolution and provide the IP myself. The equivalent in curl would be a --resolve as illustrated below.
curl https://domain.com/dir/filename --resolve "domain.com:443:10.10.10.10"
Since this is ssl I want to avoid substituting in the IP for the domain as in the following example.
curl https://10.10.10.10/dir/filename --header "Host: domain.com"
答案1
得分: 35
你可以提供一个自定义的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)
}
英文:
You can provide a custom Transport.DialContext
function.
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)
}
答案2
得分: 5
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("原始地址 =", addr)
if addr == "google.com:443" {
addr = "216.58.198.206:443"
fmt.Println("修改后的地址 =", addr)
}
return dialer.DialContext(ctx, network, addr)
}
resp, err := http.Get("https://google.com")
log.Println(resp.Header, err)
}
希望对你有帮助!
英文:
OneOfOne's answer above is excellent. I am posting the full working package code here to make it easier for noobs like me. I added a couple of println so that you could see the addr value before and after modification.
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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论