请求体太大,在Go中导致连接重置。

huangapple go评论70阅读模式
英文:

Request body too large causing connection reset in Go

问题

我有一个简单的多部分表单,用于上传到一个Go应用程序。我想设置上传大小的限制,所以我做了以下操作:

func myHandler(rw http.ResponseWriter, request *http.Request){  
    request.Body = http.MaxBytesReader(rw, request.Body, 1024)
    err := request.ParseMultipartForm(1024)
    if err != nil{
        // Some response.
    } 
}

每当上传的文件大小超过最大限制时,我会得到一个类似下面的连接重置的错误:
请求体太大,在Go中导致连接重置。

然而,代码仍然继续执行。我似乎无法向用户提供任何反馈。我希望不是断开连接,而是显示"您已超过大小限制"。这种情况是否可能?

英文:

I have a simple multipart form which uploads to a Go app. I wanted to set a restriction on the upload size, so I did the following:

func myHandler(rw http.ResponseWriter, request *http.Request){  
    request.Body = http.MaxBytesReader(rw, request.Body, 1024)
    err := request.ParseMultipartForm(1024)
    if err != nil{
    // Some response.
    } 
}  

Whenever an upload exceeds the maximum size, I get a connection reset like the following:
请求体太大,在Go中导致连接重置。

and yet the code continues executing. I can't seem to provide any feedback to the user. Instead of severing the connection I'd prefer to say "You've exceeded the size limit". Is this possible?

答案1

得分: 5

这段代码按预期工作。http.MaxBytesReader的描述如下:

MaxBytesReader类似于io.LimitReader,但用于限制传入请求体的大小。与io.LimitReader不同,MaxBytesReader的结果是一个ReadCloser,对于超出限制的读取会返回一个非EOF的错误,并在调用其Close方法时关闭底层读取器。

MaxBytesReader可以防止客户端意外或恶意发送大型请求,从而浪费服务器资源。

你可以使用io.LimitReader来读取指定的N个字节,然后自行处理HTTP请求。

英文:

This code works as intended. Description of http.MaxBytesReader

> MaxBytesReader is similar to io.LimitReader but is intended for
> limiting the size of incoming request bodies. In contrast to
> io.LimitReader, MaxBytesReader's result is a ReadCloser, returns a
> non-EOF error for a Read beyond the limit, and closes the underlying
> reader when its Close method is called.
>
> MaxBytesReader prevents clients from accidentally or maliciously
> sending a large request and wasting server resources.

You could use io.LimitReader to read just N bytes and then do the handling of the HTTP request on your own.

答案2

得分: 3

强制客户端停止发送数据的唯一方法是强制关闭连接,这就是你使用 http.MaxBytesReader 所做的操作。

你可以使用一个包装在 ioutil.NopCloser 中的 io.LimitReader,并通知客户端发生错误。然后,你可以检查是否还有更多的数据,并尝试在另一个限制范围内清空连接以保持其开放状态。然而,对于没有正确响应 MaxBytesReader 的客户端,这种方法可能也不起作用。

处理这种情况的优雅方式是使用 Expect: 100-continue,但这只适用于非 Web 浏览器的客户端。

英文:

The only way to force a client to stop sending data is to forcefully close the connection, which is what you're doing with http.MaxBytesReader.

You could use a io.LimitReader wrapped in a ioutil.NopCloser, and notify the client of the error state. You could then check for more data, and try and drain the connection up to another limit to keep it open. However, clients that aren't responding correctly to MaxBytesReader may not work in this case either.

The graceful way to handle something like this is using Expect: 100-continue, but that only really applies to clients other than web browsers.

huangapple
  • 本文由 发表于 2016年2月3日 18:01:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/35173819.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定