使用Golang代理时localhost超时问题求助
问题分析与解决方案
核心问题1:HTTPS访问非TLS代理端口
你的代理是纯TCP转发代理,未配置任何TLS/SSL加密逻辑,但你用https://localhost:1111访问时,客户端会发起TLS握手请求,代理无法识别并处理该握手,导致连接卡在TLS协商阶段(对应curl输出停在TLSv1.3 (OUT), TLS handshake, Client hello (1):)。
核心问题2:代理代码的响应转发方向错误
handleConn函数最后一段逻辑错误:你将客户端连接(src)的数据再次复制到目标服务器(dst),而非把目标服务器的响应(dst)转发回客户端(src),导致客户端无法收到Web应用的响应。
修正后的代理代码
调整响应转发方向,同时将log.Fatalln改为log.Println(避免单个连接错误终止整个代理程序),并补充关闭客户端连接的逻辑:
package main import ( "io" "log" "net" ) func main(){ //listen for proxy requests listener, err := net.Listen("tcp", ":1111") if err != nil { log.Fatalln("unable to bind on port") } log.Printf("binded on port 1111") for { conn, err := listener.Accept() if err != nil { log.Println("unable to accept connection:", err) continue } log.Printf("accepted connection from %s", conn.RemoteAddr()) //handling proxy request go handleConn(conn) } } func handleConn(src net.Conn) { defer src.Close() // 关闭客户端连接 //connect to the server dst, err := net.Dial("tcp", "localhost:8000") if err != nil { log.Println("unable to connect to target server:", err) return } defer dst.Close() log.Printf("connected to target server localhost:8000") //copy client request to server go func() { if _,err := io.Copy(dst, src); err != nil { log.Println("failed to copy client request to server:", err) } }() //copy server response to client if _,err := io.Copy(src, dst); err != nil { log.Println("failed to copy server response to client:", err) } }
正确的访问方式
修正代码后,使用HTTP而非HTTPS访问代理端口:
curl -v http://localhost:1111/hello
或在浏览器中输入http://localhost:1111,即可正常访问Web应用。
可选:支持HTTPS代理(进阶)
若需客户端通过HTTPS连接代理,需为代理配置TLS证书,修改监听逻辑为tls.Listen:
// 替换main函数中的监听代码 import "crypto/tls" certFile := "server.crt" keyFile := "server.key" cert, err := tls.LoadX509KeyPair(certFile, keyFile) if err != nil { log.Fatalln("failed to load certificate:", err) } config := &tls.Config{Certificates: []tls.Certificate{cert}} listener, err := tls.Listen("tcp", ":1111", config)
可通过openssl生成自签名测试证书:
openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365 -nodes
客户端访问时需信任该证书,curl可加-k参数跳过验证:
curl -v -k https://localhost:1111/hello
内容的提问来源于stack exchange,提问作者eseazywork
相关产品推荐
相关产品推荐

