Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why is golang http server failing with "broken pipe" when response exceeds 8kb?

I have a example web server below where if you call curl localhost:3000 -v then ^C (cancel) it immediately (before 1 second), it will report write tcp 127.0.0.1:3000->127.0.0.1:XXXXX: write: broken pipe.

package main

import (
    "fmt"
    "net/http"
    "time"
)

func main() {
    log.Fatal(http.ListenAndServe(":3000", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            time.Sleep(1 * time.Second)

            // Why 8061 bytes? Because the response header on my computer
            // is 132 bytes, adding up the entire response to 8193 (1 byte 
            // over 8kb)
            if _, err := w.Write(make([]byte, 8061)); err != nil {
                    fmt.Println(err)
                    return
            }   
    })))
}

Based on my debugging, I have been able to conclude that this will only happen if the entire response is writing more than 8192 bytes (or 8kb). If my entire response write less than 8192, the broken pipe error is not returned.

My question is where is this 8192 bytes (or 8kb) buffer limit set? Is this a limit in Golang's HTTP write buffer? Is this related to the response being chunked? Is this only related to the curl client or the browser client? How can I change this limit so I can have a bigger buffer written before the connection is closed (for debugging purposes)?

Thanks!

like image 861
eldosoa Avatar asked Apr 03 '17 16:04

eldosoa


People also ask

What causes a broken pipe error?

This error generally means means that the data stopped flowing to us and we were unable to start the transfer again. Often times this is caused by a wireless internet connection with fluctuating signal strength, a firewall or other security software.

What is broken pipe error Golang?

The broken pipe is a TCP/IP error occurring when you write to a stream where the other end (the peer) has closed the underlying connection. The first write to the closed connection causes the peer to reply with an RST packet indicating that the connection should be terminated immediately.

What is broken pipe error in Linux?

A broken Pipe Error is generally an Input/Output Error, which is occurred at the Linux System level. The error has occurred during the reading and writing of the files and it mainly occurs during the operations of the files.


1 Answers

In net/http/server.go the output buffer is set to 4<<10, i.e. 4KB.

The reason you see the error at 8KB, is that it takes at least 2 writes to a socket to detect a closed remote connection. The first write succeeds, but the remote host sends an RST packet. The second write will be to a closed socket, which is what returns the broken pipe error.

Depending on the socket write buffer, and the connection latency, it's possible that even more writes could succeed before the first RST packet is registered.

like image 72
JimB Avatar answered Sep 17 '22 14:09

JimB