搜尋
首頁後端開發Golang如何修復 proxyconnect tcp: tls: 第一筆記錄看起來不像 TLS 握手

如何修复 proxyconnect tcp: tls: 第一条记录看起来不像 TLS 握手

php小編蘋果在這裡為大家帶來解決"proxyconnect tcp: tls: 第一筆記錄看起來不像 TLS 握手"問題的方法。這種錯誤通常出現在使用代理伺服器時,可能會導致網路連線問題。在解決此問題之前,我們首先需要了解問題的根源。透過以下簡潔的步驟,我們將向您展示如何修復這個問題,以確保您的網路連線正常運作。

問題內容

在如何在 Go 中使用 REST API 中,提供了一個完全有效的範例程式碼來呼叫公共 REST API。但如果我嘗試範例,則會出現此錯誤:

error getting cat fact: 
      Get "https://catfact.ninja/fact": 
      proxyconnect tcp: tls: first record does not look like a TLS handshake

有關http狀態的文檔

<code>
For control over proxies, TLS configuration, keep-alives, compression, and other settings, create a Transport:
</code>

以及傳輸文件:

<code>    // DialContext specifies the dial function for creating unencrypted TCP connections.
    // If DialContext is nil (and the deprecated Dial below is also nil),
    // then the transport dials using package net.
    //
    // DialContext runs concurrently with calls to RoundTrip.
    // A RoundTrip call that initiates a dial may end up using
    // a connection dialed previously when the earlier connection
    // becomes idle before the later DialContext completes.
    DialContext func(ctx context.Context, network, addr string) (net.Conn, error)
</code>

因此,我假設我必須設定 Dialcontext 才能啟用從客戶端到代理的不安全連線 without TLS。但我不知道該怎麼做。閱讀這些:

  • 如何在golang中進行代理程式和TLS;
  • 如何透過代理程式進行 HTTP/HTTPS GET;和
  • 如何使用錯誤的憑證執行 https 要求?

也沒有幫助。有些有同樣的錯誤 proxyconnect tcp: tls:first record does not Look like a TLS handshake 並解釋原因:

<code>
This is because the proxy answers with an plain HTTP error to the strange HTTP request (which is actually the start of the TLS handshake).
</code>

但是Steffen的回覆沒有範例程式碼如何設定DialContext func(ctx context.Context, network, addr string),Bogdan和cyberdelia都建議設定tls.Config{InsecureSkipVerify: true},例如這樣

<code>    tr := &http.Transport{
        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    }
    client := &http.Client{Transport: tr}
</code>

但是上面的沒有效果。我仍然遇到同樣的錯誤。並且連接仍然調用 https://* 而不是 http://*

這是範例程式碼,我嘗試包含上述建議並對其進行調整:

<code>var tr = &http.Transport{ TLSClientConfig: 
                           &tls.Config{InsecureSkipVerify: true}, } 
                           // lacks DialContext config
var client*  http.Client = &http.Client{Transport: tr} // modified * added
// var client *http.Client // code from tutorial

type CatFact struct {
    Fact   string `json:"fact"`
    Length int    `json:"length"`
}

func GetCatFact() {
    url := "http://catfact.ninja/fact" // changed from https to http
    var catFact CatFact

    err := GetJson(url, &catFact)
    if err != nil {
        fmt.Printf("error getting cat fact: %s\n", err.Error())
    } else {
        fmt.Printf("A super interesting Cat Fact: %s\n", catFact.Fact)
    }
}

func main() {
    client = &http.Client{Timeout: 10 * time.Second}
    GetCatFact()
    // same error 
    // proxyconnect tcp: tls: first record does 
    //                   not look like a TLS handshake
    // still uses https 
    // for GET catfact.ninja
}
</code>

如何將連線配置為使用從 myClient 透過代理程式到伺服器的未加密連線?設定 DialContext func(ctx context.Context, network, addr string) 有助於做到這一點嗎?怎麼辦?

解決方法

我剛剛嘗試過:

package main

import (
    "context"
    "crypto/tls"
    "encoding/json"
    "fmt"
    "net"
    "net/http"
    "time"
)

type CatFact struct {
    Fact   string `json:"fact"`
    Length int    `json:"length"`
}

