Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to put "defer req.Body.Close()"?

Tags:

go

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 put it in the end of the function or does it matter at all, and I can put it in the beginning?

like image 995
Sergei Basharov Avatar asked Mar 01 '17 07:03

Sergei Basharov


3 Answers

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.
like image 111
JimB Avatar answered Nov 01 '22 13:11

JimB


net/http

Server requests

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.
like image 9
Andrew Siplas Avatar answered Nov 01 '22 13:11

Andrew Siplas


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:

  1. If the request failed (non nil error returned) there is no Body to close, neither in a defered way nor a direct way.

  2. You must close the Body (if present) on all code paths you might take.

  3. 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.

like image 8
Volker Avatar answered Nov 01 '22 14:11

Volker