【问题标题】:How to read request body twice in Golang middleware?如何在 Golang 中间件中读取请求正文两次?
【发布时间】:2018-04-07 11:11:03
【问题描述】:

在中间件中,我想读取请求正文以执行一些检查。然后,请求被传递到下一个中​​间件,在该中间件将再次读取正文。 这是我的工作:

bodyBytes, _ := ioutil.ReadAll(req.Body)
req.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
// use bodyBytes
// pass to next middleware

现在,req.Body.Close 什么都不做。由于之前的 req.Body.Close 实现做了一些连接处理,它会中断吗?

【问题讨论】:

  • Golang read request body 的相关/可能重复。
  • 我读过。在答案中,原始主体没有关闭,这令人困惑。
  • 在服务器端你不需要关闭请求体。 Request.Body:“服务器将关闭请求体。ServeHTTP Handler 不需要。”
  • 不,原来的“关闭”并没有丢失。您只需为导出的Request.Body 字段分配一个新值。这不是唯一需要关闭的对原始正文阅读器的引用。
  • 标题有误导性,应该是读取请求正文

标签: http go tcp


【解决方案1】:

由于之前的 req.Body.Close 实现做了一些连接处理,它会中断吗?

没有。

但是您的代码有问题:阅读完所有内容后,您应该关闭 req.Body。然后你像你一样构造一个新的 ReadCloser 并将它交给下一个中间件(它本身或更底层的东西负责关闭。)

bodyBytes, _ := ioutil.ReadAll(req.Body)
req.Body.Close()  //  must close
req.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))

【讨论】:

  • 谢谢。也许,我应该重新表述我的问题,因为我想得到一些理解。在 golang 客户端中,我关闭响应主体以将连接返回到池中,以便随后在其他请求中重用(如果我错了,请纠正我)。 req.body.close 在服务器中到底做了什么?
  • 我怀疑是否有一个简单的答案。首先,它可能不会在服务器中执行任何操作。在客户端上,是否重用连接也很困难,这更多地取决于客户端和服务器同意做什么,而不是您关闭主体。但是:当然,您必须关闭原始主体。我会更新我的答案。
  • 在你的代码中,不应该只在 err 为 nil 时才关闭正文吗?
  • 在服务器端你不需要关闭请求体。 Request.Body:“服务器将关闭请求体。ServeHTTP Handler 不需要。”
  • @Sergey 我不明白。您应该关闭 req.Body,即使从中读取会产生错误。这是无关的。您是否考虑不关闭请求本身会产生错误?
猜你喜欢
  • 1970-01-01
  • 2015-10-02
  • 2017-08-18
  • 2014-10-29
  • 2021-10-21
  • 2019-06-23
  • 1970-01-01
  • 2016-04-20
  • 2021-08-18
相关资源
最近更新 更多