首頁 > 後端開發 > Golang > 主體

502 錯誤閘道:IPSec 隧道的 net/http GET 失敗

PHPz
發布: 2024-02-09 13:09:25
轉載
671 人瀏覽過

502 错误网关:IPSec 隧道的 net/http GET 失败

php小編子墨在使用網路時,有時候會遇到502錯誤網關的提示。這個錯誤提示意味著網關伺服器和上游伺服器之間的通訊出現了問題,導致請求無法完成。其中一個可能的原因是IPSec隧道的net/http GET失敗。雖然這個錯誤可能會讓人感到困惑,但是透過了解錯誤的原因和解決方法,我們可以很快地解決這個問題,繼續享受網路的便利性。

問題內容

在windows 上透過ipsec 隧道(vpn) 使用net/http 套件發出遠端get 請求時,get 請求失敗,回應碼為502 bad gateway。但是,由 curl 發送的具有相同 headersurimethod 的請求效果很好。 go 原始碼如下所示:

    var req *http.request
    req, err = http.newrequest('get', *uri, reader)
    if nil != err {
        level.warn(log).log("msg", "unable to create request", "err", err, "uri", uri)
        return nil, err
    }
    if nil != req.body {
        defer req.body.close()
    }
    for h, v := range opts.headers {
        req.header.add(h, *v)
    }

    client := http.client{}
    if nil != err {
        return nil, err
    }
    res, err := client.do(req)
    if nil != err {
        level.warn(log).log("msg", "unable to send request", "err", err, "uri", uri)
        return nil, err
    }
    defer res.body.close()

    buf, err := io.readall(res.body)
    if nil != err {
        level.warn(log).log("msg", "unable to read response", "err", err, "uri", uri, "status", res.status, "status_code", res.statuscode)
        return nil, err
    }
登入後複製

對流量進行抓包分析後,發現vpn介面可以正常抓到curl發送的請求,但是getgo(net /http)發送的請求遺失了。

那麼我猜可能是因為框架選擇了錯誤的介面來傳送封包。

因此,我嘗試找到正確的本機網路介面並指定其 localaddr 來發送我的 get 請求,如下所示:

func Client(u string) (*http.Client, error) {
    uri, err := url.Parse(u)
    if nil != err {
        return nil, err
    }
    host := uri.Host
    port := uri.Port()
    if Empty == port {
        if uri.Scheme == "http" {
            host = host + ":80"
        } else if uri.Scheme == "https" {
            host = host + ":443"
        }
    }
    conn, err := net.Dial("tcp", host)
    if nil != err {
        return nil, err
    }
    addr := conn.LocalAddr().(*net.TCPAddr)
    // **make sure using random port as local port**
    addr.Port = 0

    dialer := &net.Dialer{LocalAddr: addr}
    dialContext := func(ctx context.Context, network, addr string) (net.Conn, error) {
        conn, err := dialer.Dial(network, addr)
        return conn, err
    }

    transport := &http.Transport{DialContext: dialContext}
    client := &http.Client{
        Transport: transport,
    }
    return client, nil
}
登入後複製

client 函數取代 client 後,get 請求最終有效。

client := &http.client{} => client, err := client(uri)

#那麼我的問題是為什麼 golang 沒有選擇正確的本地網路介面來自動發送請求?

解決方法

偵錯net.dial#DialContext後,發現該位址已變更為我在Visual Studio Code設定中的代理地址。我的代理伺服器將無法處理我的應用程式請求。

當我刪除代理設定時,net.dial 按預期工作。

重要的事情

我正在使用vscode 來處理TypeScript/Java/Golang...,這是我第一次在vscode IDE 中的 開發應用程式上遇到代理問題。換句話說,我從來沒有想過 IDE 代理程式能夠完成它所建構的工作。由於擴充功能或IDE本身使用這個代理設定是合理的,但是我的golang專案偵錯也使用它,這真的讓我很困惑。

以上是502 錯誤閘道:IPSec 隧道的 net/http GET 失敗的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!