I have a file server and a proxy server through which I can access the file server via http
Simple file server :
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "tmp/1.mp4")
})
if err := http.ListenAndServe("localhost:3000", nil); err != http.ErrServerClosed {
log.Fatalf("HTTP server ListenAndServe: %v", err)
}
and proxy server :
type Server struct {
conn net.Conn
}
func (s *Server) Handle(w http.ResponseWriter, r *http.Request) error {
if err := r.Write(s.conn); err != nil {
log.Fatal("req.Write ", err)
}
resp, err := http.ReadResponse(bufio.NewReader(s.conn), r)
if err != nil {
return fmt.Errorf("http.ReadResponse: %s", err)
}
defer func() {
if resp.Body != nil {
if err := resp.Body.Close(); err != nil && err != io.ErrUnexpectedEOF {
fmt.Printf("resp.Body Close error: %s", err)
}
}
}()
copyHeader(w.Header(), resp.Header)
w.WriteHeader(resp.StatusCode)
if _, err := io.Copy(w, resp.Body); err != nil {
if err == io.ErrUnexpectedEOF {
fmt.Println("Client closed the connection, couldn't copy response")
} else {
fmt.Printf("copy err: %s\n", err)
}
}
return nil
}
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err := s.Handle(w, r); err != nil {
http.Error(w, err.Error(), http.StatusBadGateway)
}
}
func copyHeader(dst, src http.Header) {
for k, v := range src {
vv := make([]string, len(v))
copy(vv, v)
dst[k] = vv
}
}
func main() {
conn, err := net.Dial("tcp", "localhost:3000")
if err != nil {
fmt.Errorf("net.Dial(tcp, localhost:3000) %s", err)
}
server := &Server{conn}
log.Fatal(http.ListenAndServe("localhost:8000", server))
}
if the file server distributes a small picture, then everything works correctly if the file server is serving a large video file (1.mp4) then I get the error:
copy err: readfrom tcp 127.0.0.1:8000->127.0.0.1:58964: write tcp 127.0.0.1:8000->127.0.0.1:58964: write: broken pipe
What could be the problem ?
broken pipeis the golang message linked to errno 32EPIPE.When dealing with a TCP connection, it is triggered when your process writes to a connection when the other end has already closed it.
Depening on what you mean by
"Client closed the connection", if your intention is to look for an indicator that the outside client that connected to your proxy closed its connection early, then you should be looking forEPIPEerrors, not forio.ErrUnexpectedEOF.Something like :
io.ErrUnexpectedEOFcould probably occur in some situation, but it would be triggered from the connection with your file server, not from the connection initiated by the client.