我试图弄清楚是否有办法将分块数据发布到 HTTP 服务器,该服务器在接受我的任何请求正文之前尝试发送标头。我有一个服务器,它通过 POST 请求接收永无止境的数据流。收到新的 POST 请求后,它会构造标头并立即尝试刷新。http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { requestId := uuid.Must(uuid.NewV4()).String() w.Header().Set("X-Request-Id", requestId) w.Header().Set("Content-Type", "application/octet-stream") client := &Connection{requestId, make(chan []byte, 50), r, w} defer client.Request.Body.Close() switch client.Request.Method { case http.MethodPost: client.Writer.(http.Flusher).Flush() // goes on to read data from the connection until it is closed }}这适用于使用套接字实现的 POST 客户端,它可以决定在实际发送任何正文数据之前读取服务器响应。但是,我无法弄清楚如何让它为 Go http Request 对象工作。在客户端,我有一个正在将数据写入 io.PipeWriter 的 goroutine,并且我已将 PipeReader (pr) 传递给 Request 对象:req := &http.Request{ Method: "POST", ProtoMajor: 1, ProtoMinor: 1, URL: serverUrl, TransferEncoding: []string{"chunked"}, Body: pr, Header: make(map[string][]string),}resp, err := http.DefaultClient.Do(req)这在两端永远挂起,因为 PipeReader 永远不会关闭,并且服务器在 Flush 上阻塞。我想做的是发送标题,等待服务器的响应,然后开始发送正文内容。我试过只是不在BodyRequest 对象中包含,这会发送标头,接收响应标头,并且连接似乎保持打开状态。但是从我所有的阅读来看,我似乎无法找到一种方法来通过这个连接发送额外的数据。当然,我可以不在服务器端刷新并处理数据——但我实际上正在实现一个指定此行为的协议,因此现有的客户端软件不会发送正文数据,除非它首先收到响应标头。
1 回答
精慕HU
TA贡献1845条经验 获得超8个赞
所以服务器在 Flush 中阻塞,因为主体仍然是打开的。事实证明,如果您在客户端的 POST 请求中将Connection
标头设置为close
(编辑:您可以在刷新之前在服务器响应标头中设置它,并且无论客户端在做什么,它都有效),服务器将忽略主体仍然存在的事实无论如何打开并刷新(并保持连接打开以读取数据)。整洁的。
我似乎无法在描述此行为的 HTTP 规范或 Go http 库中找到任何文档。但我们到了。
- 1 回答
- 0 关注
- 74 浏览
添加回答
举报
0/150
提交
取消