Сообщения HTTP
==============

HTTP сообщения - это обмен данными между сервером и клиентом. Есть два типа сообщений: ***запросы***, отправляемые клиентом, чтобы инициировать реакцию со стороны сервера, и **ответы** от сервера.

Сообщения HTTP состоят из текстовой информации в кодировке ASCII, записанной в несколько строк. В HTTP/1.1 и более ранних версиях они пересылались в качестве обычного текста. В HTTP/2 текстовое сообщение разделяется на фреймы, что позволяет выполнить оптимизацию и повысить производительность.

Веб разработчики не создают текстовые сообщения HTTP самостоятельно - это делает программа, браузер, прокси или веб-сервер. Они обеспечивают создание HTTP сообщений через конфигурационные файлы (для прокси и серверов), APIs (для браузеров) или другие интерфейсы.

![From a user-, script-, or server- generated event, an HTTP/1.x msg is generated, and if HTTP/2 is in use, it is binary framed into an HTTP/2 stream, then sent.](/ru/docs/Web/HTTP/Messages/httpmsg2.png)

Механизм бинарного фрагментирования в HTTP/2 разработан так, чтобы не потребовалось вносить изменения в имеющиеся APIs и конфигурационные файлы: он вполне прозрачен для пользователя.

HTTP запросы и ответы имеют близкую структуру. Они состоят из:

1. Стартовой строки, описывающей запрос, или статус (успех или сбой). Это всегда одна строка.
2. Произвольного набора *HTTP заголовков,* определяющих запрос или описывающих тело сообщения.
3. Пустой строки, указывающей, что вся мета информация отправлена.
4. Произвольного тела, содержащего пересылаемые с запросом данные (например, содержимое HTML-формы ) или отправляемый в ответ документ. Наличие тела и его размер определяется стартовой строкой и заголовками HTTP.

Стартовую строку вместе с заголовками сообщения HTTP называют *головой* запроса, а его данные - *телом*.

![Requests and responses share a common structure in HTTP](/ru/docs/Web/HTTP/Messages/httpmsgstructure2.png)

Запросы HTTP
------------

### Стартовая строка

HTTP запросы - это сообщения, отправляемые клиентом, чтобы инициировать реакцию со стороны сервера. Их стартовая строка состоит из трёх элементов:

1. *Метод HTTP*, глагол (например, `GET`, `PUT` или `POST`) или существительное (например, `HEAD` или `OPTIONS`), описывающие требуемое действие. Например, `GET` указывает, что нужно доставить некоторый ресурс, а `POST` означает отправку данных на сервер (для создания или модификации ресурса, или генерации возвращаемого документа).
2. *Цель запроса*, обычно URL, или абсолютный путь протокола, порт и домен обычно характеризуются контекстом запроса. Формат цели запроса зависит от используемого HTTP-метода. Это может быть
    * Абсолютный путь, за которым следует `'?'` и строка запроса. Это самая распространённая форма, называемая *исходной формой* (*origin form*) . Используется с методами `GET`, `POST`, `HEAD`, и `OPTIONS`.
     `POST / HTTP 1.1 GET /background.png HTTP/1.0 HEAD /test.html?query=alibaba HTTP/1.1 OPTIONS /anypage.html HTTP/1.0`
    * Полный URL *- абсолютная форма* (*absolute form*) , обычно используется с `GET` при подключении к прокси.
     `GET http://developer.mozilla.org/ru/docs/Web/HTTP/Messages HTTP/1.1`
    * Компонента URL "authority", состоящая из имени домена и (необязательно) порта (предваряемого символом `':'`), *называется authority form*. Используется только с методом `CONNECT` при установке туннеля HTTP.
     `CONNECT developer.mozilla.org:80 HTTP/1.1`
    * Форма звёздочки (*asterisk form)*, просто "звёздочка" (`'*'`) используется `с методом OPTIONS` и представляет сервер.
     `OPTIONS * HTTP/1.1`
3. *Версия HTTP*, определяющая структуру оставшегося сообщения, указывая, какую версию предполагается использовать для ответа.
### Заголовки

Заголовки запроса HTTP имеют стандартную для заголовка HTTP структуру: не зависящая от регистра строка, завершаемая (`':'`) и значение, структура которого определяется заголовком. Весь заголовок, включая значение, представляет собой одну строку, которая может быть довольно длинной.

Существует множество заголовков запроса. Их можно разделить на несколько групп:

* *Основные заголовки (General headers*), например, `Via` (en-US), относящиеся к сообщению в целом
* *Заголовки запроса (Request headers*), например, `User-Agent`, `Accept-Type`, уточняющие запрос (как, например, `Accept-Language`), придающие контекст (как `Referer`), или накладывающие ограничения на условия (like `If-None`).
* *Заголовки сущности*, например `Content-Length`, относящиеся к телу сообщения. Как легко понять, они отсутствуют, если у запроса нет тела.
* ![Example of headers in an HTTP request](/ru/docs/Web/HTTP/Messages/http_request_headers2.png)
### Тело

