HTTP проти FTP

HTTP vs FTP

Ця стаття — спроба описати основні відмінності між відомими протоколами обміну даними FTP та HTTP.

Ми активно використовуємо обидва протоколи в нашому основному продукті — корпоративному месенджері MyChat уже багато років, і за цей час зіткнулися з багатьма помилками та нерозумінням роботи цих двох фундаментальних протоколів обміну файлами в Інтернеті.

Якщо ви побачите якісь помилки чи неточності, напишіть про це на форумі.

Дисклеймер: в англійській мові є два терміни: "upload" та "download". У українській мові немає хороших аналогів, тому для файлів, які ми віддаємо з клієнта на сервер, застосовуємо слово "заливати" (upload), а для файлів, які забираємо на клієнт із сервера - використовуємо слово "завантажувати" ("download").

Обидва протоколи використовуються для завантаження та заливки файлів в Інтернеті та локальних мережах. Для тексту та бінарних даних. Обидва протоколи працюють поверх TCP/IP. Але з-поміж них є декілька серйозних відмінностей.


Швидкість передачі


Напевно, найпоширеніше питання: що швидше для передачі файлів, FTP чи HTTP?

Що робить FTP швидким?

  • у переданому потоці немає мета описів, тільки чисті бінарні дані. Довідкові дані йдуть в окремому з'єднанні;
  • немає накладних витрат на перекодування даних, що передаються.

Що робить HTTP швидким?

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

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

Для одиночного файлу невеликого розміру та повільного з'єднання FTP покаже себе краще. При отриманні декількох файлів поспіль (особливо невеликих розмірів) HTTP зазвичай показує найкращий результат.


Вік


FTP (RFC959) з'явився за десять років до того, як було вигадано HTTP. На той час FTP був єдиним протоколом в Інтернеті. Перші зачатки того, що згодом стало документом RFC959, можна знайти у далекому 1971 році.


Заливка


Обидва протоколи вміють це робити. У FTP є команда "append", HTTP сповідує підхід "ось вам дані, а ви самі знаєте, що з ними робити", тобто, ніяких команд з управління файлами, що заливаються, немає.

Слід сказати, що існує протокол WebDAV, побудований поверх HTTP, який дозволяє працювати з файлами у традиційній манері, ніби вони знаходяться на вашому локальному пристрої.


Формати ASCII, EBCDIC або бінарний


FTP має уявлення про формат файлу, тому може передавати дані як у ASCII, і у двійковому вигляді (raw bytes). HTTP завжди відправляє файли в двійковому вигляді. Таким чином, FTP вміє перетворювати дані "на льоту", якщо вони передаються між системами з різними архітектурами (Windows/Linux/мейнфрейми).

Наприклад, якщо відправник використовує одну схему для кодування кінця рядка ("EOL" - End-Of-Line), а одержувач — іншу, FTP зробить так, що вони один одного зрозуміють. Unix використовує лише символ NL (newLine x0A), а MS Windows два символи поспіль, CR та LF (CarriageReturn та LineFeed - x0D0A). EBCDIC перекодування використовується на старих мейнфреймах.

HTTP, на противагу FTP, надає метадані для файлів, "Content-Type". Таким чином, метадані можуть використовуватися клієнтами для інтерпретації вмісту.


Заголовки


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


Пайплайни або конвеєри


HTTP підтримує конвеєрну обробку даних. Це означає, що клієнт може запросити нову передачу файлів до того, як закінчиться попередня, що дає можливість уникнути затримки при закачуванні декількох документів поспіль. TCP-пакети, таким чином, будуть оптимізовані для максимальної швидкості передачі.

Щось подібне, хоч і не зовсім схоже, є і у FTP. Це підтримка багатьох запитів для паралельного отримання файлів в одному керуючому з'єднанні. Звичайно, для цього потрібно використовувати нові TCP з'єднання для передачі бінарних даних, по одному для кожного файлу, однак далеко не всі FTP сервери підтримують такі можливості.


FTP команди/відповіді


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


Два з'єднання


Одна з найбільших проблем для FTP у реальній роботі — це використання двох з'єднань. Перше — для надсилання команд, що управляють, а друге — для передачі вмісту файлу. Для цього він щоразу відкриває окремий потік TCP. Якщо ви передаєте 100 файлів, по черзі буде відкрито і закрито 100 TCP-з'єднань.


