Go 限制FormFile中的文件大小
我允许用户使用FormFile上传文件。我应该在什么时候检查文件大小是否过大。当我这样做的时候Go 限制FormFile中的文件大小,go,Go,我允许用户使用FormFile上传文件。我应该在什么时候检查文件大小是否过大。当我这样做的时候 file, header, fileErr := r.FormFile("file") 已创建文件对象。那么,我已经承担了读取整个文件的费用了吗 在请求结构和r.Header.Get(“内容长度”)字符串中有r.ContentLength int64字段。这可能会有所帮助。调用FormFile调用,它将解析整个请求体,在将内容存储到临时文件之前,默认情况下最多使用32M。在调用
file, header, fileErr := r.FormFile("file")
已创建文件对象。那么,我已经承担了读取整个文件的费用了吗
在请求结构和
r.Header.Get(“内容长度”)字符串中有r.ContentLength int64
字段。这可能会有所帮助。调用FormFile
调用,它将解析整个请求体,在将内容存储到临时文件之前,默认情况下最多使用32M。在调用FormFile
之前,您可以自己调用ParseMultiPartForm
来确定要消耗多少内存,但正文仍将被解析
客户端可能会在中提供一个内容长度
头,您可以在其中使用,但这取决于客户端
如果要限制传入请求的大小,请在解析任何正文之前,将request.Body
包装在处理程序中。用于限制从请求读取的字节数。在调用ParseMultiPartForm或FormFile之前,请执行此行:
r.Body = http.MaxBytesReader(w, r.Body, max)
其中r
是*http.Request
,w
是http.Response
MaxBytesReader限制为整个请求正文而不是单个文件读取的字节数。当只有一个文件上载时,对请求正文大小的限制可以很好地近似于对文件大小的限制。如果需要对一个或多个文件强制执行特定限制,请将MaxByteReader限制设置为足够大,以容纳所有预期的请求数据,并检查每个文件
当违反http.MaxByteReader限制时,服务器停止从请求中读取,并在处理程序返回后关闭连接
如果要限制使用的内存量而不是请求正文大小,请在调用r.FormFile()
之前调用。这将使用多达maxMemory
字节的文件部分,其余部分存储在磁盘上的临时文件中。此调用不限制从客户端读取的字节总数或上载文件的大小
检查标头不起作用,原因有两个:
- 未为分块请求正文设置内容长度
- 服务器可以读取整个请求正文以支持连接保持活动。违反MaxByteReader限制是确保服务器停止读取请求正文的唯一方法
一些人建议依赖内容长度
标题,我必须警告您不要使用它。此标头可以是任何数字,因为客户端可以更改它,而不考虑实际文件大小
使用,因为:
MaxByteReader可防止客户端意外或恶意
发送大请求并浪费服务器资源
以下是一个例子:
r.Body = http.MaxBytesReader(w, r.Body, 2 * 1024 * 1024) // 2 Mb
clientFile, handler, err := r.FormFile(formDataKey)
if err != nil {
log.Println(err)
return
}
如果您的请求正文大于2MB,您将看到如下内容:multipart:NextPart:http:request body过大
http.MaxBytesReader()
需要一个io.ReadCloser
,因此应该传递r.body
:r.body=http.MaxBytesReader(w,r.body,max)
这将限制总请求(包括所有字段+标题+文件组合)。如果只想限制每个文件(而不是文件数),请使用。请记住,您可能需要在一个请求中安全地防止攻击者上载100个不同的10MB文件。内容长度可能会被恶意用户篡改,我不会使用它,因为net/http服务器将请求体上的读取限制为内容长度头中指定的长度,恶意客户端通过指定较小的内容长度不会获得任何好处。也就是说,MaxBytesReader是一个不错的选择。