Hello everyone, 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.txt") // case 1
http.ServeFile(w, r, "tmp/1.mp4") // case 2, 3
})
http.ListenAndServe("localhost:3000", nil)
case 1 - light file
case 2 - big file
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 resp.Body.Close()
copyHeader(w.Header(), resp.Header)
w.WriteHeader(resp.StatusCode)
if _, err := io.Copy(w, resp.Body); err != nil {
if isEPIPE(err) {
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) {
....
}
func isEPIPE(err error) bool {
var syscallErr syscall.Errno
b := errors.As(err, &syscallErr) && syscallErr == syscall.EPIPE
return b
}
func main() {
conn, _ := net.Dial("tcp", "localhost:3000")
server := &Server{conn}
log.Fatal(http.ListenAndServe("localhost:8000", server))
}
In case 1 everything works correctly
In case 2, when i use safari browser, everything works correctly
In case 3, when i use chrome browser, i get error syscall.EPIPE
I just can’t figure out why the client (chrome browser) closes the connection ???