Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it advisable to (further) limit the size of forms when using golang?

Tags:

go

I searched around and as far as I can tell, POST form requests are already limited to 10MB (http://golang.org/src/net/http/request.go#L721).

If I were to go about reducing this in my ServeHTTP method, I'm not sure how to properly do it. I would try something like this:

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

But would returning upon error close the connection as well? How would I prevent having to read everything? I found this: https://stackoverflow.com/a/26393261/2202497, but what if content length is not set and in the middle of reading I realize that the file is too big.

I'm using this as a security measure to prevent someone from hogging my server's resources.

like image 592
John Avatar asked Feb 02 '15 16:02

John


1 Answers

The correct way to limit the size of the request body is to do as you suggested:

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

MaxBytesReader sets a flag on the response when the limit is reached. When this flag is set, the server does not read the remainder of the request body and the server closes the connection on return from the handler.

If you are concerned about malicious clients, then you should also set Server.ReadTimeout, Server.WriteTimeout and possibly Server.MaxHeaderBytes.

If you want to set the request body limit for all of your handlers, then wrap root handler with a handler that sets the limit before delegating to the root handler:

 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)
 }

Wrap the root handler when calling ListenAndServe:

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

or when configuring a server:

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

There's no need for a patch as suggested in another answer. MaxBytesReader is the official way to limit the size of the request body.

like image 117
Bayta Darell Avatar answered Jan 02 '23 04:01

Bayta Darell