Последней частью запроса является его тело. Оно бывает не у всех запросов: запросы, собирающие (fetching) ресурсы, такие как `GET`, `HEAD`, `DELETE`, или `OPTIONS`, в нем обычно не нуждаются. Но некоторые запросы отправляют на сервер данные для обновления, как это часто бывает с запросами `POST` (содержащими данные HTML-форм).

Тела можно грубо разделить на две категории:

* Одноресурсные тела (Single-resource bodies), состоящие из одного отдельного файла, определяемого двумя заголовками: `Content-Type` и `Content-Length`.
* Многоресурсные тела (Multiple-resource bodies), состоящие из множества частей, каждая из которых содержит свой бит информации. Они обычно связаны с HTML-формами.
Ответы HTTP
-----------

### Строка статуса (Status line)

Стартовая строка ответа HTTP, называемая строкой статуса, содержит следующую информацию:

1. *Версию протокола*, `обычно HTTP/1.1`.
2. *Код состояния (status code)*, показывающая, был ли запрос успешным. Примеры: `200`, `404` или `302`
3. *Пояснение (status text*). Краткое текстовое описание кода состояния, помогающее пользователю понять сообщение HTTP..

Пример строки статуса: `HTTP/1.1 404 Not Found.`

### Заголовки

Заголовки ответов HTTP имеют ту же структуру, что и все остальные заголовки: не зависящая от регистра строка, завершаемая двоеточием (`':'`) и значение, структура которого определяется типом заголовка. Весь заголовок, включая значение, представляет собой одну строку.

Существует множество заголовков ответов. Их можно разделить на несколько групп:

* *Основные заголовки (General headers*), например, `Via` (en-US), относящиеся к сообщению в целом.
* *Заголовки ответа (Response headers*), например, `Vary` и `Accept-Ranges`, сообщающие дополнительную информацию о сервере, которая не уместилась в строку состояния.
* *Заголовки сущности (Entity headers*), например, `Content-Length`, относящиеся к телу ответа. Отсутствуют, если у ответа нет тела.

![Example of headers in an HTTP response](/ru/docs/Web/HTTP/Messages/http_response_headers2.png)

### Тело

Последней частью ответа является его тело. Оно есть не у всех ответов: у ответов с кодом состояния, например, `201` или `204`, оно обычно отсутствует.

Тела можно разделить на три категории:

* Одноресурсные тела (Single-resource bodies), состоящие из отдельного файла известной длины, определяемые двумя заголовками: `Content-Type` и `Content-Length`.
* Одноресурсные тела (Single-resource bodies), состоящие из отдельного файла неизвестной длины, разбитого на небольшие части (chunks) с заголовком `Transfer-Encoding` (en-US), значением которого является `chunked`.
* Многоресурсные тела (Multiple-resource bodies), состоящие из многокомпонентного тела, каждая часть которого содержит свой сегмент информации. Они относительно редки.
Фреймы HTTP/2
-------------

Сообщения HTTP/1.x имеют несколько недостатков в отношении производительности:

* Заголовки, в отличие от тел, не сжимаются.
* Заголовки, которые зачастую практически совпадают у идущих подряд сообщений, приходится передавать по отдельности.
* Мультиплексность невозможна. Приходится открывать соединение для каждого сообщения, а тёплые (warm) соединения TCP эффективнее холодных (cold).

HTTP/2 переходит на новый уровень: он делит сообщения HTTP/1.x на фреймы, которые внедряются в поток. Фреймы данных из заголовков отделены друг от друга, что позволяет сжимать заголовки. Несколько потоков можно объединять друг с другом - такой процесс называется мультиплексированием - что позволяет более эффективно использовать TCP-соединения.

![HTTP/2 modify the HTTP message to divide them in frames (part of a single stream), allowing for more optimization.](/ru/docs/Web/HTTP/Messages/binary_framing2.png)

Фреймы HTTP сейчас прозрачны для веб-разработчиков. Это дополнительный шаг, который HTTP/2 делает по отношению к сообщениям HTTP/1.1 и лежащему в основе транспортному протоколу. Для реализации фреймов HTTP веб-разработчикам не требуется вносить изменения в имеющиеся APIs; если HTTP/2 доступен и на сервере, и на клиенте, он включается и используется.

Заключение
----------

Сообщения HTTP играют ключевую роль в использовании HTTP; они имеют простую структуру и хорошо расширяемы. Механизм фреймов в HTTP/2 добавляет ещё один промежуточный уровень между синтаксисом HTTP/1.x и используемым им транспортным протоколом, не проводя фундаментальных изменений: создаётся надстройка над уже зарекомендовавшими себя методами.