Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limiting file size in FormFile

Tags:

go

I'm letting users upload a file using FormFile. At what point should I check if the file size is too large. When I do

 file, header, fileErr := r.FormFile("file")

A file object is already created. So have I incurred the cost of reading in the entire file already?

https://golang.org/pkg/net/http#Request.FormFile

like image 265
John Montague Avatar asked Jan 21 '15 17:01

John Montague


People also ask

How do I fix maximum file size exceeded in Google Forms?

Sometimes, however the issue is that a single document exceeds 35 MBs.No single document can exceed 25MB. You need to split it to two or more separate documents so that each part does not exceed 35 MBs.


2 Answers

Use http.MaxBytesReader to limit the number of bytes read from the request. Before calling ParseMultiPartForm or FormFile, execute this line:

 r.Body = http.MaxBytesReader(w, r.Body, max)

where r is the *http.Request and w is the http.Response.

MaxBytesReader limits the bytes read for the entire request body and not an individual file. A limit on the request body size can be a good approximation of a limit on the file size when there's only one file upload. If you need to enforce a specific limit for one or more files, then set the MaxBytesReader limit large enough for all expected request data and check FileHeader.Size for each file.

When the http.MaxBytesReader limit is breached, the server stops reading from the request and closes the connection after the handler returns.

If you want to limit the amount of memory used instead of the request body size, then call r.ParseMultipartForm(maxMemory) before calling r.FormFile(). This will use up to maxMemory bytes for file parts, with the remainder stored in temporary files on disk. This call does not limit the total number of bytes read from the client or the size of an uploaded file.

Checking the request Content-Length header does not work for two reasons:

  • The content length is not set for chunked request bodies.
  • The server may read the entire request body to support connection keep-alive. Breaching the MaxBytesReader limit is the only way to ensure that the server stops reading the request body.
like image 53
Bayta Darell Avatar answered Oct 17 '22 21:10

Bayta Darell


Some people are suggesting to rely on Content-Length header and I have to warn you not to use it at all. This header can be any number because it can be changed by a client regardless of the actual file size.

Use MaxBytesReader because:

MaxBytesReader prevents clients from accidentally or maliciously sending a large request and wasting server resources.

Here is an example:

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
}

If your request body is bigger than 2 Mb, you will see something like this: multipart: NextPart: http: request body too large

like image 35
Salvador Dali Avatar answered Oct 17 '22 21:10

Salvador Dali