// Custom dialing function to handle connections
func customDialContext(ctx context.Context, network, addr string) (net.Conn, error) {
    conn, err := net.Dial(network, addr)
    return conn, err
}

// Function to get a cat fact
func GetCatFact(client *http.Client) {
    url := "https://catfact.ninja/fact"  // Reverted back to https
    var catFact CatFact

    err := GetJson(url, &catFact, client)
    if err != nil {
        fmt.Printf("error getting cat fact: %s\n", err.Error())
    } else {
        fmt.Printf("A super interesting Cat Fact: %s\n", catFact.Fact)
    }
}

// Function to send a GET request and decode the JSON response
func GetJson(url string, target interface{}, client *http.Client) error {
    resp, err := client.Get(url)
    if err != nil {
        return fmt.Errorf("error sending GET request: %w", err)
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        return fmt.Errorf("received non-OK HTTP status: %d", resp.StatusCode)
    }

    err = json.NewDecoder(resp.Body).Decode(target)
    if err != nil {
        return fmt.Errorf("error decoding JSON response: %w", err)
    }

    return nil
}

func main() {
    // Create a custom Transport with the desired settings
    tr := &http.Transport{
        Proxy: http.ProxyFromEnvironment,  // Use the proxy settings from the environment
        DialContext: customDialContext,    // Use the custom dialing function
        TLSClientConfig: &tls.Config{
            InsecureSkipVerify: true,  // Skip certificate verification (not recommended in production)
        },
    }

    // Create a new HTTP client using the custom Transport
    client := &http.Client{
        Transport: tr,
        Timeout:   10 * time.Second,
    }

    // Call the function to get a cat fact
    GetCatFact(client)
}

它包括:

  • 自訂撥號函數customDialContext
    # 該函數目前是 net.Dial 的簡單包裝,但它提供了一個可以在必要時引入自訂撥號邏輯的位置。它用作自訂撥號功能,用於建立網路連線。

  • 傳輸設定:

    • 修改後的程式碼使用特定設定配置自訂 http.Transport,包括自訂撥號功能、環境中的代理設定以及跳過憑證驗證的 TLS 配置(用於測試)。
    • 原始程式碼也嘗試設定自訂http.Transport,但僅包含跳過憑證驗證的TLS配置,並沒有設定自訂撥號功能或代理設定。
  • 客戶端設定:

    • 修改後的程式碼使用自訂的 http.Transport 建立新的 http.Client,並設定逾時為 10 秒。
    • 原始程式碼也嘗試使用自訂http.Transport 建立新的http.Client ,但後來在main 函數中,它使用新的http.Client 覆寫了client 變量,其中包含預設的Transport 和逾時10秒的,有效丟棄自訂的Transport
  • 函數簽章:

    • 修改後的程式碼修改了GetCatFactGetJson 函數以接受*http.Client 參數,允許它們使用在main中建立的自訂http.Client
    • 原始程式碼沒有將 http.Client 傳遞給這些函數,因此它們將使用 net/http 套件提供的預設 http.Client
  • 網址:

    • 修改後的程式碼將 GetCatFact 函數中的 URL 恢復為“https://catfact.ninja/fact”,因為伺服器無論如何都會將 HTTP 請求重新導向到 HTTPS。
    • 原始程式碼已將 URL 變更為“http://catfact.ninja/fact”,以避免 TLS 握手錯誤。

上面提供的程式碼中的 customDialContext 函數不包含任何專門忽略 TLS 握手錯誤或將 TLS 握手更改為非 TLS 連線的邏輯。它只提供了自訂撥號功能,在提供的形式中,直接呼叫net.Dial,無需任何特殊處理。

忽略TLS憑證驗證錯誤的機制實際上是由http.Transport結構體的TLSClientConfig欄位提供的,具體是將InsecureSkipVerify欄位設定為true

tr := &http.Transport{
    TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}

该配置告诉 Go 跳过验证服务器的证书链和主机名,这是 TLS 握手过程的一部分。但是,它不会忽略其他类型的 TLS 握手错误或切换到非 TLS 连接。通常不建议在生产环境中使用 InsecureSkipVerify: true,因为它会禁用重要的安全检查。

