В середине сентября в Google Chrome Canary в качестве эксперимента добавили поддержку протокола HTTP/3. Он обеспечивает работу HTTP вместе с QUIC. О возможностях протокола читайте в адаптированном переводе статьи HTTP/3: the past, the present and the future из блога Cloudflare.
Практически все инновации в интернете сталкиваются с фундаментальным вопросом: где в первую очередь должна поддерживаться новинка: на стороне сервера или на стороне браузера? В случае с протоколом передачи гипертекста ответ на этот вопрос однозначный: технологию должен поддерживать как сервер, так и клиент. В противном случае протокол не получится протестировать и использовать.
Компания Cloudflare входит в число пионеров новых веб-стандартов. Она участвовала в разработке разных технологий: HTTP/2, TLS 1.3 и ESNI. Cloudflare сотрудничали с другими командами, включая разработчиков браузеров. Работа над HTTP/3 также велась совместно с партнерами, включая команды Google Chrome и Mozilla Firefox.
В результате 26 сентября компания Cloudflare объявила о поддержке HTTP/3. Mozilla присоединится к инициативе в ближайшее время. Для рядовых пользователей это значит, что интернет становится быстрее и удобнее.
CTO Firefox Эрик Рескорла прокомментировал новость: «Разработка нового сетевого протокола — сложная задача. В течение нескольких лет мы работали с Cloudflare и другими партнёрами по отрасли, чтобы внедрить сначала TLS 1.3, а теперь HTTP/3 поверх QUIC».
Рескорла подчёркивает важный вклад Cloudflare в развитие HTTP/3 — обеспечение серверной поддержки нового протокола на ранних стадиях разработки.
Чтобы понимать преимущества HTTP/3, необходимо рассмотреть эволюцию протокола HTTP.
Начать стоит с 1996 года, когда была опубликована спецификация HTTP 1.0. В нём определяется текстовый формат HTTP, каким мы знаем его сегодня. Для удобства читателей автор оригинальной публикации предлагает притвориться, как будто версии HTTP 0.9 не существовало.
В HTTP 1.0 для каждого запроса и ответа между клиентом и сервером создаётся новое TCP-соединение. Это значит, что обмен данными замедляется, так как перед каждым запросом завершается взаимодействие TCP и TLS.
Более того, вместо немедленной отправки данных после соединения TCP использует так называемый «медленный старт». Он необходим, чтобы алгоритм управления перегрузкой определил объём данных, которые могут быть отправлены в любой момент времени без риска получить перегрузку, с которой не справится сеть. Но из-за «медленного старта» TCP не может использовать всю пропускную способность сети.
В HTTP 1.1 была предпринята попытка решить эту проблему. Проблема решалась с помощью поддерживающих соединений, которые позволяли клиентам повторно использовать TCP соединения. Это снижало стоимость «медленного старта» и установки соединения для каждого запроса. Но решение не стало панацеей. Множественные запросы теперь могли использовать общее соединение, но они всё равно выполнялись последовательно. Поэтому сервер мог выполнять только один запрос и ответ в конкретный момент времени для каждого соединения.
С развитием интернета браузеры столкнулись с дополнительным вызовом. Обозревателям пришлось учиться параллельно получать и рендерить большие объёмы данных, так как веб-страницы использовали больше ресурсов: CSS, JavaScript, изображения и так далее.
HTTP 1.1 позволял клиенту обрабатывать только один запрос в конкретный момент времени. Поэтому для параллельной работы браузеры использовали множество TCP-соединений одновременно. Это сводило на нет идею поддерживающих соединений. То есть разработчики протокола HTTP вернулись в точку отправления.
Наконец спустя более чем 10 лет появились SPDY и HTTP/2. В числе других нововведений были представлены HTTP-потоки. Это абстракция, которая позволяет HTTP выполнять множество запросов через одно TCP-соединение. Это позволяет браузерам повторно использовать TCP-соединения и повышает эффективность работы клиента.
Но и это решение не стало панацеей. HTTP/2 решает старую проблему — неэффективное использование TCP-соединения. Эта версия протокола поддерживает выполнение множества запросов через одно соединение одновременно. Однако все запросы и ответы подвержены потере пакетов из-за перегрузки сети. Проблема сохраняется даже в том случае, если потеря пакетов касается только одного запроса. HTTP/2 умеет разделять запросы и ответы в потоках, но TCP не умеет работать с этой абстракцией.
Задача TCP — доставить поток байтов, расположенных в нужном порядке, из одной точки в другую. Когда TCP теряет часть байтов, в потоке данных образуется пробел. TCP отправляет повторный запрос, чтобы восстановить утраченные байты. В это время данные, которые следуют за потерянными байтами, не доставляются в пункт назначения. Эта проблема известна как блокировка заголовка или head-of-line blocking.
Описанные выше проблемы успешно решает HTTP/3. Вместо TCP новая версия HTTP использует QUIC. Это экспериментальный транспортный протокол, разработанный Google. В QUIC потоки реализованы как объекты первого класса.
Потоки в QUIC используют общие соединения. Поэтому здесь нет проблемы «медленного старта». При этом потоки остаются независимыми, поэтому потеря части пакета не приводит к задержке передачи данных. Это возможно благодаря реализации пакетов QUIC поверх протокола UDP.
Использование UDP обеспечивает большую гибкость по сравнению с TCP. Например, обновления протокола не привязаны к обновлениям операционной системы как в случае с TCP. С помощью QUIC потоки уровня HTTP реализуются поверх потоков QUIC. Это обеспечивает преимущества HTTP/2 без эффекта head-of-line blocking.
В QUIC комбинируется трёхстороннее рукопожатие TCP с рукопожатием TLS 1.3. Благодаря этому по умолчанию обеспечивается возможность шифрования и аутентификации. Также этот подход обеспечивает быструю установку соединения. Когда HTTP-сессия требует нового соединения QUIC, задержка передачи данных получается короче, чем при использовании TCP и TLS.
Но почему бы просто не использовать HTTP/2 поверх QUIC вместо создания новой версии HTTP? Ведь HTTP/2 тоже работает с множеством потоков. На практике всё оказалось сложнее.
Действительно, некоторые возможности HTTP/2 можно использовать поверх QUIC. Но речь идет только о некоторых, а не обо всех возможностях. Например, возможность применения схемы сжатия заголовков HPAC зависит от порядка доставки HTTP-запросов в конечную точку. QUIC не гарантирует сохранения порядка потоков.
Эта ситуация потребовала разработки новой схемы сжатия заголовков QPAC. В свою очередь, QPAC требует изменений в протоколе HTTP. Также некоторые возможности HTTP/2, например, управление потоками, уже реализованы в QUIC. Поэтому их удалили из HTTP/3, чтобы не усложнять новую версию протокола.
Компания Cloudflare реализовала возможность практического использования HTTP/3 и QUIC с помощью quiсhe — опенсорсного решения, написанного на языке программирования Rust. Quiche позволяет использовать HTTP/3 на клиенте и на сервере.
На момент выхода оригинальной публикации возможность использования HTTP/3 доступна только части клиентов Cloudflare. Функцию необходимо активировать вручную в панели управления. После этого можно воспользоваться одним из описанных ниже способов, чтобы оценить преимущества HTTP/3.
Чтобы получить доступ к сайту через HTTP/3, нужно установить последнюю версию Chrome Canary. Затем нужно запустить обозреватель в командной строке с флагами -- enable-quick
и -- quic-version=h3-23
.
После этого введите URL сайта в адресную строку браузера. Чтобы убедиться, что ресурс загрузился с помощью HTTP/3, используйте вкладку Network в инструментах разработчика Chrome. Возможно, для установки соединения с помощью HTTP/3 придётся несколько раз перезагрузить страницу.
Обратите внимание, HTTP/3 остаётся экспериментальной функцией, поэтому пока этот протокол в в Google Chrome отображается нак http/2 + quic/99.
Утилита командной строки curl также поддерживает HTTP/3. Чтобы воспользоваться возможностью, установите последнюю версию инструмента и включите поддержку новой версии протокола с помощью инструкции.
Если вы пользуетесь macOS, можно установить последнюю версию curl с поддержкой HTTP/3 из Homebrew:
% brew install --HEAD -s [https://raw.githubusercontent.com/cloudflare/homebrew-cloudflare/master/curl.rb](https://raw.githubusercontent.com/cloudflare/homebrew-cloudflare/master/curl.rb)
Чтобы использовать протокол HTTP/3, нужно добавлять флаг --http3
к командам curl.
% ./curl -I https://blog.cloudflare.com/ --http3
HTTP/3 200
date: Tue, 17 Sep 2019 12:27:07 GMT
content-type: text/html; charset=utf-8
set-cookie: __cfduid=d3fc7b95edd40bc69c7d894d296564df31568723227; expires=Wed, 16-Sep-20 12:27:07 GMT; path=/; domain=.blog.cloudflare.com; HttpOnly; Secure
x-powered-by: Express
cache-control: public, max-age=60
vary: Accept-Encoding
cf-cache-status: HIT
age: 57
expires: Tue, 17 Sep 2019 12:28:07 GMT
alt-svc: h3-23=":443"; ma=86400
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 517b128df871bfe3-MAN
Компания Cloudflare разработа ещё одно решение: HTTP/3-клиент, работающий поверх quiche. Чтобы воспользоваться возможностью, клонируйте репозиторий.
$ git clone --recursive https://github.com/cloudflare/quiche
Запустите сборку. Обратите внимание, у вас должны быть установлены Rust и Cargo.
$ cargo build --examples
Теперь выполните HTTP/3 запрос.
$ RUST_LOG=info target/debug/examples/http3-client https://blog.cloudflare.com/
Cloudflare, Mozilla, Google и другие представители индустрии работают над протоколом HTTP/3 и QUIC. В ближайшее время можно ожидать широкого внедрения новой версии протокола. Конечному пользователю новая версия HTTP обеспечит более быстрый и безопасный веб.
Адаптированный перевод статьи HTTP/3: the past, the present, and the future by Rustam Lalkaka and Alessandro Ghedini. Мнение администрации «Хекслета» может не совпадать с мнением авторов оригинальной публикации.