# HTTP

HTTP (англ. HyperText Transfer Protocol - «протокол передачи гипертекста») - протокол прикладного уровня передачи данных, изначально - в виде гипертекстовых документов (то есть документов, которые могут содержать ссылки, позволяющие организовать переход к другим документам) в формате HTML, в настоящее время используется для передачи произвольных данных.

Основой HTTP является технология «клиент-сервер», то есть предполагается существование:

* Потребителей (клиентов), которые инициируют соединение и посылают запрос;
* Поставщиков (серверов), которые ожидают соединения для получения запроса, производят необходимые действия и возвращают обратно сообщение с результатом.

HTTP используется также в качестве «транспорта» для других протоколов прикладного уровня, таких как SOAP, XML-RPC, WebDAV.

Основным объектом манипуляции в HTTP является ресурс, на который указывает URI (Uniform Resource Identifier) в запросе клиента. Обычно такими ресурсами являются хранящиеся на сервере файлы, но ими могут быть логические объекты или что-то абстрактное. Особенностью протокола HTTP является возможность указать в запросе и ответе способ представления одного и того же ресурса по различным параметрам: формату, кодировке, языку и т. д. (в частности, для этого используется HTTP-заголовок). Именно благодаря возможности указания способа кодирования сообщения клиент и сервер могут обмениваться двоичными данными, хотя данный протокол является текстовым.

HTTP - протокол прикладного уровня; аналогичными ему являются FTP и SMTP. Обмен сообщениями идёт по обыкновенной схеме «запрос-ответ». Для идентификации ресурсов HTTP использует глобальные URI. В отличие от многих других протоколов, HTTP не сохраняет своего состояния (stateless). Это означает отсутствие сохранения промежуточного состояния между парами «запрос-ответ». Компоненты, использующие HTTP, могут самостоятельно осуществлять сохранение информации о состоянии, связанной с последними запросами и ответами (например, «куки» на стороне клиента, «сессии» на стороне сервера). Браузер, посылающий запросы, может отслеживать задержки ответов. Сервер может хранить IP-адреса и заголовки запросов последних клиентов. Однако сам протокол не осведомлён о предыдущих запросах и ответах, в нём не предусмотрена внутренняя поддержка состояния, к нему не предъявляются такие требования.

Большинство протоколов предусматривает установление TCP-сессии, в ходе которой один раз происходит авторизация, и дальнейшие действия выполняются в контексте этой авторизации. HTTP же устанавливает отдельную TCP-сессию на каждый запрос; в более поздних версиях HTTP было разрешено делать несколько запросов в ходе одной TCP-сессии, но браузеры обычно запрашивают только страницу и включенные в нее объекты (картинки, каскадные стили и т. п.), а затем сразу разрывают TCP-сессию. Для поддержки авторизованного (неанонимного) доступа в HTTP используются cookies; причем такой способ авторизации позволяет сохранить сессию даже после перезагрузки клиента и сервера.

При доступе к данным по FTP или по файловым протоколам тип файла (точнее, тип содержащихся в нем данных) определяется по расширению имени файла, что не всегда удобно. HTTP перед тем, как передать сами данные, передаёт заголовок «Content-Type: тип/подтип», позволяющий клиенту однозначно определить, каким образом обрабатывать присланные данные. Это особенно важно при работе с CGI-скриптами, когда расширение имени файла указывает не на тип присылаемых клиенту данных, а на необходимость запуска данного файла на сервере и отправки клиенту результатов работы программы, записанной в этом файле (при этом один и тот же файл в зависимости от аргументов запроса и своих собственных соображений может порождать ответы разных типов - в простейшем случае картинки в разных форматах).

Кроме того, HTTP позволяет клиенту прислать на сервер параметры, которые будут переданы запускаемому CGI-скрипту. Для этого же в HTML были введены формы.

**Структура HTTP-сообщения**

Каждое HTTP-сообщение состоит из трёх частей, которые передаются в указанном порядке:

1. **Стартовая строка** (англ. Starting line) - определяет тип сообщения, различается для запроса и ответа;
2. **Заголовки** (англ. Headers) - характеризуют тело сообщения, параметры передачи и прочие сведения;
3. **Тело сообщения** (англ. Message Body) - непосредственно данные сообщения. Обязательно должно отделяться от заголовков пустой строкой.

