io.Copy problem with chrome

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)

    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 ???

For example, the error message “ERR_CONNECTION_CLOSED” informs you that the connection to the desired website has been closed, but because it is almost impossible to correct the error, the user knows nothing. Especially because the error is not necessarily caused by Chrome.