登录
首页 >  Golang >  Go问答

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

来源:stackoverflow

时间:2024-03-16 19:45:30 270浏览 收藏

在进行 HTTP POST 请求时,如果服务器在接受请求正文之前尝试发送标头,则需要一种方法来分块发布正文内容。通过在客户端请求中设置“Connection: close”标头,服务器可以忽略正文仍然打开的事实并刷新响应标头,从而允许客户端开始发送分块正文内容。

问题内容

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

在客户端,我有一个 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,这会发送标头,接收响应标头,并且连接似乎保持打开状态。但从我所有的阅读来看,我似乎找不到通过此连接发送附加数据的方法。

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


解决方案


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

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

以上就是《转到 HTTP 请求 POST 标头,等待响应,然后发布分块的正文内容》的详细内容,更多关于的资料请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>