func (handler Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var content string
...
w.Write([]byte(content))
}
如果len(content)〈= 2048,则在响应中自动添加content-length
,如果超过2048,则没有content-length
,添加Transfer-Encoding: chunked
。
我找不到2048年的时间。
我请求帮助找到源代码,在哪里确定2048.
2条答案
按热度按时间c9x0cxw01#
为了清楚起见,让我们看看
http.ResponseWriter
接口中此特性的文档:[I]f所有写入数据的总大小小于几KB,并且没有Flush调用,则自动添加Content-Length报头。
首先,我们可以看到这个数字可能不是2048(2 KB),但在我们预期的“几KB”范围内;其次,我们可以看到这个行为与
Flush
方法有关,该方法记录在Flusher
接口中:Flush将所有缓冲数据发送到客户端。
Flusher接口由ResponseWriters实现,它允许HTTP处理程序将缓冲数据刷新到客户端。
默认的HTTP/1.x和HTTP/2 ResponseWriter实现支持Flusher,但ResponseWriter Package 器可能不支持。处理程序应始终在运行时测试此功能。
正如上面所说,您的
ResponseWriter
可能支持数据缓冲和刷新。这意味着当您将数据写入响应写入器时,它不会立即通过连接传输。相反,它首先被写入缓冲区。每次缓冲区太满而无法再写入时,以及当ServeHTTP
方法返回时,整个缓冲区都将被传输。这确保了即使你做了很多微小的写入,数据也能有效地传输,并且所有数据最终都会被传输。您还可以选择使用Flush
方法随时主动清空缓冲区。HTTP头必须在正文数据之前发送,但是在缓冲区第一次清空之前不需要发送它们。把所有这些放在一起,你会发现如果写入的总量不超过缓冲区大小,并且我们从不调用
Flush
,那么在所有数据准备好之前不需要发送头,这时我们知道了内容长度;如果写入的总量超过缓冲区大小,那么在知道内容长度之前必须发送头。所以ResponseWriter
不能自动确定它。这是在
net/http/server.go
的源代码中实现的。具体来说,下面是缓冲区大小的声明,以及实现部分缓冲写入行为的chunkedWriter
:Link to the source code for 1.19.5。请注意,源代码可能会随着Go语言的发布而发生变化。
dfddblmv2#
该值定义如下:
写的生命解释了发生了什么:
如果处理程序没有预先声明Content-Length,我们要么进入分块模式,要么,如果处理程序在分块缓冲区大小之前完成运行,我们计算Content-Length并在头中发送它。