Search code examples
gohttp-status-codesstandard-library

Why couldn't Go read a request properly?


My API needs to parse incoming requests. In the first step, the data needs to be read by Go's ReadAll() function of the ioutil package. Why should there an error occur?

The official documentation does not give a hint, because the reasons for such an error aren't described.

func ParseRequest(w http.ResponseWriter, r *http.Request) {
    body, err := ioutil.ReadAll(r.Body)

    if err != nil {
        // handle the error
    }
}

Solution

  • ioutil.ReadAll can fail for many reasons. It is capable of reading any io.Reader, not just an HTTP request body. And Request.Body is just an io.ReadCloser. It is totally legal for me to generate one that is tied to things other than the network socket (I do these kinds of things to http all the time to build proxies and tunneling protocols).

    It should be obvious that many kinds of io.Reader events can have errors (you may not have access to a file for instance, or the disk may be unmounted half-way through reading it). Specific to HTTP, you might similarly expect network failure errors. What would you expect to happen if the network socket received a RST packet half-way through reading the request body?

    Ultimately, though, the point you should take away is that you must deal with errors because the Reader interface can generate errors. Do not make assumptions about how that interface is implemented.