Кратко
Секция статьи "Кратко"HTTP был разработан как протокол обмена данными между веб-сервером и веб-браузером. Это протокол прикладного уровня модели OSI, который используется для передачи между клиентом и сервером файлов HTML, CSS, JS, API, картинок, аудио, видео, введённых пользователем данных и прочего. Клиент (веб-браузер) отправляет серверу (веб-серверу) запросы и получает от него ответы. Сервер в рамках протокола HTTP практически всегда занимает пассивную позицию.
Как понять
Секция статьи "Как понять"Есть три главных объекта, которые обмениваются сообщениями:
- Клиент (user agent) — программа, которая отправляет запросы, получает и обрабатывает ответы от имени пользователя на устройстве пользователя, например, браузер.
- Сервер (веб-сервер) — программа, которая работает на сервере, принимает и обрабатывает запросы от клиента, а затем отправляет ответы клиенту. Этой программой является веб-сервер.
- Прокси (прокси-сервер) — программа, которая работает на сервере, пропускает через себя запросы и ответы и выступает в роли посредника между клиентом и сервером.
На первом этапе клиент устанавливает соединение с сервером с помощью протокола транспортного уровня TCP. Клиент может переиспользовать одно и то же соединение для работы с сервером или создавать его каждый раз. Это зависит от задачи, конфигурации сети и конкретных настроек оборудования. После установки соединения клиент посылает HTTP-сообщение с телом и параметрами запроса. Сервер принимает это сообщение и на основании логики работы бэкенда формирует и отправляет HTTP-сообщение ответа.
Протокол HTTP не хранит состояние, поэтому количество соединений не приводит к существенному усложнению взаимодействия между объектами системы. Однако существует понятие сессии, с помощью которой можно передавать и хранить необходимые данные, относящиеся в конкретному сеансу связи. Данные сессии сохраняются на клиенте и на сервере. Например, доступен идентификатор сессии, который позволяет не проводить авторизацию клиента при каждом обращении к серверу.
Прокси-серверы осуществляют сервисные функции:
- Кэшировать данные запроса или ответа для улучшения производительности и снижения сетевого трафика.
- Фильтровать данные. Например, можно сканировать данные антивирусом или использовать родительский контроль.
- Осуществлять балансировку нагрузки, распределяя запросы между разными серверами.
- Проводить аутентификацию клиентов для управления доступом к ресурсам.
- Хранить информацию о запросах клиентов и ответах сервера, реализуя таким образом логирование.
- Обнаруживать некоторые типы атак на сетевой узел (например, определение подозрительного трафика или DDoS-атаки).
Формат сообщения
Секция статьи "Формат сообщения"HTTP-сообщение представляет собой обычный текст. Структура сообщения строго определена:
- Стартовая строка;
- Заголовки, передают сервисную информацию;
- Тело сообщения, представляет данные в текстовом виде.
Тело сообщения — это опциональная часть сообщения, которая может отсутствовать. Например, для некоторых GET-запросов (то есть запросов со стороны клиента, в качестве метода получения данных для которого выбран метод GET
) или для всех HEAD-запросов. Если тело сообщения присутствует, то это обозначается заголовками Content
или Transfer
.
Стартовая строка
Секция статьи "Стартовая строка"Стартовая строка запроса содержит информацию о методе запроса, относительном адресе и версии протокола в формате Метод URI HTTP
. Стартовая строка ответа содержит версию протокола, код и статус ответа сервера в формате HTTP
.
Когда браузер посылает запрос на открытие главной страницы сайта, стартовая строка запроса будет такой:
GET / HTTP/1.1
GET / HTTP/1.1
Если страница существует и к ней есть доступ, то стартовая строка ответа будет такой:
HTTP/1.1 200 OK
HTTP/1.1 200 OK
Методы запроса описывают тип обработки данных, который клиент хочет осуществить. Доступны следующие методы:
OPTIONS
— используется для определения возможностей сервера по преобразованию данных.GET
— используется для получения данных от сервера.HEAD
— то же, что иGET
, но не содержит тело в сообщении ответа.POST
— используется для отправки данных на сервер.PUT
— используется для добавления новых или изменения существующих данных на сервере.PATCH
— то же, что иPUT
, но используется для обновления части данных.DELETE
— используется для удаления данных на сервере.TRACE
— возвращает запрос от клиента таким образом, что в ответе содержится информация о преобразованиях запроса на промежуточных серверах.CONNECT
— переводит текущее соединение в TCP/IP-туннель. Обычно этот метод используется для установления защищённого SSL-соединения.
Код состояния в ответе сервера содержит информацию о результате обработки данных. Существует пять классов кодов состояний:
1xx
— обработка данных на сервере продолжается;2xx
— успешная обработка данных;3xx
— перенаправление запросов;4xx
— ошибка по вине клиента;5xx
— ошибка по вине сервера.
Самые популярные ответы сервера (коды состояния и статусы):
200 OK
в случае успешной обработки запроса.301 Moved Permanently
если редирект используется на постоянной основе.307 Temporary Redirect
если редирект используется временно.400 Bad Request
если в запросе есть синтаксическая ошибка.403 Forbidden
если запрос успешный, но сервер его не может выполнить, поскольку пользователь не имеет достаточных прав.404 Not Found
если запрошенного ресурса не существует.500 Internal Server Error
если работа программы на сервере выдала ошибку.
Все возможные статусы описаны в реестре кодов, а так же на справочных ресурсах.
Использование заголовков
Секция статьи "Использование заголовков"Заголовки делятся на четыре группы:
- Основные заголовки, которые могут включаться в любые сообщения клиента и сервера.
- Заголовки запроса, которые используются только в сообщениях клиента.
- Заголовки ответа, которые используются только в сообщениях сервера.
- Заголовки сущности, которые описывают данные в сообщении.
Заголовки принято группировать в соответствии со списком выше и посылать их в соответствующем списку порядке. В стандартах для каждой версии HTTP описано довольно много заголовков, но можно использовать и свои.
В заголовках указывается разная необходимая для работы веб-сервера или клиента информация. Например, есть адрес домена, к которому обращается клиент или информация об авторизации пользователя. Также заголовки могут содержать информацию о настройках кэширования на клиенте и сервере, формате передаваемых данных, языке, последних дате и времени модификации данных и так далее.
Приведём пример. Для экономии трафика часто используют сжатие данных: архивация данных перед пересылкой и разархивация после пересылки. Для этого применяют несколько алгоритмов сжатия. Например, часто применяется gzip, но наиболее интересным и современным является brotli.
Для того чтобы пользоваться сжатием, необходимо дать понять клиенту и серверу, что это вообще возможно и какой алгоритм сжатия применять. Выбор конкретного алгоритма обусловлен несколькими специфическими причинами. Например, программная поддержка на клиенте (чаще всего клиентом является браузер), реализация сжатия на сервере, особенности пересылаемых данных. В любом случае клиент должен сообщить серверу, что сжатие поддерживается, сервер должен сообщить клиенту, что данные сжаты и их необходимо распаковать перед использованием.
Например, для того чтобы сообщить серверу о поддержке сжатия в форматах gzip, br или deflate, нужно использовать заголовок:
Accept-Encoding: gzip, br, deflate
Accept-Encoding: gzip, br, deflate
Сервер для передачи данных в сжатом формате gzip должен послать заголовок:
Content-Encoding: gzip
Content-Encoding: gzip
Тело сообщения
Секция статьи "Тело сообщения"Формат данных тела сообщения может быть нескольких типов, которые закреплены в спецификациях HTTP-протокола различных версий (HTTP/1.0 (стандарт RFC 1945), HTTP/1.1 (стандарт RFC 2616), HTTP/2 (черновик стандарта), HTTP/3 (черновик стандарта)). Чаще всего встречаются типы:
- text/html.
- application/json.
- multipart/form-data.
На практике
Секция статьи "На практике"Просмотр HTTP-сообщений из командной строки
Секция статьи "Просмотр HTTP-сообщений из командной строки"В мире Unix-подобных операционных систем есть многофункциональная утилита curl, которая позволяет работать с протоколом HTTP. С одной стороны, с её помощью можно скачивать файлы, отправлять данные пользователей на сервер аналогично тому, как это делается через формы на сайтах, работать с API и даже отправлять письмо. С другой, это отличный способ познакомиться с работой протокола или протестировать веб-приложение, которое работает на стороне сервера.
Чтобы скачать главную страницу какого-то сайта (например, http://example.com), можно воспользоваться командой:
curl http://example.com
curl http://example.com
В терминале вы увидите HTML-код страницы — это тело сообщения ответа. Существует возможность посмотреть и полные сообщения запроса и ответа, добавив ключ
:
curl -v http://example.com* Trying 93.184.216.34...* TCP_NODELAY set* Connected to example.com (93.184.216.34) port 80 (#0)> GET / HTTP/1.1> Host: example.com> User-Agent: curl/7.64.1> Accept: */*>< HTTP/1.1 200 OK< Age: 258083< Cache-Control: max-age=604800< Content-Type: text/html; charset=UTF-8< Date: Thu, 22 Jul 2021 15:42:57 GMT< Etag: "3147526947+ident"< Expires: Thu, 29 Jul 2021 15:42:57 GMT< Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT< Server: ECS (dcb/7F17)< Vary: Accept-Encoding< X-Cache: HIT< Content-Length: 1256<<!doctype html><html>* Connection #0 to host example.com left intact* Closing connection 0
curl -v http://example.com * Trying 93.184.216.34... * TCP_NODELAY set * Connected to example.com (93.184.216.34) port 80 (#0) > GET / HTTP/1.1 > Host: example.com > User-Agent: curl/7.64.1 > Accept: */* > < HTTP/1.1 200 OK < Age: 258083 < Cache-Control: max-age=604800 < Content-Type: text/html; charset=UTF-8 < Date: Thu, 22 Jul 2021 15:42:57 GMT < Etag: "3147526947+ident" < Expires: Thu, 29 Jul 2021 15:42:57 GMT < Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT < Server: ECS (dcb/7F17) < Vary: Accept-Encoding < X-Cache: HIT < Content-Length: 1256 < <!doctype html> <html> * Connection #0 to host example.com left intact * Closing connection 0
В выводе команды curl символы *
, >
и <
являются маркерами типа информации, отображённой в выводе команды. *
используется для сервисной информации о соединении, >
— для обозначения запросов клиента (клиентом является curl), <
— для обозначения ответов сервера.
В первой части вывода содержится информация о процессе установления соединения через протокол TCP:
* Trying 93.184.216.34...* TCP_NODELAY set* Connected to example.com (93.184.216.34) port 80 (#0)
* Trying 93.184.216.34... * TCP_NODELAY set * Connected to example.com (93.184.216.34) port 80 (#0)
Curl пытается соединиться с сетевым устройством с IP-адресом 93.184.216.34, поскольку именно этот адрес соответствует домену example.com. Строка после слова Connected
curl указывает, что соединение установлено. В последней части curl выводит информацию о прекращении соединения:
* Connection #0 to host example.com left intact* Closing connection 0
* Connection #0 to host example.com left intact * Closing connection 0
Вторая часть вывода — полное HTML-сообщение запроса со стартовой строкой и заголовками (тело сообщения отсутствует):
> GET
— Стартовая строка с методом запроса, адресом внутри сайта и версией протокола./ HTTP / 1 . 1 > Host
— Заголовок с указанием хоста, на котором работает веб-сервер.: example . com > User
— Заголовок с информацией о клиенте, программе, запущенной у пользователя.- Agent : curl / 7 . 64 . 1 > Accept
— Заголовок с типами контента, которые клиент может корректно обработать.: * / * >
— После этой пустой строки могло быть тело запроса, но его редко используют в случае обработки данных методом GET.
Третья часть вывода — полное HTML-сообщение ответа веб-сервера со стартовой строкой, заголовками и телом, в котором передаётся HTML-код страницы:
< HTTP
— Стартовая строка с версией протокола, кодом и статусом ответа сервера.
< Age
— Заголовок с временем жизни контента в кэше (в секундах).
< Cache
— Заголовок для определения времени (в секундах) и типа кэширования на сервере.
< Content
— Заголовок с типом контента и кодировкой.
< Date
— Заголовок с датой и временем отправки сообщения.
< Etag
— Заголовок с версией контента.
< Expires
— Заголовок с датой и временем, после которых контент считается устаревшим.
< Last
— Заголовок с датой и временем последнего изменения контента.
< Server
— Заголовок с именем веб-сервера. В нашем случае Elastic Cloud Server.
< Vary
— Заголовок, который отвечает за выбор стратегии кэширования и сжатия.
< X
— Заголовок означает, что контент расположен на CDN (Content Delivery Network), а не на одном сервере.
< Content
— Заголовок с информацией о длине контента в символах.
<
— После этой пустой строки идёт тело ответа сервера, в нашем случае HTML-код страницы
Вы можете узнать больше о домене с помощью разных сервисов, например, с помощью domain.glass.