Target <----- Internal Client -------> Proxy
Target <-----------------------------> Proxy <----> Client
目标主机:
func main() {
f, _ := os.Open("1.mp4")
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.ServeContent(w, r, "1.mp4", time.Now(), f)
})
http.ListenAndServe("127.0.0.1:3000", nil)
}
代理服务器:
type Master struct {
conn net.Conn
}
func (m *Master) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err := r.Write(m.conn); err != nil {
log.Fatal("req.Write ", err)
}
resp, err := http.ReadResponse(bufio.NewReader(m.conn), r)
if err != nil {
fmt.Printf("\nhttp.ReadResponse: ", err)
}
defer func() {
if resp.Body != nil {
Log("Close body")
if err := resp.Body.Close(); err != nil && err != io.ErrUnexpectedEOF {
fmt.Printf("\nresp.Body Close error: %s", err)
}
}
}()
copyHeader(w.Header(), resp.Header)
w.WriteHeader(resp.StatusCode)
if _, err := io.Copy(w, resp.Body); err != nil {
if isEPIPE(err) {
fmt.Println("\nClient closed the connection, couldn't copy response")
} else {
fmt.Printf("copy err: %s\n", err)
}
}
}
func main() {
var wg sync.WaitGroup
m := &Master{}
wg.Add(1)
go func() {
log.Fatal(http.ListenAndServe("localhost:8000", m))
wg.Done()
}()
go func() {
Log("start tcp server...")
ln, _ := net.Listen("tcp", ":9000")
for {
conn, _ := ln.Accept()
m.conn = conn
}
}()
wg.Wait()
}
用于代理的内部客户端(func 目标只是执行 io.Copy 然后关闭)
var wg sync.WaitGroup
wg.Add(2)
serverConn, _ := net.Dial("tcp", "127.0.0.1:9000")
targetConn, _ := net.Dial("tcp", "127.0.0.1:3000")
go func() {
transfer("server -> target", targetConn, serverConn)
wg.Done()
}()
go func() {
transfer("target -> server", serverConn, targetConn)
wg.Done()
}()
wg.Wait()
发生了什么
相反,服务器因错误而崩溃:
<块引用>客户端关闭连接,无法复制响应关闭正文
http.ReadResponse: %!(EXTRA *errors.errorString=格式错误的 HTTP 响应 "\xc9 霁ۍ^\x8aX\x17G\xee\x946\x ...
<块引用>http: panic services 127.0.0.1:50106: runtime error: invalid memory > address or nil pointer dereference
从前两行来看,原来chrome已经关闭了连接
但我就是不明白为什么和为什么 发生无效的 HTTP 响应错误 ????
任何帮助
完整的堆栈跟踪
代理服务器:
http.ReadResponse: %!(EXTRA *errors.errorString=malformed HTTP response "\xc9ޜۍ^\x8aX\x1... 2021/07/22 16:04:53 http: panic serving 127.0.0.1:50106: runtime error: invalid memory address or nil pointer dereference
goroutine 35 [running]:
net/http.(*conn).serve.func1(0xc0001300a0)
/usr/local/go/src/net/http/server.go:1824 +0x153
panic(0x12591a0, 0x143ba40)
/usr/local/go/src/runtime/panic.go:971 +0x499
main.(*Master).ServeHTTP.func1(0x0)
/Users/konstantin/goprojects/go-lab/server/server.go:44 +0x37
panic(0x12591a0, 0x143ba40)
/usr/local/go/src/runtime/panic.go:965 +0x1b9
main.(*Master).ServeHTTP(0xc000012cf0, 0x12f2af0, 0xc0002002a0, 0xc0001c2100)
/Users/konstantin/goprojects/go-lab/server/server.go:52 +0x27b
net/http.serverHandler.ServeHTTP(0xc000200000, 0x12f2af0, 0xc0002002a0, 0xc0001c2100)
/usr/local/go/src/net/http/server.go:2887 +0xa3
net/http.(*conn).serve(0xc0001300a0, 0x12f2f00, 0xc000128040)
/usr/local/go/src/net/http/server.go:1952 +0x8cd
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:3013 +0x39b