Открыть сервис

HPACK

HPACK — это стандартизированный метод сжатия заголовков HTTP, разработанный для протокола HTTP/2. Он предназначен для уменьшения избыточности и объёма передаваемых метаданных (заголовков запросов и ответов), что критически важно для повышения производительности веб-приложений, особенно при большом количестве параллельных соединений. HPACK определён в документе RFC 7541 (2015 год) и является обязательным компонентом HTTP/2, в отличие от HTTP/1.1, где сжатие заголовков не было стандартизировано и реализовывалось несовместимыми способами (например, через gzip).

История и предпосылки

До появления HTTP/2 каждый HTTP-запрос и ответ в HTTP/1.1 передавались в виде текстовых строк, включая заголовки. Это приводило к значительному расходу полосы пропускания, особенно на повторяющиеся заголовки (например, Cookie, User-Agent, Accept). В HTTP/1.1 существовала экспериментальная возможность сжатия заголовков (например, с помощью gzip), но она не была стандартизирована и часто приводила к уязвимостям (атаки типа CRIME, BREACH), из-за чего от неё отказались.

При разработке HTTP/2, который базируется на двоичном формате фреймов и мультиплексировании, стало очевидно, что сжатие заголовков необходимо для эффективной работы. Группа IETF HTTPbis, создавшая HTTP/2, разработала HPACK как специализированный алгоритм сжатия, учитывающий особенности HTTP-заголовков: их повторяемость, наличие имён и значений, а также необходимость защиты от атак по сторонним каналам (side-channel attacks).

Принцип работы

HPACK основан на двух ключевых механизмах: статической таблице и динамической таблице, а также на кодировании с помощью кода Хаффмана для значений заголовков.

Статическая таблица

Это предопределённая таблица, содержащая 61 наиболее часто встречающийся заголовок (например, :method: GET, :path: /, content-type, accept-encoding). Каждому заголовку в таблице соответствует индекс. Если заголовок совпадает с записью из статической таблицы, он передаётся не текстом, а одним байтом (индексом). Это позволяет сжимать самые распространённые заголовки практически до нуля.

Динамическая таблица

Это изменяемая таблица, которая строится в процессе обмена данными между клиентом и сервером. Каждый новый заголовок, не найденный в статической таблице, может быть добавлен в динамическую таблицу (при условии, что отправитель указывает это в кодированном представлении). Размер динамической таблицы ограничен (настраивается через параметр SETTINGS_HEADER_TABLE_SIZE, по умолчанию 4096 байт). При переполнении таблицы старые записи вытесняются по принципу LRU (Least Recently Used — наименее недавно использованные).

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

Кодирование Хаффмана

Для значений заголовков, которые не удаётся сжать таблицами (например, длинные строки, уникальные идентификаторы), HPACK использует статический код Хаффмана, оптимизированный для HTTP-трафика. Это позволяет уменьшить размер текстовых значений на 30–50% без потери информации.

Формат кодирования

HPACK оперирует тремя типами инструкций:

Преимущества и недостатки

Преимущества

Недостатки

Применение

HPACK является обязательным для всех реализаций HTTP/2. Он используется в современных веб-браузерах (Chrome, Firefox, Safari, Edge), веб-серверах (nginx, Apache, IIS, Caddy), а также в прокси-серверах и CDN (Cloudflare, Akamai). Без HPACK HTTP/2 был бы значительно менее эффективным, так как мультиплексирование множества потоков привело бы к огромному объёму заголовков.

Кроме того, HPACK оказал влияние на разработку QPACK — алгоритма сжатия заголовков для HTTP/3 (основанного на QUIC). QPACK решает проблему потери пакетов, характерную для ненадёжного транспорта QUIC, путём введения двух типов динамических таблиц (для запросов и для ответов) и механизма кодирования с возможностью восстановления.

Критика и ограничения

Несмотря на эффективность, HPACK критикуется за сложность реализации по сравнению с текстовым форматом HTTP/1.1. Некоторые разработчики отмечают, что динамическая таблица может быть источником ошибок при несинхронизированном состоянии (например, при использовании прокси-серверов, которые модифицируют заголовки). Также HPACK не поддерживает сжатие тела запроса или ответа — для этого используются отдельные алгоритмы (например, gzip, brotli).

Пример работы

Допустим, клиент отправляет запрос: `` :method: GET :path: /index.html :scheme: https :authority: example.com accept-encoding: gzip, deflate user-agent: Mozilla/5.0 ``

В HPACK:

Итоговый размер заголовков в HTTP/2 может составлять 20–30 байт вместо 200–300 байт в HTTP/1.1.

Источники

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →