Editor PHP Apple di sini untuk membawakan anda penyelesaian kepada masalah "proxyconnect tcp: tls: rekod pertama tidak kelihatan seperti jabat tangan TLS". Ralat ini biasanya berlaku apabila menggunakan pelayan proksi dan boleh menyebabkan masalah sambungan rangkaian. Sebelum kita dapat menyelesaikan masalah ini, kita perlu memahami punca masalah tersebut. Dengan langkah mudah berikut, kami akan menunjukkan kepada anda cara untuk menyelesaikan masalah ini untuk memastikan sambungan rangkaian anda berfungsi dengan baik.
Dalam Cara menggunakan REST API dalam Go, kod contoh yang berfungsi sepenuhnya disediakan untuk memanggil API REST awam. Tetapi jika saya mencuba contoh saya mendapat ralat ini:
error getting cat fact: Get "https://catfact.ninja/fact": proxyconnect tcp: tls: first record does not look like a TLS handshake
Dokumentasi pada status http
<code> For control over proxies, TLS configuration, keep-alives, compression, and other settings, create a Transport: </code>
Dan dokumen pemindahan:
<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>
Jadi saya menganggap saya perlu mengkonfigurasi Konteks Dail untuk membolehkan sambungan tidak selamat daripada klien ke proksi without TLS
. Tetapi saya tidak tahu bagaimana untuk melakukannya. Baca ini:
Tidak membantu juga. Ada yang mengalami ralat yang sama proxyconnect tcp: tls:first record does not Look like a TLS handshake
dan terangkan sebabnya:
<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>
Tetapi balasan Steffen tidak mempunyai kod contoh tentang cara menyediakannya DialContext func(ctx context.Context, network, addr string)
,Bogdan和cyberdelia都建议设置tls.Config{InsecureSkipVerify: true}
, contohnya seperti ini < /p>
<code> tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } client := &http.Client{Transport: tr} </code>
Tetapi perkara di atas tiada kesan. Saya masih mendapat ralat yang sama. dan sambungan masih memanggil https://*
而不是 http://*
Ini adalah contoh kod, saya cuba memasukkan cadangan di atas dan menyesuaikannya:
<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>
Bagaimana untuk mengkonfigurasi sambungan untuk menggunakan sambungan yang tidak disulitkan daripada Pelanggan saya ke pelayan melalui proksi? Adakah tetapan DialContext func(ctx context.Context, network, addr string)
membantu dengan ini? apa yang perlu dilakukan
Saya baru mencuba:
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) }
Ia termasuk:
Fungsi dailan tersuaicustomDialContext
:
Fungsi ini pada masa ini merupakan pembalut ringkas net.Dial
, tetapi ia menyediakan tempat untuk memperkenalkan logik dailan tersuai jika perlu. Ia digunakan sebagai fungsi pendailan tersuai untuk membuat sambungan rangkaian.
Konfigurasi penghantaran:
http.Transport
dengan konfigurasi tetapan khusus, termasuk fungsi dailan tersuai, tetapan proksi dalam persekitaran dan konfigurasi TLS yang melangkau pengesahan sijil (untuk ujian). http.Transport
tersuai, tetapi hanya menyertakan konfigurasi TLS yang melangkau pengesahan sijil dan tidak menetapkan keupayaan dailan tersuai atau tetapan proksi. Konfigurasi pelanggan:
http.Transport
创建新的 http.Client
tersuai untuk mencipta http.Client
baharu dan menetapkan tamat masa kepada 10 saat. http.Client
baharu menggunakan tersuai http.Transport
创建新的 http.Client
,但后来在 main
函数中,它使用新的 http.Client
覆盖了 client
变量,其中包含默认的 Transport
和超时10秒的,有效丢弃自定义的 Transport
tetapi kemudian dalam fungsi main
ia menggunakan http.Client
baharu > Mengatasi pembolehubah client
, yang mengandungi Transport
lalai dan tamat masa 10 saat, dengan berkesan membuang Transport
tersuai. Tandatangan fungsi:
GetCatFact
和 GetJson
函数以接受 *http.Client
参数,允许它们使用在 main
中创建的自定义 http.Client
. http.Client
传递给这些函数,因此它们将使用 net/http
包提供的默认 http.Client
. Laman web:
GetCatFact
kepada "https://catfact.ninja/fact" memandangkan pelayan mengubah hala permintaan HTTP ke HTTPS juga. Fungsi customDialContext
函数不包含任何专门忽略 TLS 握手错误或将 TLS 握手更改为非 TLS 连接的逻辑。它只提供了自定义拨号功能,在提供的形式中,直接调用net.Dial
dalam kod yang disediakan di atas tidak mengandungi sebarang logik untuk mengabaikan ralat jabat tangan TLS secara khusus atau menukar jabat tangan TLS kepada sambungan bukan TLS. Ia hanya menyediakan fungsi dailan tersuai, dalam bentuk yang disediakan, memanggil terus
http.Transport
结构体的TLSClientConfig
字段提供的,具体是将InsecureSkipVerify
字段设置为true
Mekanisme untuk mengabaikan ralat pengesahan sijil TLS sebenarnya disediakan oleh medan TLSClientConfig
dalam
InsecureSkipVerify
kepada 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 连接。
Atas ialah kandungan terperinci Cara membetulkan proxyconnect tcp: tls: rekod pertama tidak kelihatan seperti jabat tangan TLS. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!