我正在尝试确定是否有一种方法可以将分块数据发布到HTTP服务器,该服务器尝试在接受我的任何请求正文之前发送标头。
我有一个服务器,该服务器通过POST请求接收永无休止的数据流。收到新的POST请求后,它会构造标头并立即尝试刷新。
arg2
这对于使用套接字实现的POST客户端效果很好,可以在实际发送任何主体数据之前决定读取服务器响应。但是,我不知道如何使它适用于Go http Request对象。
在客户端,我有一个goroutine,它将数据写入io.PipeWriter,并且已将PipeReader(pr)传递给Request对象:
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
}
}
由于PipeReader从未关闭,并且服务器在Flush上阻塞,因此两端都将永远挂起。我想做的是发送标头,等待服务器的响应,然后开始发送正文内容。
我只是尝试在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)
,这将发送标头,接收响应标头以及连接似乎保持打开状态。但是从我的所有阅读中,我似乎找不到一种通过此连接发送其他数据的方法。
当然,我不能在服务器端刷新并处理数据-但实际上我正在实现一种协议,用于指定此行为,因此,现有的客户端软件除非先接收到主体数据,否则不会发送主体数据。响应标头。
答案 0 :(得分:0)
因此,由于主体仍处于打开状态,因此服务器在Flush中处于阻塞状态。原来,如果您在客户端的POST请求中将Connection
标头设置为close
(编辑:您可以在刷新之前在服务器响应标头中设置它,并且无论客户端在做什么,它都可以工作),服务器将忽略主体仍处于打开和冲洗状态(并保持连接打开以读取数据)这一事实。整洁。
我似乎无法在描述此行为的HTTP规范或Go http库中找到任何文档。但是我们来了。