Golang中意外的http / net响应内容长度

时间:2018-03-05 14:15:43

标签: http go get content-length

我正在使用以下代码发出HTTP Get请求。我通过Fiddler代理它来分析请求。该请求似乎正在按预期的响应正确进行。但是,GO中响应的resp.ContentLength属性为-1 尽管Fiddler中的响应显示Content-Length: 1830的正整数值。

为什么ContentLength没有在GO中被选中?

转码

package main

import "net/http"
import "os"
import "fmt"

func main() {
    os.Setenv("HTTP_PROXY", "http://127.0.0.1:8888") // For Fiddler debugging
    resp,err := http.Get("http://www.google.com/robots.txt")
    if (err == nil) {
        if (resp.StatusCode == 200) {
            fmt.Println(resp.ContentLength) // Prints -1
        }
    }
}

Fiddler中的结果请求

GET /robots.txt HTTP/1.1
Host: www.google.com
User-Agent: Go-http-client/1.1
Accept-Encoding: gzip

Fiddler收到的回复

HTTP/1.1 200 OK
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Type: text/plain
Content-Length: 6907
Date: Mon, 05 Mar 2018 13:53:00 GMT
Expires: Mon, 05 Mar 2018 13:53:00 GMT
Cache-Control: private, max-age=0
Last-Modified: Thu, 01 Mar 2018 18:00:00 GMT
X-Content-Type-Options: nosniff
Server: sffe
X-XSS-Protection: 1; mode=block

2 个答案:

答案 0 :(得分:5)

值-1表示长度未知。 (在大多数情况下,这表明 分块编码)。

答案 1 :(得分:1)

只想分享我的研究成果。

DisableCompression结构中有一个http.Transport选项,默认为falsehttp.Get使用此默认选项)。使用该选项,go的内部软件包将通过在请求中添加Accept-Encoding: gzip标头来强制进行gzip压缩。收到响应后,go的内部软件包将为我们完成解压缩工作,从而使我们不必处理gzip块。他们还会删除原来的Content-Length标头,因为它不再正确。

所有这些“幕后魔术”行为都为我们提供了此处看到的内容,但缺少Content-Length标头。

参考:https://github.com/golang/go/blob/master/src/net/http/transport.go#L182