Фаєрволи і NAT


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

Це також означає, що якщо обидві сторони з'єднання знаходяться за NAT, ви, скоріше всього, не зможете користуватися FTP.

Крім того, NAT вбиває незайняті з'єднання, через які тривалий час не було передачі даних. Тому, під час довгих передач FTP на повільних каналах зв'язку ми опиняємося в ситуації, коли з'єднання виявляється розірваним, тому що NAT вирішив, що воно вже неактивне.

Щоб такого не відбувалося, доводиться час від часу відправляти фіктивні порожні команди, щоби з'єднання підтримувалося в "живому" стані. Результат невеликий, але є зайвий трафік.


Активний і пасивний режими


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


Зашифровані керуючі з'єднання


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

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


Схеми авторизації


У FTP та HTTP є кілька документованих методів аутентифікації. Обидва протоколи пропонують базову автентифікацію звичайним текстом (логін/пароль). Однак, для HTTP існують декілька методів перевірки, які часто використовуються та не відправляють пароль у вигляді звичайного тексту, на відміну від FTP.


Завантаження


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


Діапазони/відноввлення завантаження


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

На противагу FTP, HTTP підтримує більш просунуті діапазони для завантаження.

Також FTP має проблеми при відновленні з'єднань при заливці або завантаженні файлів, починаючи з сегмента, більшого, ніж 2 GB.


Постійні з'єднання


HTTP-клієнт може тримати одне постійне з'єднання з сервером для будь-якої кількості передач файлів.

FTP має створювати нове з'єднання кожної нової передачі. Багаторазові виконання нових підключень погано позначаються на продуктивності через необхідність "рукостискання" (handshakes) для TCP-з'єднань.


Кодування HTTP-чанків


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

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

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


Стискання


HTTP надає серверу та клієнту можливість домовитися та вибрати один з алгоритмів стиснення. Алгоритм gzip, мабуть, найбільш широко використовується. Є більш сучасний brotli, але він ще не повністю підтримується різними серверами та клієнтами, хоча дає краще стискання (до +20%), особливо на текстових html, javascript та css файлах.

FTP надає офіційне вбудоване RLE-стискання, проте воно зазвичай неефективне для більшості бінарних і текстових даних. Є багато додаткових "хакерських" реалізацій для стиснення FTP-трафіку, але жодна з них не стала офіційною та широко використовуваною.


FXP


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


IPv6


І HTTP, і FTP відмінно працюють з IPv6, проте спочатку в оригінальній специфікації протоколу FTP не було підтримки IPv6, і тому безліч серверів досі не мають потрібних команд для його включення. Це також стосується міжмережевих екранів між клієнтами та серверами, які мають розуміти FTP.


Віртуальний хостинг на основі імені


Використовуючи HTTP 1.1, ви можете легко розмістити безліч сайтів на одному сервері, і всі вони будуть відрізнятися за їх іменами.

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


Перегляд каталогів


У FTP можна отримати список файлів з папки на віддаленому сервері, не завантажуючи їх, у той час як у HTTP немає такої можливості.

Однак, оскільки автори специфікації FTP жили у різний час, команди для отримання списку файлів у каталозі (LIST і NLST) немає чітко описаного формату виводу. Тому авторам FTP-клієнтів доводиться займатися написання синтаксичних аналізаторів тексту, щоб спробувати правильно вгадати, які саме дані їм передає сервер. Пізніші специфікації (RFC3659) передбачають нові команди типу MLSD, але вони ще не набули широкого поширення і погано підтримуються різними серверами та клієнтами.

Списки файлів у каталогах через HTTP зазвичай передаються текстом у HTML-форматі, або за допомогою WebDAV, що працює поверх HTTP.


Підтримка проксі


Одна з серйозних переваг HTTP перед FTP — це підтримка проксі, вбудована в нього з самого початку. Технологія налагоджена та дуже добре працює. Багато протоколів можуть бути інкапсульовані всередину HTTP, як у своєрідний "конверт" для проходження проксі-серверів.

FTP завжди використовувався з проксі-серверами, але це ніколи не було стандартизовано, і завжди вимагало спеціальних підходів у кожному конкретному випадку.

Служба поддержки