Golang 中意外的 http/net 响应内容长度
Unexpected http/net response content length in Golang
我正在使用以下代码发出 HTTP Get 请求。我通过 Fiddler 代理它来分析请求。该请求似乎已正确发出,并得到了预期的响应。然而,GO中响应的resp.ContentLength
属性是-1
每次尽管 Fiddler 中的响应显示 Content-Length: 1830
.
的正整数值
为什么在 GO 中没有提取 ContentLength?
转到代码
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
值-1表示长度未知。 (在大多数情况下,这表明
分块编码)。
只是想分享我的研究。
http.Transport
结构中有一个 DisableCompression
选项,默认为 false
(http.Get
使用此默认选项)。使用该选项,go 的内部包将通过在请求中添加 Accept-Encoding: gzip
header 来强制进行 gzip 压缩。收到响应后,go的内部包会为我们做解压工作,这样我们就不用去处理gzip
chunk了。他们还删除了原来的 Content-Length
header 因为它不再正确了。
所有这些“引擎盖下的魔法”行为给了我们在这里看到的东西,缺少 Content-Length
header。
参考:https://github.com/golang/go/blob/master/src/net/http/transport.go#L182
我正在使用以下代码发出 HTTP Get 请求。我通过 Fiddler 代理它来分析请求。该请求似乎已正确发出,并得到了预期的响应。然而,GO中响应的resp.ContentLength
属性是-1
每次尽管 Fiddler 中的响应显示 Content-Length: 1830
.
为什么在 GO 中没有提取 ContentLength?
转到代码
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
值-1表示长度未知。 (在大多数情况下,这表明 分块编码)。
只是想分享我的研究。
http.Transport
结构中有一个 DisableCompression
选项,默认为 false
(http.Get
使用此默认选项)。使用该选项,go 的内部包将通过在请求中添加 Accept-Encoding: gzip
header 来强制进行 gzip 压缩。收到响应后,go的内部包会为我们做解压工作,这样我们就不用去处理gzip
chunk了。他们还删除了原来的 Content-Length
header 因为它不再正确了。
所有这些“引擎盖下的魔法”行为给了我们在这里看到的东西,缺少 Content-Length
header。
参考:https://github.com/golang/go/blob/master/src/net/http/transport.go#L182