2015-01-21 5 views
4

Я разрешаю пользователям загружать файл с помощью FormFile. В какой момент я должен проверить, слишком ли большой размер файла. Когда я делаюОграничение размера файла в FormFile

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

Файл-объект уже создан. Так что я уже понес расходы на чтение во всем файле?

ответ

1

У вас есть r.ContentLength int64 Поле в запросе struct и r.Header.Get("Content-Length") string метод. Может быть, это может помочь.

3

Вызов FormFile вызывает ParseMultiPartForm, который будет анализировать весь тело запроса, используя до 32M по умолчанию, прежде чем хранить содержимое во временных файлах. Вы можете позвонить ParseMultiPartForm непосредственно перед вызовом FormFile, чтобы определить, сколько памяти нужно потреблять, но тело все равно будет разобрано.

Почтовый клиент может предоставить заголовок Content-Length в multipart.FileHeader, который вы можете использовать, но это зависит от клиента.

Если вы хотите ограничить размер входящего запроса, заверните request.Body с помощью MaxBytesReader в вашем обработчике, прежде чем разбирать любой из тел.

4

Используйте MaxBytesReader, чтобы ограничить размер запроса. Перед вызовом ParseMultiPartForm или FormFile, выполнить эту строку:

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

где r является *http.Request и w является http.Response.

Это ограничивает размер всего тела запроса, а не отдельного файла. Если вы загружаете один файл за раз, ограничение размера тела запроса должно быть хорошим приближением к ограничению размера файла.

Если вы хотите ограничить объем используемой памяти вместо размера тела запроса, позвоните по телефону r.ParseMultipartForm(maxMemory) перед вызовом r.FormFile(). Это будет использовать до maxMemory байт для частей файла, а оставшаяся часть хранится во временных файлах на диске.

+0

'http.MaxBytesReader()' 'ожидает И.О. .ReadCloser', поэтому 'r.Body' следует передавать вместо просто' r': 'r.Body = http.MaxBytesReader (w, r.Body, max)' – icza

+0

Это ограничит общий запрос (включая все поля + заголовки + файлы вместе).Если вы хотите ограничить каждый файл (а не количество файлов), используйте [r.ParseMultipartForm (MaxSize)] (https://golang.org/pkg/net/http/#Request.ParseMultipartForm). Имейте в виду, что вам может понадобиться обе, чтобы быть в безопасности от злоумышленников, загружающих 100 разных 10 МБ файлов в один запрос. – Xeoncross

2

Некоторые люди предлагают полагаться на заголовок Content-Length, и я должен предупредить вас, чтобы он не использовал его вообще. Этот заголовок может быть любым числом, потому что он может быть изменен клиентом независимо от фактического размера файла.

MaxBytesReader Использование потому что:

MaxBytesReader предотвращает клиентов от случайного или злонамеренно отправки большого запроса и тратить ресурсы сервера.

Вот пример:

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 
} 

Если тело запроса больше 2 Мб, вы увидите что-то вроде этого: multipart: NextPart: http: request body too large

Смежные вопросы