I have net/http
handlers that have defer req.Body.Close()
in each on web server side.
What is the correct place to put this in? Should I pu
What is the correct place to put this in? Should I put it in the end of the function or does it matter at all, and I can put it in the beginning?
Neither nor. Both are terribly wrong.
The defer req.Body.Close()
has become cult.
Hard facts first:
If the request failed (non nil error returned) there is no Body to close, neither in a defered way nor a direct way.
You must close the Body (if present) on all code paths you might take.
You probably do not want to close the Body before having processed it (or at least parts of it).
Back to the options in your question:
"at the beginning [of the function]": Totally wrong as Body might be nil (fact 1).
"at the end [of the function]": Totally wrong because of A) it is dangerous as you might miss a code path leaving your function (fact 2) and B) even if you equip all your function ends (i.e. returns) with defer Bod.Close()
it is totally useless to defer it instead of simply closing it via Body.Close()
.
The only sensible way of defered closing the request body is once, right after having established that Body is non-nil what means the request did not return an error.
net/http
Clarified at 2ede818, net/http
states that:
For server requests, the Request Body is always non-nil but will return EOF immediately when no body is present. The Server will close the request body. The ServeHTTP Handler does not need to.
As mentioned in the documentation, no need to explicit close it both in client and server side.
// Body is the request's body.
//
// For client requests, a nil body means the request has no
// body, such as a GET request. The HTTP Client's Transport
// is responsible for calling the Close method.
//
// For server requests, the Request Body is always non-nil
// but will return EOF immediately when no body is present.
// The Server will close the request body. The ServeHTTP
// Handler does not need to.
A request body does not need to be closed in the handler. From the http.Request documentation
// The Server will close the request body. The ServeHTTP
// Handler does not need to.
According to the Go documentation it is up to you to close the body once you are done with it.
I usually put the defer line right after the line where I check the request for errors.