Если у вас есть опыт работы с HTTP/2, вы, возможно, знаете, что высокая производительность HTTP/2 зависит от следующих функций, таких как мультиплексирование потоков, явные зависимости потоков иПуш сервера.
Но есть еще одна особенность, не очевидная, но очень важная, это сжатие заголовков HPACK.
В этой статье приведены некоторые причины для разработки HPACK, а также преимущества пропускной способности и задержки, которые он дает.
какой-то фон
Обычное соединение HTTPS на самом деле представляет собой суперпозицию нескольких соединений многоуровневой модели. Самое простое соединение, о котором вы обычно заботитесь, — это TCP-соединение (транспортный уровень), кроме того, у вас есть TLS-соединение (гибрид транспортного/прикладного уровня), а затем, наконец, HTTP-соединение (прикладной уровень).
Ранее HTTP-сжатие выполнялось с помощью gzip на уровне TLS. И заголовок, и тело сжимаются, поскольку уровень TLS не знает о типе передаваемых данных. На самом деле оба используютDEFLATEалгоритм сжатия.
Позже был предложен новый алгоритм SPDY, предназначенный для сжатия заголовков. Алгоритм включает в себя использование словаря предварительной обработки, включая динамическое кодирование Хаффмана и сопоставление строк, хотя он специально разработан для заголовков, но все же использует алгоритм DEFLATE.
На самом деле и DEFLATE, и SPDY подвержены риску атаки, потому что злоумышленник может извлечь ключ авторизации в файле cookie из сжатого заголовка: поскольку DEFLATE использует обратное сопоставление строк и динамическое кодирование Хаффмана, злоумышленник может контролировать часть заголовков запроса. , а затем измените часть запроса, чтобы постепенно восстановить полный файл cookie, наблюдая за изменением размера после сжатия.
Из-за этого риска сжатие заголовков отключено в большинстве пограничных сетей. Пока появление HTTP/2 не изменило эту дилемму.
HPACK
HTTP/2 поддерживает новый алгоритм сжатия заголовков под названием HPACK. HPACK был разработан и спроектирован с учетом опасности нападения, поэтому его можно безопасно использовать.
HPACK может защищаться от атак злоумышленников, потому что он не использует обратное сопоставление строк и динамический Хаффман, как DEFLATE, он использует следующие три метода для сжатия:
- Статическая таблица словаря: предопределенная таблица словаря, состоящая из 61 обычного поля заголовка и некоторых предопределенных значений.
- Таблица динамического словаря: список фактических полей заголовков, встречающихся в соединении. Эта словарная таблица имеет ограничение по размеру, в нее добавляются новые ключи, а старые могут быть удалены.
- Кодирование Хаффмана: статическоеКодирование ХаффманаМожно закодировать любую строку: имя или значение. Эта кодировка специально используется в заголовках запросов/ответов HTTP, а кодировки ASCII и строчных букв короче. Самая короткая кодировка может иметь длину всего 5 бит (один байт 8 бит), поэтому максимальная исходная длина и соотношение сжатой длины составляют 8: 5 (или коэффициент сжатия 37,5%).
поток HPACK
Когда HPACK необходимо закодировать заголовок в форме имя:значение, он сначала просматривает статические и динамические таблицы словаря. Если присутствуют все name:values, он просто ищет соответствующую запись в таблице словаря. Обычно для этого требуется 1 байт пространства, а 2 байта достаточно в большинстве случаев. Весь заголовок кодируется одним байтом, и это здорово.
Поскольку многие заголовки повторяются, вышеописанная стратегия имеет высокий уровень успеха. Например, такие заголовки:authority:www.cloudflare.comИли несколько больших файлов cookie, что обычно бывает.
Когда HPACK не может сопоставить весь заголовок в таблице словаря, он попытается найти заголовок с таким же именем. Наиболее распространенные имена хедеров будут доступны в статических таблицах, таких какcontent-encoding, cookie, etag. Остальные могут иметь дубликаты в динамической таблице. Например, Cloudflare будет выделять на каждый ответcf-rayзаголовок, и его значение другое, но имя можно использовать повторно.
Если имя найдено, оно может быть снова представлено 1~2 байтами, в противном случае будет использоваться другая родная кодировка или кодировка Хаффмана (в зависимости от того, что короче). Значение в шапке по тому же принципу.
Мы обнаружили, что использование только кодировки Хаффмана экономит 30% размера заголовка.
Хотя HPACK не выполняет сопоставление строк, чтобы злоумышленник мог найти значение заголовка, он должен угадать значение всей записи таблицы словаря, а не выполнять пошаговое сопоставление, как DEFLATE, но HPACK все еще может быть атакован.
Request Headers
Среди преимуществ, которые HPACK предоставляет для HTTP, запрос будет более выгодным, чем ответ. Заголовки запросов могут быть сжаты более эффективно, поскольку в заголовках больше повторений. Например, ниже приведены заголовки двух запросов с использованием браузера Chrome:
Request #1:
authority:
blog. cloudflare. com
method:GET
path: /
scheme:https
accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
accept-encoding:gzip, deflate, sdch, br
accept-language:en-US,en;q=0.8
cookie: 297 byte cookie
upgrade-insecure-requests:1
user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2853.0 Safari/537.36
Я отметил красным цветом заголовки, которые можно сжать с помощью статических таблиц словарей. Есть 3 поля:method:GET, path:/а такжеscheme:https, они всегда находятся в таблице статического словаря и будут закодированы как 1 байт, для некоторых других полей только имя будет закодировано как 1 байт:authority, accept, accept-encoding, accept-language, cookie , user-agent
Все остальные части отмечены зеленым цветом и обработаны по кодировке Хаффмана.
Если соответствующих заголовков нет, они будут вставлены в таблицу динамического словаря для использования в последующих запросах.
Давайте рассмотрим другую ситуацию:
authority:blog.cloudflare.com
method:GET
path:/assets/images/cloudflare-sprite-small.png
scheme:https
accept:image/webp,image/,/*;q=0.8
accept-encoding:gzip, deflate, sdch, br
accept-language:en-US,en;q=0.8
cookie: 297 byte cookie
referer:blog.cloudflare.com/assets/CSS/…
user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2853.0 Safari/537.36
Здесь я добавил закодированные поля синим цветом, они указывают, какие поля заголовка соответствуют таблице динамического словаря. Очевидно, что эти поля дублируются в разных запросах. В таблице статического словаря снова появляются два поля, что означает, что каждое поле может быть закодировано как строка из 1 или 2 байтов. Одно поле размером около 300 байтcookieзаголовок, другой длиной около 130 байтuser-agent. Длина 430 байт сжата до 4 байтов, что составляет 99%.
Короче говоря, больше, чем все повторные запросы, только две или три короткие строки будут закодированы как коды Хаффмана.
Это заголовки трафика портала доступа Cloudflare за 6 часов.
Мы видим, что заголовки из запроса сжаты на 76%. Поскольку на заголовки приходится большая часть трафика доступа, экономия места для всего трафика доступа значительна.Мы видим сокращение всего объема данных трафика на 53% благодаря сжатию HPACK.
О разнице между разными версиями http см. в этой статье https://mp.weixin.qq.com/s/GICbiyJpINrHZ41u_4zT-A.
Response Headers
Для заголовка ответа HPACK относительно менее выгоден.
Response #1:
cache-control:public, max-age=30
cf-cache-status:HIT
cf-h2-pushed:</assets/css/screen.css?v=2237be22c2>,</assets/js/jquery.fitvids.js?v=2237be22c2>
cf-ray:2ded53145e0c1ffa-DFW
content-encoding:gzip
content-type:text/html; charset=utf-8
date:Wed, 07 Sep 2016 21:41:23 GMT
expires:Wed, 07 Sep 2016 21:41:53 GMT
link:<//cdn.bizible.com/scripts/bizible.js>; rel=preload; as=script,code.jQuery.com/jQuery-1.11…; rel=preload; as=script
server:cloudflare-nginx
status:200
vary:Accept-Encoding
x-ghost-cache-status:From Cache
x-powered-by:Express
Большинство заголовков первого ответа будут закодированы по методу Хаффмана, а некоторые будут сопоставлены со статической таблицей словаря.
Response #2:
cache-control:public, max-age=31536000
cf-bgj:imgq:100
cf-cache-status:HIT
cf-ray:2ded53163e241ffa-DFW
content-type:image/png
date:Wed, 07 Sep 2016 21:41:23 GMT
expires:Thu, 07 Sep 2017 21:41:23 GMT
server:cloudflare-nginx
status:200
vary:Accept-Encoding
x-ghost-cache-status:From Cache
x-powered-by:Express
Опять же, синяя часть соответствует таблице динамического словаря, красная часть соответствует таблице статического словаря, а зеленая часть представляет строку, закодированную Хаффманом.
Второй ответ может соответствовать 7 из всех 12 заголовков. Среди оставшихся 5 есть 4 имени заголовка, которые можно сопоставить, а затем 6 строк будут использовать кодировку Хаффмана.
Несмотря на то, что заголовки двух истечений почти идентичны, они используют только кодировку Хаффмана, потому что они не совсем совпадают.
Чем больше запросов будет обработано, тем больше будет таблица динамического словаря, тем больше заголовков будет сопоставлено, а степень сжатия будет улучшена.
Ниже показана ситуация с заголовком в возвращаемом трафике.
Средняя степень сжатия составляет 69%. Но влияние общего экспортного потока не очень велико.
Сжатие может быть непростым для наблюдения, но у нас все еще есть экономия 1,4% всего исходящего трафика HTTP/2. Хотя это может показаться незначительным, степень сжатия данных во многих случаях увеличилась. Это число также может зависеть от того, как сайт обрабатывает большие файлы. Мы измерили экономию около 15% для некоторых сайтов.
Оригинальная ссылка:
blog.cloudflare.com/страх страданий — он и — есть…