如果您想强制使用非 TLS(纯 HTTP)连接,通常只需使用 http:// URL,而不是 https:// URL。但是,如果服务器或代理服务器将 HTTP 重定向到 HTTPS(例如 http://catfact.ninja/fact 的情况),则客户端将遵循重定向并切换到 TLS 连接。

以上是如何修復 proxyconnect tcp: tls: 第一筆記錄看起來不像 TLS 握手的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:stackoverflow。如有侵權,請聯絡admin@php.cn刪除
初始功能和副作用:平衡初始化與可維護性初始功能和副作用:平衡初始化與可維護性Apr 26, 2025 am 12:23 AM

Toensureinitfunctionsareeffectiveandmaintainable:1)Minimizesideeffectsbyreturningvaluesinsteadofmodifyingglobalstate,2)Ensureidempotencytohandlemultiplecallssafely,and3)Breakdowncomplexinitializationintosmaller,focusedfunctionstoenhancemodularityandm

開始GO:初學者指南開始GO:初學者指南Apr 26, 2025 am 12:21 AM

goisidealforbeginnersandsubableforforcloudnetworkservicesduetoitssimplicity,效率和concurrencyFeatures.1)installgromtheofficialwebsitealwebsiteandverifywith'.2)

進行並發模式:開發人員的最佳實踐進行並發模式:開發人員的最佳實踐Apr 26, 2025 am 12:20 AM

開發者應遵循以下最佳實踐:1.謹慎管理goroutines以防止資源洩漏;2.使用通道進行同步,但避免過度使用;3.在並發程序中顯式處理錯誤;4.了解GOMAXPROCS以優化性能。這些實踐對於高效和穩健的軟件開發至關重要,因為它們確保了資源的有效管理、同步的正確實現、錯誤的適當處理以及性能的優化,從而提升軟件的效率和可維護性。

進行生產:現實世界的用例和示例進行生產:現實世界的用例和示例Apr 26, 2025 am 12:18 AM

Goexcelsinproductionduetoitsperformanceandsimplicity,butrequirescarefulmanagementofscalability,errorhandling,andresources.1)DockerusesGoforefficientcontainermanagementthroughgoroutines.2)UberscalesmicroserviceswithGo,facingchallengesinservicemanageme

go中的自定義錯誤類型:提供詳細的錯誤信息go中的自定義錯誤類型:提供詳細的錯誤信息Apr 26, 2025 am 12:09 AM

我們需要自定義錯誤類型,因為標準錯誤接口提供的信息有限,自定義類型能添加更多上下文和結構化信息。 1)自定義錯誤類型能包含錯誤代碼、位置、上下文數據等,2)提高調試效率和用戶體驗,3)但需注意其複雜性和維護成本。

使用GO編程語言構建可擴展系統使用GO編程語言構建可擴展系統Apr 25, 2025 am 12:19 AM

goisidealforbuildingscalablesystemsduetoitssimplicity,效率和建築物內currencysupport.1)go'scleansyntaxandaxandaxandaxandMinimalisticDesignenhanceProductivityAndRedCoductivityAndRedCuceErr.2)ItSgoroutinesAndInesAndInesAndInesAndineSandChannelsEnablenableNablenableNableNablenableFifficConcurrentscorncurrentprogragrammentworking torkermenticmminging

有效地使用Init功能的最佳實踐有效地使用Init功能的最佳實踐Apr 25, 2025 am 12:18 AM

Initfunctionsingorunautomationbeforemain()andareusefulforsettingupenvorments和InitializingVariables.usethemforsimpletasks,避免使用輔助效果,andbecautiouswithTestingTestingTestingAndLoggingTomaintAnainCodeCodeCodeClarityAndTestesto。

INIT函數在GO軟件包中的執行順序INIT函數在GO軟件包中的執行順序Apr 25, 2025 am 12:14 AM

goinitializespackagesintheordertheordertheyimported,thenexecutesInitFunctionswithinApcageIntheirdeFinityOrder,andfilenamesdetermineTheOrderAcractacractacrosmultiplefiles.thisprocessCanbeCanbeinepessCanbeInfleccessByendercrededBydeccredByDependenciesbetenciesbetencemendencenciesbetnependendpackages,whermayleLeadtocomplexinitialitialializizesizization

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器