Размер загруженного файла

Предоставляются ли веб-браузерм размер файла в заголовке http при загрузке файла на сервер? И если это так, то можно ли отказаться от файла, просто прочитав заголовок и не дожидаясь завершения всего процесса загрузки?

Ответ 1

http://www.faqs.org/rfcs/rfc1867.html

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

Но длина контента не требуется, поэтому вы не можете полагаться на нее. Кроме того, злоумышленник может создать неправильную длину содержимого.

Чтение содержимого файла является единственным надежным способом. Сказав, что если длина контента присутствует и слишком велика, закрыть соединение было бы разумно.

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

Ответ 2

EDIT: прежде чем заходить слишком далеко, вы можете проверить этот другой ответ, опираясь на конфигурацию apache: Использование jQuery, ограничение размера файла перед загрузкой. описание ниже полезно только в том случае, если вам действительно нужна еще более индивидуальная обратная связь.

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

Вот пример заголовка, исходящего из формы с атрибутом enctype="multipart/form-data":

POST / HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.3) Gecko/2008092414 Firefox/3.0.3
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.7,fr-be;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Content-Type: multipart/form-data; boundary=---------------------------886261531333586100294758961
Content-Length: 135361

-----------------------------886261531333586100294758961
Content-Disposition: form-data; name=""; filename="IMG_1132.jpg"
Content-Type: image/jpeg

(data starts here and ends with -----------------------------886261531333586100294758961 )

У вас есть Content-Length в заголовке, кроме того, в заголовке файловой части есть Content-Type (каждый файл имеет свой собственный заголовок, который является целью многострочной кодировки). Помните, что ответственность браузера за установку соответствующего Content-Type зависит от типа файла; вы не можете гарантировать это, но он должен быть достаточно надежным для раннего отклонения (но вам лучше проверить весь файл, когда он будет полностью доступен).

Теперь у вас есть. Я использовал для фильтрации файлов изображений, подобных этому, но не по размеру, а по типу содержимого; но поскольку вы хотите как можно скорее остановить запрос, возникает одна и та же проблема: браузер получает ответ только после отправки всего запроса, включая содержимое формы и, следовательно, загруженные файлы.

Если вам не нужен предоставленный контент и прекратите загрузку, у вас нет выбора, кроме как зверски закрыть сокет. Пользователь увидит только сообщение "соединение reset by peer". И это отстой, но это по дизайну.

Таким образом, вы хотите использовать этот метод только в случае фоновых асинхронных проверок (используя таймер, который проверяет поле файла). Итак, у меня был этот хак:

  • Я использую jquery, чтобы сообщить мне, изменилось ли поле файла
  • Когда выбран новый файл, отключите все остальные поля файла в той же форме, чтобы получить только тот.
  • Отправить файл асинхронно (jQuery может сделать это за вас, он использует скрытый фрейм)
  • На стороне сервера проверьте заголовок (длина контента, тип содержимого,...), отключите соединение, как только получите то, что вам нужно.
  • Задайте переменную сеанса, указав, был ли этот файл в порядке или нет.
  • Клиентская сторона, так как файл загружается в кадр , вы даже не получаете никакой обратной связи, если соединение закрыто. Ваша единственная альтернатива - это таймер.
  • Клиентская сторона, таймер опроса сервера, чтобы получить статус для загруженного файла. На стороне сервера у вас установлена ​​эта переменная сессии, отправьте ее обратно в браузер.
  • Клиент имеет код состояния; отнести его к вашей форме: сообщение об ошибке, зеленая галочка/красный X, что угодно. reset поле файла или отключите форму, вы решите. Не забудьте снова включить другие поля файла.

Довольно грязно, а? Если у кого-то из вас есть лучшая альтернатива, у меня все уши.

Ответ 3

  • Я не уверен, но вы не должны доверять чему-либо, отправленному в заголовке, так как это может быть подделано пользователем.

  • Это зависит от того, как работает сервер. Например, в PHP ваш script не будет запускаться до завершения загрузки файла, поэтому это будет невозможно.