Go的http。默认客户端块直到正文的最后一个字节?



例如,如果我有代码

t := time.Now()
http.Get("google.com")
fmt.Println(time.Now().Sub(t))

打印的持续时间是在响应正文的最后一个字节之后,还是在接收到响应标头的最后一字节之后?

文档没有明确说明这一点,但在读取响应标头后会立即返回。

一旦你对Go有了一点经验,你就会意识到,几乎每次你收到一个io.Reader(或者在这种情况下,resp.Bodyio.ReadCloser),它都是一个还没有所有数据的流式阅读器。就像调用os.Open一样,返回一些可以用作io.Reader但不读取整个文件的内容。

在Go的许多情况下,如果文档不清楚,您可以查看标准包代码以获得启示。诚然,在这种特定的情况下(与encoding/json一样),代码要做很多工作,所以乍一看很难理解。大多数标准软件包都更易于遵循和学习。

如果做不到这一点,你可以对你给出的代码进行一个小的扩展(在你自己的机器上,操场不支持建立TCP连接),以使其非常清楚:

(注意,我只是随机选择了这些URL,最好是选择一些负载很大的URL,你知道没有人会介意你为测试获取)

package main
import (
"fmt"
"io"
"io/ioutil"
"net/http"
"time"
)
func measure(url string) (t1, t2 time.Duration, n int64, err error) {
start := time.Now()
resp, err := http.Get(url)
if err != nil {
return
}
defer resp.Body.Close()
t1 = time.Since(start)
n, err = io.Copy(ioutil.Discard, resp.Body)
t2 = time.Since(start)
return
}
func main() {
for _, url := range []string{
"http://google.com/",
"http://en.wikipedia.org/",
"http://upload.wikimedia.org/wikipedia/commons/7/76/PIA02863_-_Jupiter_surface_motion_animation.gif",
} {
fmt.Printf("fetching %q ", url)
t1, t2, n, err := measure(url)
if err != nil {
fmt.Println("error:", err)
continue
}
fmt.Printf("got %d bytes in %v / %vn", n, t1, t2)
}
}

例如,在一个有点慢的连接上,上面测量的最终URL显示:597.055907ms / 29.269763851s。(也就是说,最初的Get调用返回得很快,而读取所有数据需要大约60倍的时间。)

相关内容

最新更新