Для версии протокола 1.1 сообщение запроса обязательно должно содержать заголовок Host.

**1. Стартовая строка**:

* Стартовая строка запроса выглядит так: *Метод URI HTTP/Версия*, где:

  * Метод (англ. Method) - тип запроса, одно слово заглавными буквами;
  * URI определяет путь к запрашиваемому документу;
  * Версия (англ. Version) - пара разделенных точкой цифр. Например: 1.1.

  Чтобы запросить страницу данной статьи, клиент должен передать строку (задан всего один заголовок):

  GET /wiki/HTTP HTTP/1.1

  Host: ru.wikipedia.org
* Стартовая строка ответа сервера имеет следующий формат: *HTTP/Версия КодСостояния Пояснение*, где:

  * Версия - пара разделенных точкой цифр, как в запросе;
  * Код состояния (англ. Status Code) - три цифры. По коду состояния определяется дальнейшее содержимое сообщения и поведение клиента;
  * Пояснение (англ. Reason Phrase) - текстовое короткое пояснение к коду ответа для пользователя. Никак не влияет на сообщение и является необязательным.

  Например, стартовая строка ответа сервера на предыдущий запрос может выглядеть так:

  HTTP/1.0 200 OK

**2. Заголовки:** Заголовки HTTP (англ. HTTP Headers) - это строки в HTTP-сообщении, содержащие разделённую двоеточием пару параметр-значение. Формат заголовков соответствует общему формату заголовков текстовых сетевых сообщений ARPA (см. RFC 822). Заголовки должны отделяться от тела сообщения хотя бы одной пустой строкой. Примеры заголовков:

* Server: Apache/2.2.11 (Win32) PHP/5.3.0
* Last-Modified: Sat, 16 Jan 2010 21:16:42 GMT
* Content-Type: text/plain; charset=windows-1251
* Content-Language: ru

В примере выше каждая строка представляет собой один заголовок. При этом то, что находится до двоеточия, называется именем (англ. name), а что после него - значением (англ. value).

Все заголовки разделяются на четыре основных группы:

* General Headers («Основные заголовки») - могут включаться в любое сообщение клиента и сервера;
* Request Headers («Заголовки запроса») - используются только в запросах клиента;
* Response Headers («Заголовки ответа») - только для ответов от сервера;
* Entity Headers («Заголовки сущности») - сопровождают каждую сущность сообщения.

Именно в таком порядке рекомендуется посылать заголовки получателю.

