HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>Протокол HTTP 1.1 расширяет возможности предыдущей версии и добавляет виртуальные хосты. Сейчас мы посмотрим, для чего это нужно, и как это работает.</p>
1 <p>Протокол HTTP 1.1 расширяет возможности предыдущей версии и добавляет виртуальные хосты. Сейчас мы посмотрим, для чего это нужно, и как это работает.</p>
2 <p>Предыдущая версия требует наличия только<em>request line</em>. В ней мы описываем, какой путь на сайте мы хотим посмотреть. Но упоминания сайта как такового здесь нет. При этом мы подключаемся по telnet к конкретному IP адресу. Отсюда можно сделать вывод, что понятие домена (доменного имени) при использовании HTTP 1.0 неважно. Действительно, эта версия была создана в те времена, когда считалось, что один IP адрес соответствует одному сайту. Естественно, это не могло продолжаться долго, потому что рост интернета был стремительным. И HTTP 1.1 ввел такое понятие как виртуальные хосты. С точки зрения реализации в протоколе HTTP появилась одна небольшая деталь. Кроме request line стал обязательным еще и заголовок, который называется host. Он определяет, какой именно домен должен быть возвращен с этого IP адреса.</p>
2 <p>Предыдущая версия требует наличия только<em>request line</em>. В ней мы описываем, какой путь на сайте мы хотим посмотреть. Но упоминания сайта как такового здесь нет. При этом мы подключаемся по telnet к конкретному IP адресу. Отсюда можно сделать вывод, что понятие домена (доменного имени) при использовании HTTP 1.0 неважно. Действительно, эта версия была создана в те времена, когда считалось, что один IP адрес соответствует одному сайту. Естественно, это не могло продолжаться долго, потому что рост интернета был стремительным. И HTTP 1.1 ввел такое понятие как виртуальные хосты. С точки зрения реализации в протоколе HTTP появилась одна небольшая деталь. Кроме request line стал обязательным еще и заголовок, который называется host. Он определяет, какой именно домен должен быть возвращен с этого IP адреса.</p>
3 <p>На самом деле, иногда в поведение HTTP и серверов заложены какие-то умолчания, например, они могут исправлять ошибки пользователей. То есть можно сделать запрос HTTP 1.1 без указания хоста и получить что-то в ответ. По-хорошему такой запрос вообще не должен проходить, но часто веб-серверы отдают сайт, который указан в настройках по дефолту. Например, в Nginx есть сайт по умолчанию. Но так нельзя делать запросы в принципе, это не соответствует стандарту. Нужно всегда указывать хост, иначе ответ не гарантирован. Сегодня он один, а завтра другой. Некоторые библиотеки вообще могут так не работать. Виртуальные хосты являются неотъемлемым атрибутом HTTP 1.1. Их нельзя игнорировать.</p>
3 <p>На самом деле, иногда в поведение HTTP и серверов заложены какие-то умолчания, например, они могут исправлять ошибки пользователей. То есть можно сделать запрос HTTP 1.1 без указания хоста и получить что-то в ответ. По-хорошему такой запрос вообще не должен проходить, но часто веб-серверы отдают сайт, который указан в настройках по дефолту. Например, в Nginx есть сайт по умолчанию. Но так нельзя делать запросы в принципе, это не соответствует стандарту. Нужно всегда указывать хост, иначе ответ не гарантирован. Сегодня он один, а завтра другой. Некоторые библиотеки вообще могут так не работать. Виртуальные хосты являются неотъемлемым атрибутом HTTP 1.1. Их нельзя игнорировать.</p>
4 <p>Сейчас мы можем сделать GET-запрос с использованием протокола версии 1.1 и посмотреть, что он нам вернет:</p>
4 <p>Сейчас мы можем сделать GET-запрос с использованием протокола версии 1.1 и посмотреть, что он нам вернет:</p>
5 <p>В итоге мы получили ответ, код которого равен 200. Здесь есть еще одна интересная деталь, которая введена в HTTP 1.1. После выполнения запроса мы не выпали из telnet и не оказались в bash. Это значит, что подключение не было закрыто, и мы можем продолжить вводить данные. Сделаем HEAD-запрос на тот же самый домен:</p>
5 <p>В итоге мы получили ответ, код которого равен 200. Здесь есть еще одна интересная деталь, которая введена в HTTP 1.1. После выполнения запроса мы не выпали из telnet и не оказались в bash. Это значит, что подключение не было закрыто, и мы можем продолжить вводить данные. Сделаем HEAD-запрос на тот же самый домен:</p>
6 <p>Мы снова получили ответ, но уже без body (Слово "Done!"), поскольку использовали HEAD, а не GET-запрос:</p>
6 <p>Мы снова получили ответ, но уже без body (Слово "Done!"), поскольку использовали HEAD, а не GET-запрос:</p>
7 <p>HTTP 1.1 вводит еще одно понятие по умолчанию, которое называется<em>keep-alive</em>.<em>Keep-alive</em>означает, что соединение TCP, по которому ходит HTTP, не закрывается. Причем по умолчанию так должны себя вести все веб-серверы. Основная цель введения этой возможности в том, чтобы сократить использование ресурсов, уменьшить нагрузку на процессор, открывать меньше TCP-соединений (установка каждого TCP-соединения занимает время), уменьшить время ожидания (latency). Когда мы открываем сайт, то обычно с одного домена грузится несколько ресурсов.<em>Keep-alive</em>позволяет открывать и использовать одно соединение, которое не будет закрыто до тех пор, пока это не будет указано явно, либо не произойдет таймаут. Таймаут зависит от того, какой браузер и какой веб-сервер используется.</p>
7 <p>HTTP 1.1 вводит еще одно понятие по умолчанию, которое называется<em>keep-alive</em>.<em>Keep-alive</em>означает, что соединение TCP, по которому ходит HTTP, не закрывается. Причем по умолчанию так должны себя вести все веб-серверы. Основная цель введения этой возможности в том, чтобы сократить использование ресурсов, уменьшить нагрузку на процессор, открывать меньше TCP-соединений (установка каждого TCP-соединения занимает время), уменьшить время ожидания (latency). Когда мы открываем сайт, то обычно с одного домена грузится несколько ресурсов.<em>Keep-alive</em>позволяет открывать и использовать одно соединение, которое не будет закрыто до тех пор, пока это не будет указано явно, либо не произойдет таймаут. Таймаут зависит от того, какой браузер и какой веб-сервер используется.</p>
8 <p>Мы также можем указать, что хотим закрыть соединение. Для этого после установки соединения и передачи стандартных заголовков нужно передать еще один заголовок. Он называется connection: close. Тогда<em>keep-alive</em>будет отключен, и после получения ответа мы увидим сообщение, что хост закрыл соединение:<em>Connection closed by foreign host</em>.</p>
8 <p>Мы также можем указать, что хотим закрыть соединение. Для этого после установки соединения и передачи стандартных заголовков нужно передать еще один заголовок. Он называется connection: close. Тогда<em>keep-alive</em>будет отключен, и после получения ответа мы увидим сообщение, что хост закрыл соединение:<em>Connection closed by foreign host</em>.</p>