zea*_*lot 3 http go http-content-length content-length
func (handler Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var content string
...
w.Write([]byte(content))
}
Run Code Online (Sandbox Code Playgroud)
如果 len(content) <= 2048,content-length将自动添加到响应中。如果超过2048,则没有content-length,则会Transfer-Encoding: chunked添加 。
我找不到在哪里确定2048。
我请求帮助找到在哪里确定 2048 的源代码。
http.ResponseWriter为了清楚起见,让我们看一下界面中此功能的文档:
[I]如果所有写入数据的总大小低于几 KB 并且没有 Flush 调用,则会自动添加 Content-Length 标头。
首先,我们可以看到该数字可能不完全是 2048 (2 KB),但在我们预期的“几 KB”范围内。其次,我们可以看到这种行为与方法有关Flush,该方法记录在Flusher接口中:
Flush 将所有缓冲的数据发送到客户端。
Flusher 接口由 ResponseWriter 实现,允许 HTTP 处理程序将缓冲数据刷新到客户端。
默认的 HTTP/1.x 和 HTTP/2 ResponseWriter 实现支持 Flusher,但 ResponseWriter 包装器可能不支持。处理程序应始终在运行时测试此功能。
正如它所说,您ResponseWriter可能支持数据缓冲和刷新。这意味着当您将数据写入响应写入器时,它不会立即通过连接传输。相反,它首先被写入缓冲区。每次缓冲区太满而无法再写入时,当该ServeHTTP方法返回时,整个缓冲区将被传输。这可以确保即使您进行大量微小写入,数据也能有效传输,并且所有数据最终都能传输。您还可以选择使用该方法随时主动清空缓冲区Flush。HTTP 标头必须在正文数据之前发送,但在缓冲区第一次清空之前不需要发送它们。
将所有这些放在一起,您将看到,如果写入的总量不超过缓冲区大小,并且我们从不调用Flush,则不需要发送标头,直到所有数据准备就绪,此时我们知道内容长度。如果写入的总量大于缓冲区大小,则必须在知道内容长度之前发送标头,因此ResponseWriter无法自动确定它。
这是在 中的源代码中实现的net/http/server.go。具体来说,这里是缓冲区大小的声明,以及它chunkedWriter实现部分缓冲写入行为:
// This should be >= 512 bytes for DetectContentType,
// but otherwise it's somewhat arbitrary.
const bufferBeforeChunkingSize = 2048
// chunkWriter writes to a response's conn buffer, and is the writer
// wrapped by the response.w buffered writer.
//
// chunkWriter also is responsible for finalizing the Header, including
// conditionally setting the Content-Type and setting a Content-Length
// in cases where the handler's final output is smaller than the buffer
// size. It also conditionally adds chunk headers, when in chunking mode.
//
// See the comment above (*response).Write for the entire write flow.
type chunkWriter struct {
Run Code Online (Sandbox Code Playgroud)
链接到 1.19.5 的源代码。请注意,源代码可能会随着每个 Go 版本的变化而变化。
| 归档时间: |
|
| 查看次数: |
1988 次 |
| 最近记录: |