登录
首页 >  Golang >  Go问答

在Go中,带有请求正文时无法捕获HTTP请求取消信号(curl、postman)

来源:stackoverflow

时间:2024-03-04 16:27:28 253浏览 收藏

从现在开始,我们要努力学习啦!今天我给大家带来《在Go中,带有请求正文时无法捕获HTTP请求取消信号(curl、postman)》,感兴趣的朋友请继续看下去吧!下文中的内容我们主要会涉及到等等知识点,如果在阅读本文过程中有遇到不清楚的地方,欢迎留言呀!我们一起讨论,一起学习!

问题内容

可以使用以下简单的 go 代码片段重现该问题:

简单的go http服务器:

package main

import (
    "fmt"
    "log"
    "net/http"
    "time"
)

func handler(w http.responsewriter, r *http.request) {
    go func(done <-chan struct{}) {
        <-done
        fmt.println("message", "client connection has gone away, request got cancelled")
    }(r.context().done())

    time.sleep(30 * time.second)
    fmt.fprintf(w, "hi there, i love %s!\n", r.url.path[1:])
}

func main() {
    http.handlefunc("/", handler)
    log.fatal(http.listenandserve(":8080", nil))
}

从http服务器上方开始,如果我使用curl(也有postman)发送一个简单的get请求,如下所示:

curl -x get http://localhost:8080/

然后按ctrl+c终止请求,然后我就可以在服务器端看到打印的消息:

message client connection has gone away, request got cancelled

以上是我期望的正确行为:模拟当客户端消失时服务器可以捕获它的情况,然后尽早取消所有不必要的工作。

但是,当我发送一个带有请求正文的 post 请求时,这种预期行为不会发生,<-done 信号被捕获,直到请求截止日期满足。

curl -X POST http://localhost:8080/ -H 'Content-Type: application/json' -d '{}'

总结我的问题:

  1. curl(postman) getpost(带或不带请求正文)请求为何以及如何产生如此大的差异?
  2. 我应该如何使用go context包正确处理这种情况,我的意思是尽快捕获客户端消失的信号,从而进一步取消服务器端不必要的工作以尽早释放资源。

正确答案


读取请求正文以检测客户端何时关闭连接:

func handler(w http.ResponseWriter, r *http.Request) {
    go func(done <-chan struct{}) {
        <-done
        fmt.Println("message", "client connection has gone away, request got cancelled")
    }(r.Context().Done())

    io.Copy(ioutil.Discard, r.Body) // <-- read the body
    time.Sleep(30 * time.Second)
    fmt.Fprintf(w, "Hi there, I love %s!\n", r.URL.Path[1:])
}

net/http 服务器通过读取连接来检查关闭的连接。在应用程序开始读取请求正文(如果有)之前,不会开始读取。

以上就是《在Go中,带有请求正文时无法捕获HTTP请求取消信号(curl、postman)》的详细内容,更多关于的资料请关注golang学习网公众号!

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