在golang中多次请求后多次关闭响应主体

时间:2016-12-29 16:32:24

标签: rest http go request response

http package godoc中,指出应关闭response.Body以避免资源泄漏。它也显示在{{3}}中的概述示例中。

在我的测试代码中,我发送了多个请求以尝试使用

的API

Canvas

在同一个函数中多次。这是一种不好的做法吗?在这种情况下,我是在每个之后写一个Paint还是只写一次?

resp, err := http.DefaultClient.Do(req)

一个相关的问题,在服务器端,即在defer resp.Body.Close()内,是否有必要关闭请求正文?

2 个答案:

答案 0 :(得分:4)

是的,您需要关闭这两个回复。将一个呼叫推迟到resp.Body.Close并不会以某种方式影响另一个。 *http.Response在每种情况下都不同,它们都可以推迟。

在服务器端,您无需关闭http.Request documentation中的Request.Body

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

答案 1 :(得分:0)

不良做法

如果你没有重用resp变量,很明显你正在处理不同的响应实例,每个响应实例都必须关闭。

  

发送HTTP请求,返回HTTP响应(实例)...

因此,不好的做法不是做几个请求,而是为多个响应重用相同的变量。它导致代码不明显。并生成无法完成的无法访问的对象。

延期执行

  

defer语句将函数调用推送到列表中。保存的调用列表在周围函数返回后执行。

如果您已经参考同一个变量安排了单个或多个defer红色执行,则只会执行分配给变量对象方法的最后一个(多次defer个)。

Playground with an example

结束Response.Body

来自Response documentation

  

打电话的责任是   关闭身体。

因此,通常您必须关闭每个Response.Body

垃圾收集和完成(编辑)

垃圾收集器调用绑定到收集对象终结器以关闭文件,连接以及执行其他清理操作。并且默认情况下没有终结器绑定到Body对象。

您改进的代码段:

// ...a lot of code
resp_one, err := http.DefaultClient.Do(req)                                 
 // BTW, `assert.Nil` just returns whether the assertion was successful (bool) not terminates a test.
if assert.Nil(t, err) == true {
    defer resp_one.Body.Close()                                                 
}

// ...a lot of code
resp_two, err = http.DefaultClient.Do(req)                                  
if assert.Nil(t, err) == true {
    defer resp_two.Body.Close()
}