031.3 Урок 1
Сертифікат: |
Основи веброзробки |
---|---|
Версія: |
1.0 |
Розділ: |
031 Розробка програмного забезпечення та вебтехнології |
Тема: |
031.3 Основи HTTP |
Урок: |
1 з 1 |
Вступ
HyperText Transfer Protocol (HTTP) визначає, як клієнт запитує у сервера певний ресурс. Принцип роботи цього протоколу досить простий: клієнт створює повідомлення-запит, у якому зазначає потрібний йому ресурс, і пересилає це повідомлення на сервер через мережу. Передусім HTTP-сервер оцінює, звідки витягнути запитуваний ресурс, і надсилає клієнту відповідь. Повідомлення-відповідь містить інформацію про запитуваний ресурс, і далі безпосередньо ресурс.
Точніше, HTTP — це набір правил, які визначають, як клієнтська програма має форматувати повідомлення-запити request, які надсилатимуться на сервер. Потім сервер дотримується правил HTTP, щоб інтерпретувати запит і форматувати повідомлення-відповідь reply. Окрім запиту або передачі запитаного вмісту, HTTP-повідомлення містять додаткову інформацію про клієнта і сервер, про сам вміст і навіть про його недоступність. Якщо ресурс неможливо надіслати, код у відповіді пояснює причину недоступності та за можливості вказує, куди був переміщений ресурс.
Частина повідомлення, яка визначає інформацію про ресурс та іншу контекстну інформацію, називається header, заголовком повідомлення. Частина після заголовка, яка містить вміст відповідного ресурсу, називається payload, корисним навантаженням повідомлення. Як повідомлення-запити, так і повідомлення-відповіді можуть мати корисне навантаження, але здебільшого корисне навантаження має лише повідомлення-відповідь.
Запит клієнта
Перший етап обміну HTTP-даними між клієнтом і сервером ініціюється клієнтом, коли він пише запит серверу. Розглянемо, наприклад, звичайне завдання браузера: завантажити HTML-сторінку з сервера, на якому розміщено вебсайт, наприклад https://learning.lpi.org/en/
. Адреса або URL-адреса, містить кілька частин важливої інформації. У цьому конкретному прикладі з’являються три складові:
-
Протокол: Безпечний протокол передачі гіпертексту (
https
, HyperText Transfer Protocol Secure), шифрована версія HTTP. -
Мережне ім’я вебвузла (
learning.lpi.org
) -
Розташування запитуваного ресурсу на сервері (у цьому випадку каталог
/en/
, англійська версія домашньої сторінки).
Note
|
Uniform Resource Locator (URL) – Уніфікований покажчик інформаційного ресурсу – це адреса, яка вказує на ресурс в Інтернеті. Цей ресурс, як правило, є файлом, який можна скопіювати з віддаленого сервера, але URL-адреси також можуть вказувати на динамічно згенерований вміст і потоки даних. |
Як клієнт обробляє URL-адресу
Перш ніж зв’язатися з сервером, клієнту потрібно перетворити learning.lpi.org
на відповідну IP-адресу. Клієнт використовує іншу послугу Інтернету, Систему доменних імен (DNS, Domain Name System), щоб запитати IP-адресу для імені хоста від одного або декількох попередньо визначених DNS-серверів (сервери DNS зазвичай автоматично визначаються ISP, постачальником послуг Інтернет).
Використовуючи IP-адресу сервера, клієнт намагається підключитися до порту HTTP або HTTPS. Мережні порти — це ідентифікаційні номери, визначені Transmission Control Protocol (TCP) для ідентифікації окремих каналів зв’язку в з’єднанні клієнт/сервер. За замовчуванням HTTP-сервери отримують запити на порти TCP 80 (HTTP) і 443 (HTTPS).
Note
|
Існують інші протоколи, які використовуються вебзастосунками для реалізації зв’язку клієнт/сервер. Для аудіо- та відеодзвінків, наприклад, доцільніше використовувати WebSockets, протокол нижчого рівня, який є ефективнішим, ніж HTTP, для передачі потоків даних в обох напрямках. |
Формат повідомлення запиту, яке клієнт надсилає серверу, однаковий у HTTP і HTTPS. HTTPS вже використовується частіше, ніж HTTP, оскільки всі обміни даними між клієнтом і сервером зашифровані, що є необхідною функцією для забезпечення конфіденційності та безпеки в публічних мережах. Зашифроване з’єднання встановлюється між клієнтом і сервером ще до початку обміну будь-якими HTTP-повідомленнями за допомогою криптографічного протоколу Transport Layer Security (TLS). Таким чином, усі HTTPS-повідомлення інкапсулюються TLS. Після розшифрування запит або відповідь, передані через HTTPS, нічим не відрізняються від запиту чи відповіді, зроблених виключно через HTTP.
Третій елемент нашої URL-адреси, /en/
, буде інтерпретований сервером як розташування або шлях для запитуваного ресурсу. Якщо в URL-адресі шлях не зазначено, буде використано розташування за замовчуванням /
. Найпростіша реалізація HTTP-сервера пов’язує шляхи в URL-адресах з файлами у файловій системі, на якій працює сервер, але це лише один із багатьох варіантів, доступних на більш складних HTTP-серверах.
Повідомлення запиту
HTTP працює через з’єднання, яке вже встановлено між клієнтом і сервером, зазвичай реалізовано в TCP і зашифроване за допомогою TLS. Фактично, щойно з’єднання, яке відповідає вимогам, встановленим сервером, створене, HTTP-запит, введений вручну у вигляді простого тексту, може генерувати відповідь від сервера. Однак на практиці програмістам рідко потрібно реалізовувати підпрограми для створення HTTP-повідомлень, оскільки більшість мов програмування забезпечують механізми автоматизації створення HTTP-повідомлення. Для приклади URL-адреси, https://learning.lpi.org/en/
, найпростіше повідомлення запиту матиме наступний вміст:
GET /en/ HTTP/1.1 Host: learning.lpi.org User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0 Accept: text/html
Перше слово першого рядка ідентифікує HTTP метод. Він визначає, яку операцію клієнт хоче виконати на сервері. Метод GET інформує сервер про те, що клієнт запитує зазначений далі ресурс: /en/
. І клієнт, і сервер можуть підтримувати більше ніж одну версію протоколу HTTP, тому версія, яка використовуватиметься під час обміну даними, також зазначена в першому рядку: HTTP/1.1
.
Note
|
Найновіша версія протоколу HTTP – HTTP/2. Серед інших відмінностей, написані в HTTP/2 повідомлення кодуються у двійковій структурі, тоді як повідомлення, написані в HTTP/1.1, надсилаються у вигляді простого тексту. Ця зміна оптимізує швидкість передачі даних, але контент повідомлень здебільшого той самий. |
Заголовок може містити більше рядків після першого, щоб контекстуалізувати та допомогти ідентифікувати запит до сервера. Поле заголовка Host
, наприклад, може здатися надлишковим, тому що хост сервера, очевидно був ідентифікований клієнтом під час встановлення з’єднання, і логічно припустити, що сервер знає свою власну ідентичність. Тим не менш, важливо повідомити хосту очікуване ім’я хоста в заголовку запиту, оскільки зазвичай використовують той самий HTTP-сервер для розміщення кількох вебсайтів. (у цьому сценарії кожен конкретний хост називається віртуальним хостом.) Таким чином, поле Host
використовується сервером HTTP, щоб визначити, до якого з них відноситься запит.
Поле заголовка User-Agent
містить інформацію про клієнтську програму, яка робить запит. Це поле може використовуватися сервером для адаптації відповіді до потреб конкретного клієнта, частіше воно використовується для отримання статистики щодо клієнтів, які використовують сервер.
Поле Accept
має більш практичне значення, оскільки воно інформує сервер про формат запитуваного ресурсу. Якщо для клієнта не важливий формат ресурсу, в полі Accept
можна зазначити */*
в якості формату.
Існує багато інших полів заголовка, які можуть бути використані в HTTP-повідомленні, але полів, показаних у прикладі, достатньо для запиту ресурсу із сервера.
Крім полів у заголовку запиту, клієнт може включити інші додаткові дані до HTTP-запиту, який буде надіслано на сервер. Якщо ці дані складаються лише з простих текстових параметрів у форматі ім’я=значення
, їх можна додати до шляху, записаного в методі GET. Параметри вбудовуються в шлях після знака питання та відокремлюються символами амперсанд (&
):
GET /cgi-bin/receive.cgi?name=LPI&email=info@lpi.org HTTP/1.1
У цьому прикладі, /cgi-bin/receive.cgi
– це шлях до сценарію на сервері, який оброблятиме та, можливо, використовуватиме параметри name
та email
, отримані з шляху, зазначеного в запиті. Рядок, який відповідає цим полям у форматі name=LPI&email=info@lpi.org
, називається query string (рядок запиту) і передається скрипту receive.cgi
HTTP-сервером, який отримує запит.
Коли дані складаються з більш ніж коротких текстових полів, доцільніше надсилати їх у корисному навантаженні повідомлення. В такому випадку необхідно використовувати метод HTTP POST, щоб сервер отримував і обробляв корисне навантаження повідомлення відповідно до специфікацій, зазначених у заголовку запиту. При використанні метода POST у заголовку запиту має бути зазначений розмір корисного навантаження, яке буде надіслано далі, і спосіб форматування тіла повідомлення:
POST /cgi-bin/receive.cgi HTTP/1.1 Host: learning.lpi.org Content-Length: 1503 Content-Type: multipart/form-data; boundary=------------------------405f7edfd646a37d
У полі Content-Length
зазначається розмір корисного навантаження в байтах, а в полі Content-Type
зазначається його формат. Формат multipart/form-data
найбільш часто використовується в традиційних HTML-формах, які використовують метод POST. У цьому форматі кожне поле, вставлене до корисного навантаження запиту, відокремлюється кодом, зазначеним ключовим словом boundary
. Метод POST варто використовувати лише тоді, коли це доречно, оскільки він використовує трохи більшу кількість даних, ніж еквівалентний запит, зроблений за допомогою методу GET. Оскільки метод GET надсилає параметри безпосередньо в заголовку повідомлення запиту, загальний обмін даними має меншу затримку, оскільки додатковий етап з’єднання для передачі тіла повідомлення не потрібен.
Заголовок відповіді
Після того як HTTP-сервер отримує заголовок повідомлення запиту, сервер повертає клієнту відповідь. Запит HTML-файлу зазвичай має такий заголовок відповіді:
HTTP/1.1 200 OK Accept-Ranges: bytes Content-Length: 18170 Content-Type: text/html Date: Mon, 05 Apr 2021 13:44:25 GMT Etag: "606adcd4-46fa" Last-Modified: Mon, 05 Apr 2021 09:48:04 GMT Server: nginx/1.17.10
Перший рядок містить версію протоколу HTTP, що використовується в повідомленні відповіді, і вона повинна відповідати версії, яка використовувалась у заголовку запиту. Далі в першому рядку записаний код статусу відповіді, який вказує, як сервер інтерпретував і згенерував відповідь на запит.
Код статусу – це тризначне число, де крайня ліва цифра визначає клас відповіді. Існує п’ять класів кодів стану, пронумерованих від 1 до 5, кожен із яких вказує на тип дії, яку виконує сервер:
- 1xx (Informational)
-
Запит отримано, процес продовжується.
- 2xx (Successful)
-
Запит було успішно отримано, зрозуміло та прийнято.
- 3xx (Redirection)
-
Щоб завершити запит, необхідно виконати додаткові дії.
- 4xx (Client Error)
-
Запит містить неправильний синтаксис або не може бути виконаний.
- 5xx (Server Error)
-
Сервер не зміг виконати начебто дійсний запит.
Друга і третя цифри використовуються для позначення додаткових деталей. Код 200, наприклад, вказує, що на запит можна відповісти без проблем. Як показано в прикладі, можна також надати короткий текстовий опис після коду відповіді (OK
). Деякі конкретні коди представляють особливий інтерес для забезпечення того, що HTTP-клієнт зможе отримати доступ до ресурсу в несприятливих ситуаціях або допомогти визначити причину збою в разі невдалого запиту:
301 Moved Permanently
-
Цільовому ресурсу було призначено нову постійну URL-адресу, надану полем заголовка
Location
у відповіді. 302 Found
-
Цільовий ресурс тимчасово знаходиться за іншою URL-адресою.
401 Unauthorized
-
Запит не застосовано, оскільки в ньому відсутні дійсні облікові дані для цільового ресурсу.
403 Forbidden
-
Відповідь
Forbidden
вказує, що, хоча запит дійсний, сервер налаштований так, щоб його не обробляти. 404 Not Found
-
Початковий сервер не знайшов поточного представлення цільового ресурсу або не бажає розголошувати його існування.
500 Internal Server Error
-
Сервер зіткнувся з несподіваною умовою, яка завадила йому виконати запит.
502 Bad Gateway
-
Сервер, виконуючи роль шлюзу або проксі-сервера, отримав недійсну відповідь від вхідного сервера, до якого він звертався, намагаючись виконати запит.
Хоча ці коди вказують на те, що виконати запит було неможливо, коди статусу 4xx
і 5xx
принаймні вказують на те, що HTTP-сервер запущений і здатний отримувати запити. Коди 4xx
вимагають виконання дії на клієнті, оскільки його URL-адреса або облікові дані неправильні. На відміну від цього коди 5xx
вказують на те, що на стороні сервера щось не так. Тому в контексті вебзастосунків ці два класи кодів стану вказують на те, що джерело помилки криється в самій програмі, клієнті або сервері, а не в базовій інфраструктурі.
Статичний та динамічний контенти
HTTP-сервери використовують два основних механізми для виконання запиту клієнта. Перший механізм забезпечує статичний контент: тобто шлях, зазначений у повідомленні запиту, відповідає файлу в локальній файловій системі сервера. Другий механізм забезпечує динамічний контент: тобто сервер HTTP пересилає запит до іншої програми, ймовірно сценарію, для створення відповіді з різних джерел, таких як бази даних та інші файли.
Хоча існують різні HTTP-сервери, усі вони використовують той самий протокол зв’язку HTTP і більш-менш однакові угоди. Застосунок, який не має особливих вимог, може бути реалізований на будь-якому традиційному сервері, наприклад Apache або NGINX. Обидва здатні генерувати динамічний вміст і надавати статичний контент, але є незначні відмінності в конфігурації кожного з них.
Наприклад, місце розташування статичних файлів, які можуть надаватися клієнту, визначається різними шляхами в Apache і NGINX. Угодою є те, що ці файли знаходяться в конкретному, призначеному для цього каталозі, який має ім’я, до складу якого входить ім’я хоста, наприклад /var/www/learning.lpi.org/
. В Apache цей шлях визначається параметром DocumentRoot /var/www/learning.lpi.org
, у розділі налаштувань, який визначає віртуальний хост. У NGINX використовується параметр root /var/www/learning.lpi.org
в розділі server
файлу налаштувань.
На будь-якому іншому сервері, який ви виберете, файли з /var/www/learning.lpi.org/
будуть обслуговуватися через HTTP майже так само. Деякі поля в заголовку відповіді та їх вміст можуть бути різними для різних серверів, але такі поля, як-от Content-Type
, мають бути присутніми в заголовку відповіді та повинні бути незмінними для будь-якого сервера.
Кешування
HTTP був розроблений для роботи з будь-яким типом інтернет-з’єднання, швидким або повільним. Крім того, більшість HTTP-обмінів змушені проходити багато вузлів мережі через розподілену архітектуру Інтернету. Із цієї причини, важливо прийняти певну стратегію кешування контенту, щоб уникнути зайвої передачі раніше завантаженого вмісту. HTTP-передачі можуть працювати з двома основними типами кешу: shared та private.
Спільний кеш (shared cache) використовується більш ніж одним клієнтом. Наприклад, великий постачальник контенту може використовувати кеші на географічно розподілених серверах, щоб клієнти отримували дані з найближчого сервера. Після того, як клієнт зробив запит і його відповідь була збережена в спільному кеші, інші клієнти, які зробили такий самий запит у тій же області, отримають кешовану відповідь.
Приватний кеш (private cache) створюється самим клієнтом для його ексклюзивного використання. Це той тип кешування, який браузер виконує для зображень, CSS-файлів, JavaScript або самого HTML-документа, тому їх не потрібно завантажувати знову, якщо це буде потрібно найближчим часом.
Note
|
Не всі HTTP-запити мають бути кешовані. Запит із використанням методу POST, наприклад, передбачає відповідь, пов’язану виключно із цим конкретним запитом, тому вміст цієї відповіді не слід використовувати повторно. За замовчуванням кешуються лише відповіді на запити, зроблені за допомогою методу GET. Крім того, лише відповіді з остаточними кодами статусу, такими як-от 200 (ОК), 206 (Partial Content), 301 (Moved Permanently) та 404 (Not Found), придатні для кешування. |
Обидві стратегії, спільного і приватного кешу, використовують HTTP-заголовки для контролю того, як має кешуватися завантажений контент. Для приватного кешу клієнт звертається до заголовка відповіді та перевіряє, чи досі відповідає вміст локального кешу поточному віддаленому вмісту. Якщо це так, клієнт відмовляється від передачі корисного навантаження відповіді та використовує локальну версію.
Достовірність кешованого ресурсу можна оцінити кількома способами. Сервер може вказати дату закінчення терміну дії в заголовку відповіді для першого запиту, тож клієнт видаляє кешований ресурс після завершення терміну дії і знову запитує його, щоб отримати оновлену версію. Однак сервер не завжди може визначити дату закінчення терміну дії ресурсу, тому зазвичай використовується поле заголовка відповіді ETag
для визначення версії ресурсу, наприклад, Etag: "606adcd4-46fa"
.
Щоб переконатися, що кешований ресурс потребує оновлення, клієнт запитує із сервера лише заголовок відповіді. Якщо поле ETag
збігається з таким полем у локально збереженій версії, клієнт повторно використовує кешований контент. В іншому випадку оновлений вміст ресурсу завантажується із сервера.
HTTP-сесії
У звичайному вебсайті або вебзастосунку функції, які керують сеансом, базуються на HTTP-заголовках. Сервер не може вважати, наприклад, що всі запити, які надходять з однієї IP-адреси, надходять від одного і того самого клієнта. Найбільш традиційним методом, який дає змогу серверу асоціювати різні запити з одним клієнтом, є використання cookies, ідентифікаційного тегу, який надається клієнту сервером і передається в HTTP-заголовку.
Файли cookie дають змогу серверу зберігати інформацію про конкретного клієнта, навіть якщо особа, яка запустила клієнт, не ідентифікує себе явно. За допомогою файлів cookie можна реалізувати сеанси, де логіни, кошики для покупок, налаштування тощо зберігаються у проміжках між різними запитами, зробленими до того самого сервера, який ці файли надав. Файли cookie також використовуються для відстеження вебпереглядів користувача, тому важливо запитати його згоди перед тим, як надсилати cookie.
Сервер встановлює файл cookie в заголовку відповіді за допомогою поля Set-Cookie
. Значення поля – це пара name=value
, обрана для представлення атрибута, пов’язаного з конкретним клієнтом. Сервер може, наприклад, створити ідентифікаційний номер для клієнта, який вперше запитує ресурс, і передати його клієнту в заголовку відповіді:
HTTP/1.1 200 OK Accept-Ranges: bytes Set-Cookie: client_id=62b5b719-fcbf
Якщо клієнт дозволяє використовувати файли cookie, нові запити до того самого сервера мають поле cookie в заголовку:
GET /en/ HTTP/1.1 Host: learning.lpi.org Cookie: client_id=62b5b719-fcbf
За допомогою цього ідентифікаційного номера сервер може отримати конкретні визначення для клієнта та створити індивідуальну відповідь. Також можливо використовувати більше одного поля Set-Cookie
для доставки різних файлів cookie одному клієнту. Таким чином, на стороні клієнта можна зберегти більше одного визначення.
Файли cookie викликають як проблеми з конфіденційністю, так і потенційні діри в безпеці, оскільки є ймовірність того, що вони можуть бути передані іншому клієнту, який буде ідентифікований сервером як оригінальний клієнт. Файли cookie, які використовуються для збереження сеансів, можуть надати доступ до конфіденційної інформації від оригінального клієнта. Тому для клієнтів дуже важливо застосовувати локальні механізми захисту, щоб запобігти вилученню та повторному використанню їхніх файлів cookie без дозволу.
Вправи до посібника
-
Який HTTP-метод використовується в наступному повідомленні запиту?
POST /cgi-bin/receive.cgi HTTP/1.1 Host: learning.lpi.org User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0 Accept: */* Content-Length: 27 Content-Type: application/x-www-form-urlencoded
-
Коли на HTTP-сервері розміщено багато вебсайтів, як він визначає, якому з них призначений запит?
-
Який параметр надається рядком запиту URL
https://www.google.com/search?q=LPI
? -
Чому наступний HTTP-запит не підходить для кешування?
POST /cgi-bin/receive.cgi HTTP/1.1 Host: learning.lpi.org User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0 Accept: */* Content-Length: 27 Content-Type: application/x-www-form-urlencoded
Дослідницькі вправи
-
Як ви можете використовувати браузер для моніторингу запитів і відповідей, створених HTML-сторінкою?
-
HTTP-сервери, які надають статичний контент, зазвичай співставляють запитуваний шлях із файлом у файловій системі сервера. Що відбувається, коли шлях у запиті вказує на каталог?
-
Вміст файлів, надісланих через HTTPS, захищений шифруванням, тому вони не можуть бути прочитані комп’ютерами, які розташовані між клієнтом і сервером. Незважаючи на це, чи можуть ці комп’ютери, розташовані на шляху запиту, визначити, який ресурс клієнт запитав у сервера?
Підсумки
Цей урок охоплює основи HTTP, основного протоколу, який використовується клієнтськими програмами для запиту ресурсів із вебсерверів. В уроці розглядаються наступні поняття:
-
Повідомлення запитів, поля заголовків та методи.
-
Коди статусу відповіді.
-
Як HTTP-сервери генерують відповіді.
-
Функції HTTP, корисні для кешування та керування сесіями.
Відповіді до вправ посібника
-
Який HTTP-метод використовується в наступному повідомленні запиту?
POST /cgi-bin/receive.cgi HTTP/1.1 Host: learning.lpi.org User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0 Accept: */* Content-Length: 27 Content-Type: application/x-www-form-urlencoded
Метод POST.
-
Коли на HTTP-сервері розміщено багато вебсайтів, як він визначає, якому з них призначений запит?
Поле
Host
в заголовку запиту містить інформацію про цільовий вебсайт. -
Який параметр надається рядком запиту URL
https://www.google.com/search?q=LPI
?Параметр з іменем
q
та значеннямLPI
. -
Чому наступний HTTP-запит не підходить для кешування?
POST /cgi-bin/receive.cgi HTTP/1.1 Host: learning.lpi.org User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0 Accept: */* Content-Length: 27 Content-Type: application/x-www-form-urlencoded
Оскільки запити, зроблені за допомогою методу POST, передбачають операцію запису на сервері, їх не слід кешувати.
Відповіді до дослідницьких вправ
-
Як ви можете використовувати браузер для моніторингу запитів і відповідей, створених HTML-сторінкою?
Усі популярні браузери пропонують development tools (інструменти розробки), які, серед іншого, можуть відображати всі мережні транзакції, здійснені поточною сторінкою.
-
HTTP-сервери, які надають статичний контент, зазвичай співставляють запитуваний шлях із файлом у файловій системі сервера. Що відбувається, коли шлях у запиті вказує на каталог?
Це залежить від того, як налаштовано сервер. За замовчуванням більшість HTTP-серверів шукають файл з іменем
index.html
(або іншим попередньо визначеним ім’ям) у тому самому каталозі та надсилають його як відповідь. Якщо цього файлу там немає, сервер видає відповідь404 Not Found
. -
Вміст файлів, надісланих через HTTPS, захищений шифруванням, тому вони не можуть бути прочитані комп’ютерами, які розташовані між клієнтом і сервером. Незважаючи на це, чи можуть ці комп’ютери, розташовані на шляху запиту, визначити, який ресурс клієнт запитав у сервера?
Ні, оскільки HTTP-заголовки запиту та відповіді також шифруються за допомогою TLS.