Завантаження великих файлів

Матеріал із PhpWiki.

На цій сторінці обговорюється доцільність завантаження великих через браузер, використовуючи протокол HTTP. Даються відповіді на ворпоси «Хто і як може обмежувати обсяг файлів, що завантажуються?» і «Чим погане завантаження великих файлів за допомогою протоколу HTTP?». Розглядаються передумови виникнення проблеми та засоби її подолання.

Зміст

Хто може обмежувати обсяг файлів, що завантажуються?

  • Сам РНР. Ретельно вивчіть всі налаштування РНР, щоб зрозуміти, як може бути обмежений обсяг файлів, що завантажуються.
  • HTTPD (наприклад, сервер Apache). Ретельно вивчіть всі налаштування сервера, щоб зрозуміти, як ваш сервер може обмежувати обсяг завантажуваних файлів.
  • Ваш браузер. Вивчіть налаштування та документацію до Вашого браузера, щоб зрозуміти, як він може обмежувати обсяг файлів, що завантажуються. Вивчіть також специфікацію HTML: багато браузери підтримують обмеження в розмірі файлів, що завантажуються, зазначені в спеціальних полях type="h > Як може бути обмежений обсяг завантажуваних файлів?
  • вказівкою максимального розміру файлів, що завантажуються (в основному – в РНР і в браузері). Наприклад, у РНР це post_max_size. У браузерах це обмеження може задаватися, наприклад, вказівкою поля type="h > Чим погане завантаження великих файлів за допомогою HTTP-протоколу?
  • При використанні повільних модемних з'єднань під час завантаження великого файлу може розірватись зв'язок. Докачати файл у такому разі не можна буде. Технічних можливостей на вирішення цієї проблеми немає.
  • у більшості FTP-браузерів завантаження файлу по ФТП виконується так само, якби Ви копіювали файли на локальному диску. З цієї точки зору, FTP-браузер зручніший для передачі файлів, ніж HTTP-браузер.

Якщо вВашому випадку це не так, це тому, і тільки тому, що Ви ніколи не працювали (або дуже рідко працюєте) з FTP-браузерами. Виберіть собі зручний FTP-браузер, користуйтеся ним постійно, і Ви виявите, що завантажувати файли з його допомогою значно простіше, ніж за допомогою HTTP-браузера.

  • на відміну від FTP-браузерів більшість HTTP-браузерів не відображають хід передачі файлів, або відображають його лише дуже приблизно. У більшості випадків HTTP-браузери не виводять час, що залишився до кінця передачі форми на сервер.
  • збільшення обсягу завантажених даних може значно знизити захищеність ваших скриптів. Проблема пов'язана з тим, що налаштування об'єму даних, що завантажуються, діють на ВСІ дані, що завантажуються.

Наприклад, якщо Ви збільшите обсяг завантажених даних до 100 МБ і в якомусь полі в одній із форм Вашого сайту, не пов'язаної із завантаженням файлів, а, наприклад, пов'язаної з модифікацією даних про користувача, Ви передаєте якийсь числовий ідентифікатор ( наприклад, номер місяця дня народження цього користувача, який, по ідеї повинен бути числом від 1 до 12), який підставляєте в SQL-запит, то Вам слід приготуватися, що злий хакер передасть в цьому полі не число від 1 до 12, а завантажить туди усі 100 МБ. Якщо Ви не налаштували Ваш сервер баз даних на обробку дуже великих запитів (за замовчуванням My SQL це близько 16 МБ), то такий запит призведе до помилки, яку і експлуатуватиме хакер.

Увага! Цей список не є списком всіх можливих уразливостей, які можуть з'явитися при перенастроюванні Ваших програм для збільшення обсягу файлів, що передаються на сервер.

У зв'язку із чим постала проблема?

Цей протокол, однак, дозволяє передавати дані від сервера. Це зроблено для того,щоб сервер міг динамічно генерувати сторінки, залежно від даних, що прийшли. Наприклад, сам Apache підтримує можливість виведення списку файлів, дозволяючи користувачам пересортувати цей перелік різними методами. Спосіб сортування задається змінною, яка передається методом GET.

