在使用golang时,是否建议(进一步)限制表单的大小?

时间:2015-02-02 16:35:40

标签: go

我四处搜索,据我所知,POST表单请求已限制为10MB(http://golang.org/src/net/http/request.go#L721)。

如果我要在我的ServeHTTP方法中减少这个,我不确定如何正确地做到这一点。我会尝试这样的事情:

r.Body = http.MaxBytesReader(w, r.Body, MaxFileSize) 
err := r.ParseForm()
if err != nil {
     //redirect to some error page
     return
}

但是错误时会返回关闭连接吗?我怎么能阻止阅读所有内容?我发现了这个:https://stackoverflow.com/a/26393261/2202497,但是如果没有设置内容长度并且在阅读过程中我意识到文件太大了怎么办。

我将此作为一项安全措施,以防止有人占用我服务器的资源。

2 个答案:

答案 0 :(得分:25)

限制请求正文大小的正确方法是按照您的建议执行:

r.Body = http.MaxBytesReader(w, r.Body, MaxFileSize) 
err := r.ParseForm()
if err != nil {
 // redirect or set error status code.
 return
}

MaxBytesReader在达到限制时设置flag on the response。设置此标志后,服务器不会读取请求正文的其余部分,服务器会在从处理程序返回时关闭连接。

如果您担心恶意客户,那么您还应该设置Server.ReadTimeoutServer.WriteTimeoutServer.MaxHeaderBytes

如果要为所有处理程序设置请求主体限制,请使用在委派给根处理程序之前设置限制的处理程序包装根处理程序:

 type maxBytesHandler struct {
     h http.Handler
     n int64
 }

 func (h *maxBytesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
     r.Body = http.MaxBytesReader(w, r.Body, h.n) 
     h.h.ServeHTTP(w, r)
 }

调用ListenAndServe时包装根处理程序:

log.Fatal(http.ListenAndServe(":8080", &maxBytesHandler{h:mux, n:4096))

或配置服务器时:

s := http.Server{
    Addr: ":8080",
    Handler: &maxBytesReader{h:mux, n:4096},
}
log.Fatal(s.ListenAndServe())

根据另一个答案的建议,不需要补丁。 MaxBytesReader是限制请求体大小的官方方式。

答案 1 :(得分:0)

编辑:正如其他人所说,MaxByteReader是受支持的方式。有趣的是,默认阅读器是在为最大字节读取器声明类型之后的limitreader。

向Go源代码提交补丁并使其可配置!毕竟,您正在使用开源项目。将一个setter添加到http.Request并为它进行一些单元测试可能只需要20分钟的工作量。在这里有一个硬编码的值有点笨重,回馈并修复它:)。

如果你真的需要覆盖它,你当然可以实现自己的ParseForm(r *http.Request)方法。 Go本质上是BSD,所以你可以复制粘贴库ParseForm并更改限制,但那有点难看没有?