【问题标题】:Is an http.Request.Body buffered in golang?http.Request.Body 是否在 golang 中缓冲?
【发布时间】:2015-02-11 16:57:46
【问题描述】:

我正在用 Go 编写一个网络应用程序。我有一个 http.Handler 做一些事情并写一个响应。

func (h *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    // do some stuff
}

到目前为止,我在 POST 和 GET 请求之间没有做任何不同的事情,这在通常情况下很好。

但是 POST 有一个 Request.Body

该 POST 数据会发生什么变化?去缓冲它吗?我的处理程序是立即调用,还是等到 POST 完全收到?


为了提供一些背景信息,我特别关注slow loris 攻击。

我知道 Go 的每个连接开销非常低,但是 POST 大量数据呢?如果我发布 9Mb 的数据,然后一次勺喂 1 个字节,那么如何处理呢?它是否缓冲了内存中的 9Mb?如果我做 10,000 个这样的请求,那可能是 90Gb 的缓冲 POST 数据。我的服务器不会很喜欢这样。

【问题讨论】:

    标签: security http go


    【解决方案1】:

    其中涉及到一些缓冲,但处理程序会立即被调用,由您来读取 request.Body。

    就慢速客户端的资源消耗,特别是像slowloris这样的攻击而言,最简单的解决方案是在您的服务器上设置ReadTimeout

    【讨论】:

    • 所以如果我不对 request.Body 做任何事情(比如我的幼稚处理程序)并开始写响应,会丢弃那些 request.Body 字节吗?我认为在开始回写 TCP 连接之前需要读取整个请求。
    • 不,当缓冲区填满时客户端将被阻塞,并且 TCP 背压阻止它们发送更多。 go 服务器很乐意立即为您编写响应,但大多数客户端不会同时读取并且在尝试发送时不会看到它。如果您期待一个正文,如果您希望客户得到响应,您应该阅读它。
    • 谢谢,我认为这有帮助。那么如果没有 ReadTimeout,一切都会陷入僵局吗?客户端等待服务器接收,服务器等待客户端接收?并且服务器在某处的缓冲区中有几 kB?
    • 如果您的响应足够大,它可以。在缓冲的 io 和两侧的 tcp 缓冲区之间,将立即发送简单的响应。
    猜你喜欢
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 2015-12-22
    • 2016-08-30
    • 2015-11-17
    • 2020-09-03
    • 2011-03-22
    • 2016-10-08
    相关资源
    最近更新 更多