Golang使用HTTP代理连接失败问题求助

Golang使用HTTP代理连接失败问题求助 Go版本:go1.13.5 linux/amd64

我正在使用 “x/net/proxy” 来连接 “http_proxy”。

我参考了以下代理页面:https://godoc.org/golang.org/x/net/proxy

为了获取代理信息,我将环境变量 “all_proxy” 设置为所需的代理 “http://192.130.0.10:3200”,并尝试建立 TCP 连接,但出现了以下错误:

[网络错误:socks 连接 tcp 192.130.0.10:3200->mx.eu1.mico.io:8883:读取 tcp 172.17.0.2:48118->192.130.0.10:3200:读取:连接被对端重置]

我查看了 “x/net/proxy”,似乎它不支持 “http_proxy”,而是支持 “SOCKS5” 代理。我曾为 “http_proxy” 实现过类似的代码,但不幸的是它没有工作。

我创建了一个示例代码(使用端口 1883),它在非代理环境下可以工作。请问如何启用 “http_proxy” 或 “https_proxy” 支持?

package main

import (
    "fmt"
    "os"

    "golang.org/x/net/proxy"
)

// 我们希望通过代理连接的主机地址
var host = "google.com:80"

func main() {
    fmt.Println("Inside main...")

    // 在启动应用程序之前设置代理
    if os.Getenv("http_proxy") == "" {
        os.Setenv("http_proxy", "http://192.130.0.10:3200")
    }
    os.Setenv("all_proxy", os.Getenv("http_proxy"))

    if os.Getenv("all_proxy") != os.Getenv("http_proxy") {
        fmt.Println("Environment variables are not matching...")
        return
    }

    fmt.Println("System proxy is:", os.Getenv("all_proxy"))

    proxyDialer := proxy.FromEnvironment()

    fmt.Println("Connecting to...", host)

    conn, err := proxyDialer.Dial("tcp", host)
    if err != nil {
        fmt.Println("Unable to dial...", err)
        return
    }
    fmt.Println("Connected...", conn)
}
输出:
Inside main...
System proxy is: http://192.130.0.10:3200
Connecting to... google.com:80
Unable to dial... dial tcp 172.217.23.174:80: connect: connection timed out

更多关于Golang使用HTTP代理连接失败问题求助的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang使用HTTP代理连接失败问题求助的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


golang.org/x/net/proxy 包默认只支持 SOCKS5 代理,不支持 HTTP/HTTPS 代理。你需要使用 net/http 包中的 Transport 来配置 HTTP 代理。以下是修改后的代码:

package main

import (
    "fmt"
    "net/http"
    "net/url"
    "os"
)

var host = "https://google.com"

func main() {
    fmt.Println("Inside main...")

    // 设置代理环境变量
    if os.Getenv("http_proxy") == "" {
        os.Setenv("http_proxy", "http://192.130.0.10:3200")
    }

    proxyURL, err := url.Parse(os.Getenv("http_proxy"))
    if err != nil {
        fmt.Println("Failed to parse proxy URL:", err)
        return
    }

    fmt.Println("System proxy is:", proxyURL)

    // 创建 HTTP 客户端并配置代理
    transport := &http.Transport{
        Proxy: http.ProxyURL(proxyURL),
    }

    client := &http.Client{
        Transport: transport,
        Timeout:   30 * time.Second,
    }

    fmt.Println("Connecting to...", host)

    resp, err := client.Get(host)
    if err != nil {
        fmt.Println("Request failed:", err)
        return
    }
    defer resp.Body.Close()

    fmt.Printf("Connected! Status: %s\n", resp.Status)
}

如果你需要通用的 TCP 连接(不仅仅是 HTTP),可以使用以下方法:

package main

import (
    "fmt"
    "net"
    "net/url"
    "os"
    "time"
)

var host = "google.com:80"

func main() {
    fmt.Println("Inside main...")

    if os.Getenv("http_proxy") == "" {
        os.Setenv("http_proxy", "http://192.130.0.10:3200")
    }

    proxyURL, err := url.Parse(os.Getenv("http_proxy"))
    if err != nil {
        fmt.Println("Failed to parse proxy URL:", err)
        return
    }

    fmt.Println("System proxy is:", proxyURL)

    // 通过 HTTP 代理建立 TCP 连接
    conn, err := net.DialTimeout("tcp", proxyURL.Host, 10*time.Second)
    if err != nil {
        fmt.Println("Failed to connect to proxy:", err)
        return
    }
    defer conn.Close()

    // 发送 CONNECT 请求到代理服务器
    connectReq := fmt.Sprintf("CONNECT %s HTTP/1.1\r\nHost: %s\r\n\r\n", host, host)
    _, err = conn.Write([]byte(connectReq))
    if err != nil {
        fmt.Println("Failed to send CONNECT request:", err)
        return
    }

    // 读取代理响应
    buffer := make([]byte, 4096)
    n, err := conn.Read(buffer)
    if err != nil {
        fmt.Println("Failed to read proxy response:", err)
        return
    }

    response := string(buffer[:n])
    fmt.Println("Proxy response:", response)

    // 检查响应是否包含 "200 Connection established"
    if !contains(response, "200") {
        fmt.Println("Proxy connection failed")
        return
    }

    fmt.Println("Successfully connected through HTTP proxy")
    // 现在可以通过 conn 进行数据传输
}

func contains(s, substr string) bool {
    return len(s) >= len(substr) && (s == substr || len(s) > len(substr) && (s[:len(substr)] == substr || contains(s[1:], substr)))
}

对于需要同时支持 HTTP 和 SOCKS 代理的情况:

package main

import (
    "fmt"
    "net/http"
    "net/url"
    "os"
    "time"
    "golang.org/x/net/proxy"
)

func createHTTPClient() *http.Client {
    httpProxy := os.Getenv("http_proxy")
    if httpProxy == "" {
        return &http.Client{Timeout: 30 * time.Second}
    }

    proxyURL, err := url.Parse(httpProxy)
    if err != nil {
        fmt.Println("Warning: Invalid proxy URL, using direct connection")
        return &http.Client{Timeout: 30 * time.Second}
    }

    // 检查是否是 SOCKS 代理
    if proxyURL.Scheme == "socks5" {
        dialer, err := proxy.FromURL(proxyURL, proxy.Direct)
        if err != nil {
            fmt.Println("Warning: Failed to create SOCKS dialer, using direct connection")
            return &http.Client{Timeout: 30 * time.Second}
        }

        transport := &http.Transport{
            Dial: dialer.Dial,
        }
        return &http.Client{
            Transport: transport,
            Timeout:   30 * time.Second,
        }
    }

    // HTTP/HTTPS 代理
    transport := &http.Transport{
        Proxy: http.ProxyURL(proxyURL),
    }
    return &http.Client{
        Transport: transport,
        Timeout:   30 * time.Second,
    }
}

func main() {
    client := createHTTPClient()
    resp, err := client.Get("https://google.com")
    if err != nil {
        fmt.Println("Request failed:", err)
        return
    }
    defer resp.Body.Close()
    fmt.Printf("Success! Status: %s\n", resp.Status)
}
回到顶部