Golang 執行 IPv6 的 request

實驗設備只能以通過綁定了 IPv6 的 network interface eth0.1002 執行 curl 的請求,那在 golang 下要如何實作?

1. 環境 Environment

  • macOS 12.5.1
  • go v1.18

2. 以 exec.Command 執行 curl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main

import (
"fmt"
"os/exec"
)

func main() {
// curl --interface eth0.1002 http://[fe80::8ee3:8eff:fe00:6974]/redfish/v1/Fabrics/NVMe-oF/Connections
curl := exec.Command("curl", "--interface", "eth0.1002", "http://[fe80::8ee3:8eff:fe00:6974]/redfish/v1/Fabrics/NVMe-oF/Connections")
out, err := curl.Output()
if err != nil {
fmt.Println("error", err)
} else {
fmt.Println(string(out))
}
}

要留意 exec.Command 對應 curl 的參數時,是要分隔開來指定的,不可寫在同一個 string 裡。

要將 response 結果輸出到檔案,可以用下列方式,

1
curl := exec.Command("bash", "-c", "curl https://www.google.com > file")

Ref: Golang 中如何执行带参的 curl 命令?

3. 以 net/http 執行

完整的 IPv6 url 為

1
http://[fe80::8ee3:8eff:fe00:6974%25eth0.1002]/redfish/v1/Fabrics/NVMe-oF/Connections

請注意 %25 在 url decode 後會是 % 這個符號。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main

import (
"fmt"
"io/ioutil"
"log"
"net/http"
)

func main() {
// http://[fe80::8ee3:8eff:fe00:6974%25eth0.1002]/redfish/v1/Fabrics/NVMe-oF/Connections
ipv6 := "fe80::8ee3:8eff:fe00:6974"
eth := "eth0.1002"
url := fmt.Sprintf("http://[%s%%25%s]/redfish/v1/Fabrics/NVMe-oF/Connections", ipv6, eth)

response, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
defer response.Body.Close()
cnt, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("status code: %d, content: %s", response.StatusCode, string(cnt))
}

Refs:

  1. What’s the Deal with IPv6 Link-Local Addresses?
  2. Percent-encoding