【问题标题】:Reading and streaming responses from http servers that are using chunk transport in go从在 go 中使用块传输的 http 服务器读取和流式传输响应
【发布时间】:2016-08-31 22:49:46
【问题描述】:
我有一个通过块协议响应请求的 http 服务器。在这个简单的例子中,它每秒响应时间。我有另一台服务器将请求转发到这个时间服务器并使用相同的块协议进行响应。
curl -i localhost:8000 返回正确的东西
然而 curl -i localhost:9000 返回一个分块的响应,但仅在三秒后(不是每一秒)。这意味着不知何故 io.copy 并没有真正刷新输出,因为它来了
【问题讨论】:
标签:
http
go
chunked-encoding
【解决方案1】:
io.Copy 必须在调用Flush 之前复制整个内容。如果要在缓冲区填满之前发送内容,则需要在每次写入后自己调用flush。
在每次写入后刷新http.ResponseWriter 的完整版本的io.Copy 如下所示:
func flushCopy(dst io.Writer, src io.Reader) (written int64, err error) {
buf := make([]byte, 1024 * 8)
flusher, canFlush := dst.(http.Flusher)
for {
nr, er := src.Read(buf)
if nr > 0 {
nw, ew := dst.Write(buf[0:nr])
if nw > 0 {
if canFlush {
flusher.Flush()
}
written += int64(nw)
}
if ew != nil {
err = ew
break
}
if nr != nw {
err = io.ErrShortWrite
break
}
}
if er == io.EOF {
break
}
if er != nil {
err = er
break
}
}
return written, err
}