首页 > 解决方案 > resp.Body 的内容存储在哪里?

问题描述

我今天做了一个简单的 url 检索器。

1 resp, _ := http.Get("http://www.yahoo.com")
2 text, _ := ioutil.ReadAll(resp.Body)
3 resp.Body.Close()
4 fmt.Printf("%s", text)

结果按预期打印出来。但是,我不明白它为什么起作用。

我对第 2 行的理解ioutil.ReadAll(resp.Body)返回 []bytes 馈送到“文本”变量。

但:

那么,这些 resp.Body 的内容存储在哪里?(与我目前接受 Body 的内容“神奇地”来自某个地方相反)

标签: gointerface

解决方案


正如@Eklayvya 在评论中提到的,响应正文是按需流式传输的。但是要添加更多上下文。当你打电话时http.Get()。包中的Get()函数http/client初始化一个http.DefaultClient代表您使用默认 HTTP 标头和元数据创建请求的函数。

实际上,查看源代码会发现,Get它只是对http.NewRequest()创建新 HTTP 请求的更常见函数的封装。该请求是由一个底层调用创建的,该调用http.Do(req *Request)接收请求,执行额外的格式化,然后将请求发送到相关服务器。

有关更多详细信息,文件中有一个func send(ireq *Request, rt RoundTripper, deadline time.Time)实际http/client.go执行 http 请求。如果您从函数签名中注意到,它会使用您的请求和名为 a 的第二个参数RoundTripper。这是事情变得更有趣的地方。

// https://golang.org/src/net/http/client.go (line 117)
// RoundTripper is an interface representing the ability to execute a
// single HTTP transaction, obtaining the Response for a given Request.
//
// A RoundTripper must be safe for concurrent use by multiple
// goroutines.
type RoundTripper interface {
    ...
    RoundTrip(*Request) (*Response, error)
}

RoundTrip接受 aRequest并返回Response包含主体的 a。这是网络传输字节的地方,response.Body因此您可以[]byte从网络接收字节。接口的实现RoundTripper由调用者的要求决定。在这种情况下,它是http.DefaultClient. 但是,您可以覆盖它并使用它做您想做的事情。

一些网络库确实实现了这个接口。一个例子是包中的ClientConn结构golang.org/x/net/http2。第 970 行包含 a 的实现,RoundTrip其中的主体被写入其中。实现非常复杂,因为它满足并发性,以及超时和其他网络考虑。有兴趣的可以看看。

这是斑点


推荐阅读