我试图弄清楚是否有办法将分块数据发布到 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 对象中包含,这会发送标头,接收响应标头,并且连接似乎保持打开状态。但是从我所有的阅读来看,我似乎无法找到一种方法来通过这个连接发送额外的数据。
当然,我可以不在服务器端刷新并处理数据——但我实际上正在实现一个指定此行为的协议,因此现有的客户端软件不会发送正文数据,除非它首先收到响应标头。
精慕HU
相关分类