请求正文时,转到http上下文无法捕获取消信号(curl,postman) [英] Go http context not able to capture cancellation signal when request has body (curl, postman)

查看:121
本文介绍了请求正文时,转到http上下文无法捕获取消信号(curl,postman)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以通过以下简单的go代码段重现该问题:

The problem can be reproduced with the below simple go code snippet:

简单的http服务器:

Simple go http server:

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服务器上方开始,如果我发送一个简单的 GET带有卷曲的请求(也有邮递员),例如:

Start above http server, if i send one simple GET request with curl(postman also) like:

curl -X GET http://localhost:8080/

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

then press Ctrl+C to terminate the request, then i am able to see the printed message at server side:

message client connection has gone away, request got cancelled

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

above is the correct behaviour i expect: to simulate the situation that when client is gone the server can capture it and then cancel all the unnecessary work as early as it can.

但是当我发送一个带有请求正文的POST请求,此预期行为不会发生,在请求截止日期之前,捕获到<完成信号。 / p>

But when i send one POST request with request body, this expected behaviour doesn't happen, the <-done signal was captured until the request deadline meet.

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

总结我的问题:


  1. 为什么以及如何卷曲(邮递员) GET POST (有或没有请求正文)请求有何不同?

  2. 我应如何正确处理这种情况? ith go上下文包,我的意思是捕获客户端尽快消失的信号,并进一步取消服务器端不必要的工作以尽早释放资源。

  1. Why and how the curl(postman) GET, POST (with or without request body) request make such a difference?
  2. How should i handle this case properly with go context package, i mean to capture the client is gone signal as soon as it can, and so further to cancel the server side unnecessary work to release the resources as early as it can.


推荐答案

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

Read the request body to detect when the client closes the connection:

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服务器通过读取连接来检查关闭的连接。在应用程序开始读取请求正文(如果有)之前,不会启动任何读取操作。

The net/http server checks for closed connections by reading the connection. No reads are started until the application starts reading the request body (if any).

这篇关于请求正文时,转到http上下文无法捕获取消信号(curl,postman)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