在哪里放“defer req.Body.Close()”?

时间:2017-03-01 07:18:48

标签: go

我有net/http个处理程序,每个Web服务器端都有defer req.Body.Close()

将它放入的正确位置是什么?我应该把它放在功能的最后还是重要的,我可以把它放在一开始?

5 个答案:

答案 0 :(得分:31)

请求体不需要在处理程序中关闭。来自http.Request documentation

// The Server will close the request body. The ServeHTTP
// Handler does not need to.

答案 1 :(得分:5)

  

将它放入的正确位置是什么?我应该把它放在功能的最后还是重要的,我可以把它放在一开始?

既不是也不是。两者都非常错误。

defer req.Body.Close()已成为邪教。

首先是事实:

  1. 如果请求失败(返回非零错误),则 没有要关闭的正文,无论是以推迟的方式还是以直接的方式关闭。

  2. 您必须在可能采用的所有代码路径上关闭Body(如果存在)。

  3. 您可能不希望在处理身体之前(或至少部分身体)关闭身体。

  4. 返回问题中的选项:

    • “[函数]的开头”:完全错误,因为Body可能是nil(事实1)。

    • “[函数]的末尾”:完全错误,因为A)它很危险,因为你可能会错过离开你的函数(事实2)和B)的代码路径,即使你装备了所有的功能结束(即返回)defer Bod.Close()它完全无用推迟它而不是简单地通过Body.Close()关闭它。

    只有推迟关闭请求主体的合理方式是一次,在确定Body为非零之后,意味着请求没有返回错误。

答案 2 :(得分:1)

根据Go documentation,完成后你需要关闭身体。

我通常将延迟线放在检查错误请求的行之后。

答案 3 :(得分:0)

net/http

服务器请求

2ede818作了澄清,net/http指出:

对于服务器请求,请求正文始终为非零,但在不存在正文时将立即返回EOF。 服务器将关闭请求正文。 ServeHTTP处理程序不需要。

答案 4 :(得分:0)

如文档中所述,无需在客户端和服务器端显式关闭它。

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