Особливість TCP/IP протоколу (а саме цей протокол є наступним у стеку протоколів під час передачі даних по HTTP) у тому, що у ньому передаються не файли, а пакети. Це, крім іншого, означає, що не знаючи довжину даних неможливо сказати, коли слід завершити читання даних. Самі дані мають бути такими, щоби можна було сказати, коли вони закінчилися. Наприклад, заголовки закінчуються після приходу символу кінця рядка. А довжину тіла запиту можна зазначити в заголовках (за допомогою заголовка Content-Length). Специфікації більшості протоколів вимагають, щоб заголовки були занадто довгими; як правило, максимальна довжина одного заголовка обмежується об'ємом порядку від 256 байт до 8192 КБ.

Тому, інший недолік методу GET пов'язаний з обмеженістю обсягу змінних, що передаються. Обмеження виникло у зв'язку з обмеженням на довжину одного заголовка в HTTP-запиті та через відсутність технічної можливості вказати реальну довжину даних.

Оскільки HTTP дозволяє передавати дані, то і сам HTML включає засоби для того, щоб користувачі могли вказувати ці дані. Таким засобом є форми. Наприклад, коли Ви залишаєте повідомлення у форумі, Ви заповнюєте форму, і відправляєте її на сервер шляхом POST.

Спочатку специфікація HTTP взагалі передбачала таку можливість, як передача файлів. Однак передавати файли за допомогою форми у браузері – це часто зручна можливість, тому булавигадана окрема специфікація - розширення HTTP, яке дозволяє передавати файли (RFC 1867).

Більшість сучасних людей пам'ятають тих часів, коли через браузер не можна було передавати файли на сервер, і знають, як влаштований весь процес передачі файлів всередині. Тому, багатьом сучасним програмістам здається, що збільшення розміру файлів, що передаються по HTTP, пов'язане тільки з дописуванням нуліків (для збільшення порядку чисел) у відповідні налаштування.

Коли Ви програмуєте під Інтернет, Вам слід пам'ятати, що

  • HTTP призначений для передачі гіпертекстових сторінок від сервера до браузера користувача
  • HTTP НЕ призначений для передачі файлів від користувача на сервер

Це все тому, що:

  • FTP призначений для передачі будь-яких файлів у будь-якому напрямку
  • FTP НЕ призначений для передачі гіпертекстових сторінок

Як завантажити великі файли?

У загальному випадку рекомендується не змінювати параметри, що обмежують обсяги файлів, що завантажуються, і не завантажувати великі файли через HTTP. Але якщо наведені Вище докази Вас не переконали, і якщо Ви знаєте, що робите, навіщо, і повністю усвідомлюєте всі наслідки, то Ви можете збільшити обсяг файлів, що завантажуються.

Нескінченно збільшувати обсяг завантажених за допомогою HTTP-протоколу даних не можна. Але можна збільшувати у деяких розумних межах.

Однозначного алгоритму, який би дозволив Вам збільшити обсяг завантажуваних файлів немає, оскільки ці обсяги обмежуються невизначеним набором використовуваних Вами програм невизначеним набором способів. Деякі з цих програм і деякі способи обмеження обсягів файлів, що використовуються ними, перераховані вище.

Насамперед спробуйте збільшитизначення налаштувань, посилання на опис яких є в розділі «Як може бути обмежений обсяг файлів, що завантажуються?».

Не забувайте, що налаштування використовуваних програм можуть бути прописані у великій кількості різних місць, при цьому можуть враховуватися всі налаштування, з урахуванням пріоритету місць.

Наприклад, налаштування РНР можуть бути прописані у файлах php.ini, .htaccess, httpd.conf, а можуть задаватися безпосередньо в скрипті. У той же час виконання скрипту може задаватися функцією set_time_limit(). Багато параметрів можуть змінюватися функцією ini_set().

Налаштування сервера Apache можуть бути прописані в httpd.conf, але багато з них можуть бути перевизначені в .htaccess. Для кожного окремого каталогу діють усі .htaccess файли, знайдені у всіх батьківських каталогах. Тому, навіть якщо в поточному каталозі немає файлу .htaccess, або в ньому немає зміни потрібних налаштувань, все одно слід перевіряти всі батьківські каталоги. Більше того, налаштування можуть бути прописані у різних контекстах. Наприклад, якщо LimitRequestBody вказано в контексті , то він матиме більший пріоритет, ніж глобальне визначення. І навіть це не все: деякі налаштування можуть бути заборонені до зміни за допомогою інших налаштувань.

