转到HTTP请求POST标头,等待响应,然后发布分块的正文内容



我正试图弄清楚是否有一种方法可以将分块的数据发布到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-httpRequest对象工作。

在客户端,我有一个goroutine,它是向io.PipeWriter写入数据,并且我已经将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上阻塞。我想做的是发送标题,等待服务器的响应,然后开始发送正文内容。

我尝试过简单地不将Body包括在Request对象中,这将发送标头,接收响应标头,并且连接似乎保持打开。但从我所有的阅读来看,我似乎找不到通过这种连接发送额外数据的方法。

当然,我不能在服务器端刷新并处理数据,但我实际上正在实现一个指定这种行为的协议,因此现有的客户端软件不会发送主体数据,除非它首先接收到响应标头。

所以服务器在Flush中被阻塞,因为主体仍然打开。事实证明,如果您在客户端的POST请求中将Connection标头设置为close(EDIT:您可以在刷新前在服务器响应标头中设置它,无论客户端在做什么,它都能工作),服务器将忽略主体仍然打开和刷新的事实(并保持连接打开以读取数据)。整洁的

在HTTP规范或Go HTTP库中,我似乎找不到任何描述这种行为的文档。但我们来了。

相关内容

最新更新