使用 golang 时是否建议(进一步)限制表单的大小?
Is it advisable to (further) limit the size of forms when using golang?
我四处搜索,据我所知,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
}
但是错误返回也会关闭连接吗?我将如何避免必须阅读所有内容?我发现了这个:,但是如果没有设置内容长度并且在阅读过程中我意识到文件太大了怎么办。
我将其用作一种安全措施,以防止有人占用我的服务器资源。
编辑:正如其他人所引用的,MaxByteReader 是受支持的方式。有趣的是,默认的 reader 是 limitreader after type asserting for max byte reader.
提交 Go 源代码的补丁并使其可配置!毕竟您正在使用一个开源项目。将 setter 添加到 http.Request 并对其进行一些单元测试可能只需要 20 分钟的工作。这里有一个硬编码的值有点笨拙,回馈并修复它:)。
如果您真的需要覆盖它,您当然可以实现自己的 ParseForm(r *http.Request)
方法。 Go 本质上是 BSD,因此您可以复制粘贴库 ParseForm 并更改限制,但这有点丑不是吗?
限制请求正文大小的正确方法是按照您的建议去做:
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。设置此标志后,服务器不会读取请求正文的其余部分,并且服务器会关闭来自处理程序的 return 上的连接。
如果您担心恶意客户端,那么您还应该设置 Server.ReadTimeout, Server.WriteTimeout and possibly Server.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 是限制请求正文大小的官方方法。
我四处搜索,据我所知,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
}
但是错误返回也会关闭连接吗?我将如何避免必须阅读所有内容?我发现了这个:,但是如果没有设置内容长度并且在阅读过程中我意识到文件太大了怎么办。
我将其用作一种安全措施,以防止有人占用我的服务器资源。
编辑:正如其他人所引用的,MaxByteReader 是受支持的方式。有趣的是,默认的 reader 是 limitreader after type asserting for max byte reader.
提交 Go 源代码的补丁并使其可配置!毕竟您正在使用一个开源项目。将 setter 添加到 http.Request 并对其进行一些单元测试可能只需要 20 分钟的工作。这里有一个硬编码的值有点笨拙,回馈并修复它:)。
如果您真的需要覆盖它,您当然可以实现自己的 ParseForm(r *http.Request)
方法。 Go 本质上是 BSD,因此您可以复制粘贴库 ParseForm 并更改限制,但这有点丑不是吗?
限制请求正文大小的正确方法是按照您的建议去做:
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。设置此标志后,服务器不会读取请求正文的其余部分,并且服务器会关闭来自处理程序的 return 上的连接。
如果您担心恶意客户端,那么您还应该设置 Server.ReadTimeout, Server.WriteTimeout and possibly Server.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 是限制请求正文大小的官方方法。