Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

HTTP 1.1 Протокол HTTP

Протокол HTTP 1.1 расширяет возможности предыдущей версии и добавляет виртуальные хосты. Сейчас мы посмотрим, для чего это нужно, и как это работает.

Предыдущая версия требует наличия только request line. В ней мы описываем, какой путь на сайте мы хотим посмотреть. Но упоминания сайта как такового здесь нет. При этом мы подключаемся по telnet к конкретному IP адресу. Отсюда можно сделать вывод, что понятие домена (доменного имени) при использовании HTTP 1.0 не важно. Действительно, эта версия была создана в те времена, когда считалось, что один IP адрес соответствует одному сайту. Естественно это не могло продолжаться долго, потому что рост интернета был стремительный. И HTTP 1.1 ввел такое понятие как виртуальные хосты. С точки зрения реализации в протоколе HTTP, появилась одна небольшая деталь. Кроме request line стал обязательным ещё и заголовок, который называется host. Он определяет, какой именно домен должен быть возвращён с этого IP адреса.

HEAD / HTTP/1.1
host: hexlet.io

На самом деле, иногда в поведение HTTP и серверов заложены какие-то умолчания, например, они могут исправлять ошибки пользователей. То есть можно сделать запрос HTTP 1.1 без указания хоста и получить что-то в ответ. По-хорошему такой запрос вообще не должен проходить, но часто веб-серверы отдают сайт, который указан в настройках по дефолту. Например, в Nginx есть сайт по умолчанию. Но так нельзя делать запросы в принципе, это не соответствует стандарту. Нужно всегда указывать хост, иначе ответ не гарантирован. Сегодня он один, а завтра другой. Некоторые библиотеки вообще могут так не работать. Виртуальные хосты являются неотъемлемым атрибутом HTTP 1.1. Их нельзя игнорировать.

Сейчас мы можем сделать GET-запрос с использованием протокола версии 1.1 и посмотреть, что он нам вернет:

telnet google.com 80

GET / HTTP/1.1
host: google.com

HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Fri, 28 Feb 2020 06:06:40 GMT
Expires: Sun, 29 Mar 2020 06:06:40 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>

Как мы уже знаем, есть много разных кодов. В итоге мы получили ответ, который отличается от 200. Здесь есть ещё одна интересная деталь, которая введена в HTTP 1.1, и на которую стоит обратить внимание. После выполнения запроса мы не выпали из telnet и не оказались в bash. Это значит, что подключение не было закрыто, и мы можем продолжить вводить данные. Cделаем HEAD-запрос на тот же самый домен:

HEAD / HTTP/1.1
host: google.com

HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Fri, 28 Feb 2020 06:11:31 GMT
Expires: Sun, 29 Mar 2020 06:11:31 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN

Мы снова получили ответ, но уже без body, поскольку использовали HEAD, а не GET-запрос.

Механизм работы keep-alive

HTTP 1.1 вводит ещё одно понятие по умолчанию, которое называется keep-alive. keep-alive означает, что соединение TCP, по которому ходит HTTP, не закрывается. Причём по умолчанию так должны себя вести все веб-сервера. Основная цель введения этой фичи в том, чтобы сократить использование ресурсов, уменьшить нагрузку на процессор, открывать меньше TCP-соединений (установка каждого TCP-соединения занимает время), уменьшить время ожидания (latency). Когда мы открываем сайт, то обычно с одного домена грузится несколько ресурсов. keep-alive позволяет открывать и использовать одно соединение, которое не будет закрыто до тех пор, пока это не будет указано явно, либо не произойдет таймаут. Таймаут зависит от того, какой браузер и какой веб-сервер используется.

Мы также можем указать, что хотим закрыть соединение. Для этого после установки соединения и передачи стандартных заголовков нужно передать еще один заголовок. Он называется connection: close. Тогда keep-alive будет отключен, и после получения ответа мы увидим собщение, что хост закрыл соединение: Connection closed by foreign host.


Дополнительные материалы

  1. Стандарт HTTP 1.1
  2. Википедия / Постоянное HTTP-соединение

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Фронтенд-разработчик
Профессия
Разработка фронтенд-компонентов веб-приложений
30 июня 10 месяцев
Иконка программы Python-разработчик
Профессия
Разработка веб-приложений на Django
30 июня 10 месяцев
Иконка программы PHP-разработчик
Профессия
Разработка веб-приложений на Laravel
30 июня 10 месяцев
Иконка программы Node.js-разработчик
Профессия
Разработка бэкенд-компонентов веб-приложений
30 июня 10 месяцев
Иконка программы Fullstack-разработчик
Профессия
Новый
Разработка фронтенд и бэкенд компонентов веб-приложений
30 июня 16 месяцев
Иконка программы Java-разработчик
Профессия
Разработка приложений на языке Java
30 июня 10 месяцев

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»