Слід пам'ятати, що max_execution_time і max_input_time можуть бути однаковими на різних серверах, але на швидше сервері за цей час великий файл встигне завантажитися, а на повільному сервері (або на тому ж сервері, але в моменти пікового завантаження, коли до сервера звертається багато користувачів ), при тих же налаштуваннях той самий файл вже не завантажиться.

Траплялися також випадки, коли на комп'ютері зберігається кілька копій файлів налаштувань і програміст змінює один з них, а сервер завантажує інший. Часто змінюють налаштування та забуваютьпісля цього перезавантажити сервер.

Якщо не допоможе зміна налаштувань – дотримуйтесь рекомендацій розділу «Хто може обмежувати обсяг файлів, що завантажуються?», тобто вивчіть всі налаштування (а не тільки описані в цій статті) у всіх програмах, які Ви використовуєте. Можете розпочати з пошуку всіх налаштувань, у яких зустрічається слово upload чи limit. Потім подивіться всі інші.

Якщо і це Вам не допоможе, значить, швидше за все, десь Ви припустилися помилки: або неправильно прописали налаштування, або Ваші налаштування перевизначаються в якомусь іншому місці, або їх зміна заборонена іншими налаштуваннями, або про якісь налаштування не прочитали.

Не сподівайтеся, що тут перераховані всі налаштування та всі програми, які можуть обмежувати розмір файлів, що завантажуються. Кількість деталей у цьому питанні така, що можна сказати, що

Завантаження великих файлів через HTTP – це технологія, а мистецтво.

Просте вирішення проблеми

Використовуйте FTP для завантаження великих файлів на сервер.

Якщо завантажені файли повинні якось оброблятися скриптом на мові РНР, це можна зробити, використовуючи CRON для періодичного запуску Ваших скриптів або спеціальною кнопкою в веб-інтерфейсі. При запуску Ваш скрипт шукає нові завантажені через FTP файли та обробляє їх так, як раніше Ви хотіли їх обробити, завантажуючи методом POST HTTP. Якщо Ваш локальний комп'ютер має виділений IP і Ви самі закачуєте файли на сервер

Рішення, запропоноване Кром.

На локальному комп'ютері ставиться найпростіший ftp. На сервері прописуєш ip, логін та пароль. Якщо крона немає, то просто за зверненням на сторінку на сервері перевіряєш локальний ftp, закачуєш файли на серер, автоматично робиш посилання і т.д. Тобто. взагалі без жодного втручаннявсе працює.

Якщо знадобиться опис файлів та якась додаткова інформація, то заходиш до адмінки та додаєш необхідні дані. При цьому на сторінці видається весь список завантажених файлів або тих, які ще знаходяться на локальному ftp. Під ними поля для додаткової інформації, чекбокси тощо. Заповнив все, натиснув ОК і пішов курити. Програма сама докачає необхідні файли та викладе їх у публічний доступ. Дивіться також

Корисні статті щодо завантаження файлів на сервер

Upload файлів, і все з цим пов'язане

  • Короткий екскурс у завантаження файлів, налаштування сервера, завантаження кількох файлів, автоматичне завантаження файлів на сервер, зберігання файлів у базі даних, завантаження файлів з українськими іменами, відображення статусу завантаження або progress bar, приклади скриптів.
  • Документація з РНР. Chapter 38. Handling file uploads.
  • RFC 1867. Form-based File Upload in HTML.
  • RFC 1945. Hypertext Transfer Protocol - HTTP/1.0
  • RFC 2616. Hypertext Transfer Protocol - HTTP/1.1

Програми, які можуть допомогти Вам

File Upload Applet

Mega Upload Progress Bar

Подяки

Крім. Спосіб завантаження великих файлів, якщо Ваш локальний комп'ютер має виділений IP і Ви самі закачуєте файли на сервер.