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)
}