Все необходимые для функционирования HTTP заголовки описаны в основных RFC. Если не хватает существующих, то можно вводить свои. Традиционно к именам таких дополнительных заголовков добавляют префикс «X-» для избежания конфликта имён с возможно существующими. Например, как в заголовках X-Powered-By или X-Cache. Некоторые разработчики используют свои индивидуальные префиксы. Примерами таких заголовков могут служить Ms-Echo-Request и Ms-Echo-Reply, введённые корпорацией Microsoft для расширения WebDAV. Больше можно узнать [тут](https://developer.mozilla.org/ru/docs/Web/HTTP/Headers).

*Какие заголовки важны тестировщику: очевидно, смотря что мы тестируем. В основном это заголовки, касающиеся авторизации, кук, кэша и юзер-агент, хотя для того же security тестера они будут иные. Больше* [*тут*](https://habr.com/ru/post/413205/) *и* [*тут*](https://xakep.ru/2011/05/24/55557/)*.*

*Как сервер узнает, с какого типа устройства/браузера/ОС/языка вы открываете веб-сайт (Например, для Adaptive design): когда вы отправляете HTTP-запрос, он содержит в себе заголовки (headers) с различной информацией. Одним из них является User-Agent. Он сообщает: браузер, его версию и язык, движок браузера, версию движка, операционную систему.*&#x20;

**3. Тело сообщения**: Тело HTTP-сообщения (message-body), если оно присутствует, используется для передачи тела объекта, связанного с запросом или ответом. Тело сообщения отличается от тела объекта (entity-body) только в том случае, когда применяется кодирование передачи, что указывается полем заголовка Transfer-Encoding.

Поле Transfer-Encoding должно использоваться для указания любого кодирования передачи, примененного приложением в целях гарантирования безопасной и правильной передачи сообщения. Поле Transfer-Encoding - это свойство сообщения, а не объекта, и, таким образом, может быть добавлено или удалено любым приложением в цепочке запросов/ответов.

Правила, устанавливающие допустимость тела сообщения в сообщении, отличны для запросов и ответов.

Присутствие тела сообщения в запросе отмечается добавлением к заголовкам запроса поля заголовка Content-Length или Transfer-Encoding. Тело сообщения может быть добавлено в запрос, только когда метод запроса допускает тело объекта.

Включается или не включается тело сообщения в сообщение ответа - зависит как от метода запроса, так и от кода состояния ответа. Все ответы на запрос с методом HEAD не должны включать тело сообщения, даже если присутствуют поля заголовка объекта (entity-header), заставляющие поверить в присутствие объекта. Никакие ответы с кодами состояния 1xx (Информационные), 204 (Нет содержимого, No Content), и 304 (Не модифицирован, Not Modified) не должны содержать тела сообщения. Все другие ответы содержат тело сообщения, даже если оно имеет нулевую длину.

**Методы HTTP**

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

Сервер может использовать любые методы, не существует обязательных методов для сервера или клиента, кроме того, программист может связать метод и выполняемую функцию как угодно его фантазии. Во избежание хаоса существуют соглашения (тот же REST) и стандарты. Формально если сервер не распознал указанный клиентом метод, то он должен вернуть статус 501 (Not Implemented). Если серверу метод известен, но он неприменим к конкретному ресурсу, то возвращается сообщение с кодом 405 (Method Not Allowed). В обоих случаях серверу следует включить в сообщение ответа заголовок Allow со списком поддерживаемых методов.

Основными и чаще всего используемыми методами являются GET, POST, PUT, DELETE которые эквивалентны базовым функциям при работе с БД или любыми хранимыми вычислительными сущностями - [CRUD](https://ru.wikipedia.org/wiki/CRUD) (create, read, update, delete).

* **OPTIONS**: Используется для определения возможностей веб-сервера или параметров соединения для конкретного ресурса. В ответ серверу следует включить заголовок Allow со списком поддерживаемых методов. Также в заголовке ответа может включаться информация о поддерживаемых расширениях. Предполагается, что запрос клиента может содержать тело сообщения для указания интересующих его сведений. Формат тела и порядок работы с ним в настоящий момент не определен; сервер пока должен его игнорировать. Аналогичная ситуация и с телом в ответе сервера. Для того, чтобы узнать возможности всего сервера, клиент должен указать в URI звёздочку - «\*». Запросы «OPTIONS \* HTTP/1.1» могут также применяться для проверки работоспособности сервера (аналогично «пингованию») и тестирования на предмет поддержки сервером протокола HTTP версии 1.1. Результат выполнения этого метода не кэшируется;
* **GET**: Используется для запроса содержимого указанного ресурса. С помощью метода GET можно также начать какой-либо процесс. В этом случае в тело ответного сообщения следует включить информацию о ходе выполнения процесса. Клиент может передавать параметры выполнения запроса в URI целевого ресурса после символа «?»: GET /path/resource?param1=value1\&param2=value2 HTTP/1.1. Согласно стандарту HTTP, запросы типа GET считаются идемпотентными. Кроме обычного метода GET, различают ещё

  * Условный GET - содержит заголовки If-Modified-Since, If-Match, If-Range и подобные;
  * Частичный GET - содержит в запросе Range.

  Порядок выполнения подобных запросов определен стандартами отдельно;
* **HEAD**: Аналогичен методу GET, за исключением того, что в ответе сервера отсутствует тело. Запрос HEAD обычно применяется для извлечения метаданных, проверки наличия ресурса (валидация URL) и чтобы узнать, не изменился ли он с момента последнего обращения. Заголовки ответа могут кэшироваться. При несовпадении метаданных ресурса с соответствующей информацией в кэше - копия ресурса помечается как устаревшая;
* **POST**: Применяется для передачи пользовательских данных заданному ресурсу. Например, в блогах посетители обычно могут вводить свои комментарии к записям в HTML-форму, после чего они передаются серверу методом POST и он помещает их на страницу. При этом передаваемые данные (в примере с блогами - текст комментария) включаются в тело запроса. Аналогично с помощью метода POST обычно загружаются файлы на сервер. В отличие от метода GET, метод POST не считается идемпотентным, то есть многократное повторение одних и тех же запросов POST может возвращать разные результаты (например, после каждой отправки комментария будет появляться очередная копия этого комментария). При результате выполнения 200 (Ok) в тело ответа следует включить сообщение об итоге выполнения запроса. Если был создан ресурс, то серверу следует вернуть ответ 201 (Created) с указанием URI нового ресурса в заголовке Location. Сообщение ответа сервера на выполнение метода POST не кэшируется. Стоит отметить, что [не всегда данные могут быть лишь в теле](https://stackoverflow.com/questions/611906/http-post-with-url-query-parameters-good-idea-or-not);
* **PUT**: Применяется для загрузки содержимого запроса на указанный в запросе URI. Если по заданному URI не существует ресурса, то сервер создаёт его и возвращает статус 201 (Created). Если же ресурс был изменен, то сервер возвращает 200 (Ok) или 204 (No Content). Сервер не должен игнорировать некорректные заголовки Content-\*, передаваемые клиентом вместе с сообщением. Если какой-то из этих заголовков не может быть распознан или недопустим при текущих условиях, то необходимо вернуть код ошибки 501 (Not Implemented). Фундаментальное различие методов POST и PUT заключается в понимании предназначений URI ресурсов. Метод POST предполагает, что по указанному URI будет производиться обработка передаваемого клиентом содержимого. Используя PUT, клиент предполагает, что загружаемое содержимое соответствует находящемуся по данному URI ресурсу. Сообщения ответов сервера на метод PUT не кэшируются;
* **PATCH**: Аналогично PUT, но применяется только к фрагменту ресурса;
* **DELETE**: Удаляет указанный ресурс;
* **TRACE**: Возвращает полученный запрос так, что клиент может увидеть, какую информацию промежуточные серверы добавляют или изменяют в запросе;
* **CONNECT**: Преобразует соединение запроса в прозрачный TCP/IP-туннель, обычно чтобы содействовать установлению защищенного SSL-соединения через нешифрованный прокси.

**Различия методов GET и POST**

Основное состоит в способе передачи данных веб-формы обрабатывающему скрипту, а именно:

* Метод GET отправляет скрипту всю собранную информацию формы как часть URL: <http://www.komtet.ru/script.php?login=admin\\&name=komtet>
* Метод POST передает данные таким образом, что пользователь сайта уже не видит передаваемые скрипту данные: <http://www.komtet.ru/script.php>

Кроме того:

* Количество информации, передаваемой методом GET через URL строку ограничено 2048 символами (минус служебная информация браузера);
* Страницу, сгенерированную методом GET, можно добавить в закладки и поделиться ссылкой;
* Sensitive data в таком открытом виде очевидно плохо влияют на безопасность;
* Метод POST в отличие от метода GET позволяет передавать запросу файлы;
* При использовании метода GET существует риск того, что поисковый робот может выполнить тот или иной открытый запрос.

**Коды состояния**

Код состояния является частью первой строки ответа сервера. Он представляет собой целое число из трёх цифр. Первая цифра указывает на класс состояния. За кодом ответа обычно следует отделенная пробелом поясняющая фраза на английском языке, которая разъясняет человеку причину именно такого ответа. Примеры:

* 201 Webpage Created;
* 403 Access allowed only for registered users;
* 507 Insufficient Storage.

Клиент узнаёт по коду ответа о результатах его запроса и определяет, какие действия ему предпринимать дальше. Набор кодов состояния является стандартом, и они описаны в соответствующих документах RFC. Введение новых кодов должно производиться только после согласования с IETF. Клиент может не знать все коды состояния, но он обязан отреагировать в соответствии с классом кода.

В настоящее время выделено пять классов кодов состояния.

| **Код**     | **Класс**                                         | **Назначение**                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ----------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 100-е (1ХХ) | <p>Информационный</p><p>(англ. informational)</p> | <p>Информирование о процессе передачи.</p><p>В HTTP/1.0 - сообщения с такими кодами должны игнорироваться.</p><p>В HTTP/1.1 - клиент должен быть готов принять этот класс сообщений как обычный ответ, но ничего отправлять серверу не нужно.</p><p>Сами сообщения от сервера содержат только стартовую строку ответа и, если требуется, несколько специфичных для ответа полей заголовка. Прокси-серверы подобные сообщения должны отправлять дальше от сервера к клиенту.</p> |
| 200-е (2ХХ) | <p>Успех</p><p>(англ. Success)</p>                | Информирование о случаях успешного принятия и обработки запроса клиента. В зависимости от статуса, сервер может ещё передать заголовки и тело сообщения.                                                                                                                                                                                                                                                                                                                        |
| 300-е (3ХХ) | <p>Перенаправление</p><p>(англ. Redirection)</p>  | Сообщает клиенту, что для успешного выполнения операции необходимо сделать другой запрос (как правило по другому URI). Из данного класса пять кодов 301, 302, 303, 305 и 307 относятся непосредственно к перенаправлениям (редирект). Адрес, по которому клиенту следует произвести запрос, сервер указывает в заголовке Location. При этом допускается использование фрагментов в целевом URI.                                                                                 |
| 400-е (4ХХ) | <p>Ошибка клиента</p><p>(англ. Client Error)</p>  | Указание ошибок со стороны клиента. При использовании всех методов, кроме HEAD, сервер должен вернуть в теле сообщения гипертекстовое пояснение для пользователя.                                                                                                                                                                                                                                                                                                               |
| 500-е (5ХХ) | <p>Ошибка сервера</p><p>(англ. Server Error)</p>  | Информирование о случаях неудачного выполнения операции по вине сервера. Для всех ситуаций, кроме использования метода HEAD, сервер должен включать в тело сообщения объяснение, которое клиент отобразит пользователю.                                                                                                                                                                                                                                                         |

Полный перечень можно найти [тут](https://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2_%D1%81%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D1%8F_HTTP). Данные диапазоны определены в стандартах, однако ничего не мешает в повседневной жизни увидеть и [неофициальные](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes), [еще](https://developer.fastly.com/reference/http/http-statuses/) и [еще](https://support.cloudflare.com/hc/en-us/articles/360029779472-Troubleshooting-Cloudflare-1XXX-errors).

**Почему ошибка 404 относится к 4** - клиентской, если по интуитивно должна быть серверной? Объясняется это тем, что сервер работает и готов вернуть страницу в ответ на запрос, однако страницы по запрашиваемому адресу у него попросту нет. Таким образом, вины сервера в этом нет и предполагается опечатка в URL, которая является виной клиента. В этом вопросе сбивает с толку то, что ошибка 404 часто возвращается, когда страница была перемещена или удалена, или не совпадает имя файла в коде и на сервере. Тогда корректнее показывать ошибки 301 Moved Permanently (перемещено), что можно настроить в конфигурации большинства серверов, либо производить перенаправление на другой URL, и возвращать код 410 Gone (удалено). Однако, так как эти два варианта требуют специальной настройки сервера, большинство веб-сайтов не используют их.

**На какой метод не может вернуться ошибка 501?** The HTTP 501 Not Implemented серверный код ответа на ошибку указывает, что метод запроса не поддерживается сервером и не может быть обработан. Единственными методами, которые необходимы серверам для поддержки (и, следовательно, не должны возвращать этот код), являются GET и HEAD.

**Отличия HTTP/1.1 от HTTP/2.0**

11 февраля 2015 года опубликованы финальные версии черновика следующей версии протокола. В отличие от предыдущих версий, протокол HTTP/2 является бинарным. Среди ключевых особенностей: мультиплексирование запросов, расстановка приоритетов для запросов, сжатие заголовков, загрузка нескольких элементов параллельно посредством одного TCP-соединения, поддержка проактивных push-уведомлений со стороны сервера. Подробнее [тут](https://www.8host.com/blog/v-chem-raznica-mezhdu-http1-1-i-http2/).

**HTTP3**

Десятилетиями весь интернет держался на TCP, но он начал устаревать еще в конце 2000-х. Его предполагаемая замена, новый транспортный протокол под названием QUIC, настолько отличается от TCP по ключевым пунктам, что просто использовать поверх него HTTP/2 было бы очень сложно. Поэтому сам по себе HTTP/3 - это относительно незначительное изменение HTTP/2 для адаптации к новому протоколу QUIC. Вот он-то как раз и содержит те фичи, которые всех приводят в восторг.

![https://hsto.org/r/w1560/webt/nb/71/n2/nb71n20vpyaiwsjwnafwhl1pxx4.png](https://hsto.org/r/w1560/webt/nb/71/n2/nb71n20vpyaiwsjwnafwhl1pxx4.png)

TCP, который мы использовали с первых дней интернета, изначально был создан не на максимуме эффективности, поэтому нам и стал нужен QUIC. Например, TCP требует рукопожатие для установки нового соединения, чтобы проверить, что клиент и сервер существуют и готовы обмениваться данными. Нужно сделать полный круговой путь по сети, прежде чем можно будет делать что-то ещё. Если клиент и сервер находятся далеко, время кругового пути (round-trip time, RTT) может составить более 100 мс, что приводит к ощутимым задержкам.

Второй пример: TCP видит все данные, которые передает, как один «файл», или поток байтов, даже если мы передаем несколько файлов одновременно (например, загружаем страницу с несколькими ресурсами). На практике это означает, что, если пакеты TCP с данными одного файла теряются, все остальные файлы будут ждать восстановления этих пакетов. Это так называемая блокировка начала очереди - head-of-line (HoL) blocking. На практике с этими недостатками можно бороться (иначе зачем бы мы мучились с TCP целых 30 с лишним лет), но они серьезно влияют на протоколы верхнего уровня, например, HTTP.

На самом деле нам нужен был не HTTP/3, а TCP/2. Просто в процессе у нас сам собой получился HTTP/3. Всё то, чего мы с таким нетерпением ждем от HTTP/3 (быстрая установка соединения, меньше блокировок HoL, миграция соединения и т. д.), - на самом деле уже реализовано в QUIC.

**QUIC**

QUIC - это универсальный транспортный протокол. Как и TCP, он может и будет использоваться в разных сценариях, не только для HTTP и загрузки сайтов. Например, поверх QUIC можно пристроить DNS, SSH, SMB, RTP и так далее. Давайте узнаем о QUIC чуть больше, ведь именно с ним связаны многие заблуждения по поводу HTTP/3.

Вы, наверное, слышали, что QUIC работает поверх еще одного протокола - UDP. Это правда, но производительность тут ни при чём. В идеале QUIC мог бы быть полностью независимым транспортным протоколом сразу над IP в стеке, как на картинке выше.

Но тогда возникли бы те же сложности, что и при попытке развивать TCP: пришлось бы сначала обновить все устройства в интернете, чтобы они распознавали и разрешали QUIC. К счастью, мы можем разместить QUIC поверх еще одного распространенного протокола транспортного уровня: UDP.

Многие говорят, что HTTP/3 создан поверх UDP в целях производительности. Якобы HTTP/3 работает быстрее, потому что, как и UDP, не устанавливает соединение и не ждет повторной передачи пакетов. Не верьте. Мы уже сказали, что UDP используется протоколом QUIC, а значит и HTTP/3, в надежде, что так их будет проще развернуть, ведь UDP уже знают и используют почти все устройства в интернете.

Расположенный поверх UDP, QUIC, по сути, реализует почти все функции, которые делают TCP таким эффективным и популярным (пусть и чуть более медленным) протоколом. QUIC абсолютно надежен - он использует подтверждение полученных пакетов и повторные передачи, чтобы добрать то, что потерялось. QUIC по-прежнему устанавливает соединение и использует сложную систему рукопожатий.

Наконец, QUIC использует механизмы flow-control и congestion-control, которые не дают отправителю перегрузить сеть или получателя, но замедляют TCP по сравнению «чистым» UDP. Правда QUIC реализует эти функции умнее и эффективнее. В нём собраны десятилетия опыта и лучших практик TCP и новые функции.

**HTTPS**

У HTTP есть один недостаток: данные передаются в открытом виде и никак не защищены. На пути из точки А в точку Б информация в интернете проходит через десятки промежуточных узлов, и, если хоть один из них находится под контролем злоумышленника, данные могут перехватить. То же самое может произойти, когда вы пользуетесь незащищенной сетью Wi-Fi, например, в кафе. Для установки безопасного соединения используется протокол HTTPS с поддержкой шифрования.

HTTPS (аббр. от англ. HyperText Transfer Protocol Secure) - расширение протокола HTTP для поддержки шифрования в целях повышения безопасности. Данные в протоколе HTTPS передаются поверх криптографических протоколов TLS или устаревшего в 2015 году SSL.

HTTPS не является отдельным протоколом. Это обычный HTTP, работающий через шифрованные транспортные механизмы SSL и TLS. Он обеспечивает защиту от атак, основанных на прослушивании сетевого соединения - от снифферских атак и атак типа man-in-the-middle, при условии, что будут использоваться шифрующие средства и сертификат сервера проверен и ему доверяют.

По умолчанию HTTPS URL использует 443 TCP-порт (для незащищенного HTTP - 80). Чтобы подготовить веб-сервер для обработки https-соединений, администратор должен получить и установить в систему сертификат открытого и закрытого ключа для этого веб-сервера. В TLS используется как асимметричная схема шифрования (для выработки общего секретного ключа), так и симметричная (для обмена данными, зашифрованными общим ключом). Сертификат открытого ключа подтверждает принадлежность данного открытого ключа владельцу сайта. Сертификат открытого ключа и сам открытый ключ посылаются клиенту при установлении соединения; закрытый ключ используется для расшифровки сообщений от клиента.

Существует возможность создать такой сертификат, не обращаясь в центр сертификации. Подписываются такие сертификаты этим же сертификатом и называются самоподписанными (self-signed). Без проверки сертификата каким-то другим способом (например, звонок владельцу и проверка контрольной суммы сертификата) такое использование HTTPS подвержено атаке посредника.

Эта система также может использоваться для аутентификации клиента, чтобы обеспечить доступ к серверу только авторизованным пользователям. Для этого администратор обычно создает сертификаты для каждого пользователя и загружает их в браузер каждого пользователя. Также будут приниматься все сертификаты, подписанные организациями, которым доверяет сервер. Такой сертификат обычно содержит имя и адрес электронной почты авторизованного пользователя, которые проверяются при каждом соединении, чтобы проверить личность пользователя без ввода пароля.

В HTTPS для шифрования используется длина ключа 40, 56, 128 или 256 бит. Некоторые старые версии браузеров используют длину ключа 40 бит (пример тому - IE версий до 4.0), что связано с экспортными ограничениями в США. Длина ключа 40 бит не является надежной. Многие современные сайты требуют использования новых версий браузеров, поддерживающих шифрование с длиной ключа 128 бит, с целью обеспечить достаточный уровень безопасности. Шифрование с длиной ключа 128 бит значительно затрудняет подбор паролей и доступ к личной информации.

Традиционно на одном IP-адресе может работать только один HTTPS-сайт. Для работы нескольких HTTPS-сайтов с различными сертификатами применяется расширение TLS под названием Server Name Indication (SNI).

Идентификация в HTTPS:

* Идентификация сервера: HTTP/TLS запросы генерируются путём разыменования URI, вследствие чего имя хоста становится известно клиенту. В начале общения, сервер посылает клиенту свой сертификат, чтобы клиент идентифицировал его. Это позволяет предотвратить атаку посредника. В сертификате указывается URI сервера. Согласование имени хоста и данных, указанных в сертификате, происходит в соответствии с протоколом RFC2459. Если имя сервера не совпадает с указанным в сертификате, то пользовательские программы, например браузеры, сообщают об этом пользователю. В основном, браузеры предоставляют пользователю выбор: продолжить незащищённое соединение или прервать его.
* Идентификация клиента: Обычно сервер не располагает информацией о клиенте, достаточной для его идентификации. Однако для обеспечения повышенной защищенности соединения используется так называемая two-way authentication. При этом сервер после подтверждения его сертификата клиентом также запрашивает сертификат. Таким образом, схема подтверждения клиента аналогична идентификации сервера.

Источники:

* [HTTP](https://ru.wikipedia.org/wiki/HTTP)
* [HTTP/3 от А до Я: основные концепции. Часть 1](https://habr.com/ru/company/southbridge/blog/575464/)
* [HTTPS](https://ru.wikipedia.org/wiki/HTTPS)

Доп. материал:

* [Протокол HTTP что это такое / Урок 23 / Тестировщик с нуля](https://www.youtube.com/watch?v=sboscOZzOO0)
* [HTTP для тестировщиков](https://www.youtube.com/watch?v=iS-D5jZ_c24\&t=1s\&ab_channel=HillelITSchool)
* [Идемпотентный метод](https://developer.mozilla.org/ru/docs/Glossary/Idempotent)
* [Жизненный цикл HTTP-запроса](https://www.youtube.com/watch?v=8ZKlOD4fRT0)
