I'm trying to make an HTTP request using a specific interface on my machine. My actual code is:
package main
import (
"context"
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
"time"
)
func PanicErr(err error) {
if err != nil {
panic(err)
}
}
func main() {
ief, err := net.InterfaceByName("usb0")
if err != nil {
log.Fatal(err)
}
addrs, err := ief.Addrs()
if err != nil {
log.Fatal(err)
}
tcpAddr := &net.TCPAddr{
IP: addrs[0].(*net.IPNet).IP,
}
dialer := net.Dialer{LocalAddr: tcpAddr}
dialContext := func(ctx context.Context, network, addr string) (net.Conn, error) {
contextTimeout, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
conn, err := dialer.DialContext(contextTimeout, network, addr)
return conn, err
}
transport := &http.Transport{DialContext: dialContext}
client := &http.Client{
Transport: transport,
}
// http request
response, err := client.Get("https://ipinfo.io/")
PanicErr(err)
data, err := ioutil.ReadAll(response.Body)
PanicErr(err)
fmt.Println(string(data))
}
But it doesn't work. Once started, as output, I have:
> go run req.go
panic: Get "https://ipinfo.io/": dial tcp 192.168.8.100:0->34.117.59.81:443: i/o timeout
But if I attempt the same request with curl, it works and the IP address is the one the interface have right now:
> curl --interface usb0 https://ipinfo.io/
{
"ip": "31.*.*.*",
...
}
Actual ifconfig
output:
usb0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.8.100 netmask 255.255.255.0 broadcast 192.168.8.255
inet6 fe80::21d5:1667:629c:7e91 prefixlen 64 scopeid 0x20<link>
ether 62:ef:7f:**:**:** txqueuelen 1000 (Ethernet)
RX packets 281 bytes 57933 (56.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 73 bytes 8688 (8.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Output of lsusb
:
Bus 001 Device 009: ID 12d1:14db Huawei Technologies Co., Ltd. E353/E3131
What's wrong with my code?