为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
一只萌萌小番薯 2023-06-05 17:24:16
我试图弄清楚是否有办法将分块数据发布到 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 库中找到任何文档。但我们到了。


查看完整回答
反对 回复 2023-06-05
  • 1 回答
  • 0 关注
  • 74 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信