Skip to content

Commit c183dd1

Browse files
Add Zstandard compression support and update tests (#12201)
* Add comprehensive zstd compression support to ATS This patch adds full support for the zstd (Zstandard) compression algorithm throughout Apache Traffic Server, including build system integration, compression plugin support, Accept-Encoding header normalization, and comprehensive test coverage. Build system and dependencies: - Add CMake support for finding zstd library with new Findzstd.cmake - Update Docker build files to include libzstd-dev package - Add TS_HAS_ZSTD feature flag for conditional compilation Core compression support: - Extend compress plugin to support zstd compression alongside gzip and brotli - Add zstd stream handling structures and functions - Update compression configuration to include zstd in supported algorithms list - Add zstd compression type constant and related infrastructure Accept-Encoding header normalization: - Extend proxy.config.http.normalize_ae configuration to support values 4 and 5 for zstd normalization - Add zstd support to header normalization logic with proper priority handling (zstd > br > gzip) - Update HTTP transaction cache matching to handle zstd encoding - Add zstd token to header parsing infrastructure API and infrastructure: - Add TS_HTTP_VALUE_ZSTD and TS_HTTP_LEN_ZSTD constants - Update MIME field handling to recognize zstd encoding - Add zstd support to traffic_layout feature detection Test coverage: - Expand compress plugin tests to cover zstd compression scenarios - Add zstd test cases to Accept-Encoding normalization tests - Update golden files to include zstd compression test results - Add new compress3.config for zstd-specific plugin configuration - Test all combinations of zstd, br, and gzip in various scenarios The implementation follows RFC 8878 standards for zstd compression and maintains backward compatibility with existing gzip and brotli compression functionality. All tests pass and the feature is properly integrated with the existing caching and content negotiation mechanisms. Co-authored-by: JosiahWI <[email protected]>
1 parent 61d9346 commit c183dd1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2215
-95
lines changed

CMakeLists.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,33 @@ set(TS_USE_MALLOC_ALLOCATOR ${ENABLE_MALLOC_ALLOCATOR})
359359
set(TS_USE_ALLOCATOR_METRICS ${ENABLE_ALLOCATOR_METRICS})
360360
find_package(ZLIB REQUIRED)
361361

362+
find_package(zstd CONFIG QUIET)
363+
if(zstd_FOUND)
364+
365+
# Provide a compatibility target name if the upstream package does not export it
366+
# Our code links against `zstd::zstd`; upstream zstd usually exports
367+
# `zstd::libzstd_shared`/`zstd::libzstd_static`. Create an alias if needed.
368+
if(NOT TARGET zstd::zstd)
369+
if(TARGET zstd::libzstd_shared)
370+
set(_zstd_target zstd::libzstd_shared)
371+
elseif(TARGET zstd::libzstd_static)
372+
set(_zstd_target zstd::libzstd_static)
373+
elseif(TARGET zstd::libzstd)
374+
set(_zstd_target zstd::libzstd)
375+
endif()
376+
if(DEFINED _zstd_target)
377+
add_library(zstd_zstd INTERFACE)
378+
target_link_libraries(zstd_zstd INTERFACE ${_zstd_target})
379+
add_library(zstd::zstd ALIAS zstd_zstd)
380+
set(HAVE_ZSTD_H TRUE)
381+
else()
382+
set(HAVE_ZSTD_H FALSE)
383+
endif()
384+
endif()
385+
else()
386+
set(HAVE_ZSTD_H FALSE)
387+
endif()
388+
362389
# ncurses is used in traffic_top
363390
find_package(Curses)
364391
set(HAVE_CURSES_H ${CURSES_HAVE_CURSES_H})

ci/docker/deb/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ RUN apt-get update; apt-get -y dist-upgrade; \
5555
apt-get -y install libssl-dev libexpat1-dev libpcre3-dev libcap-dev \
5656
libhwloc-dev libunwind8 libunwind-dev zlib1g-dev \
5757
tcl-dev tcl8.6-dev libjemalloc-dev libluajit-5.1-dev liblzma-dev \
58-
libhiredis-dev libbrotli-dev libncurses-dev libgeoip-dev libmagick++-dev; \
58+
libhiredis-dev libbrotli-dev libncurses-dev libgeoip-dev libmagick++-dev \
59+
libzstd-dev; \
5960
# Optional: This is for the OpenSSH server, and Jenkins account + access (comment out if not needed)
6061
apt-get -y install openssh-server openjdk-8-jre && mkdir /run/sshd; \
6162
groupadd -g 665 jenkins && \

ci/docker/yum/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ RUN yum -y update; \
5252
# Devel packages that ATS needs
5353
yum -y install openssl-devel expat-devel pcre-devel libcap-devel hwloc-devel libunwind-devel \
5454
xz-devel libcurl-devel ncurses-devel jemalloc-devel GeoIP-devel luajit-devel brotli-devel \
55-
ImageMagick-devel ImageMagick-c++-devel hiredis-devel zlib-devel \
55+
ImageMagick-devel ImageMagick-c++-devel hiredis-devel zlib-devel zstd-devel \
5656
perl-ExtUtils-MakeMaker perl-Digest-SHA perl-URI; \
5757
# This is for autest stuff
5858
yum -y install python3 httpd-tools procps-ng nmap-ncat pipenv \

contrib/docker/ubuntu/noble/Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ RUN apt update \
4848
libpcre3-dev \
4949
hwloc \
5050
libbrotli-dev \
51+
libzstd-dev \
52+
luajit \
5153
libluajit-5.1-dev \
5254
libcap-dev \
5355
libmagick++-dev \

doc/admin-guide/files/records.yaml.en.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2170,10 +2170,14 @@ Proxy User Variables
21702170
normalize as for value ``1``
21712171
``3`` ``Accept-Encoding: br, gzip`` (if the header has ``br`` and ``gzip`` (with any ``q`` for either) then ``br, gzip``) **ELSE**
21722172
normalize as for value ``2``
2173+
``4`` ``Accept-Encoding: zstd`` if the header has ``zstd`` (with any ``q``) **ELSE**
2174+
normalize as for value ``2``
2175+
``5`` ``Accept-Encoding: zstd, br, gzip`` (supports all combinations of ``zstd``, ``br``, and ``gzip``) **ELSE**
2176+
normalize as for value ``4``
21732177
===== ======================================================================
21742178

21752179
This is useful for minimizing cached alternates of documents (e.g. ``gzip, deflate`` vs. ``deflate, gzip``).
2176-
Enabling this option is recommended if your origin servers use no encodings other than ``gzip`` or ``br`` (Brotli).
2180+
Enabling this option is recommended if your origin servers use no encodings other than ``gzip``, ``br`` (Brotli), or ``zstd`` (Zstandard).
21772181

21782182
Security
21792183
========

doc/admin-guide/plugins/compress.en.rst

Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,59 @@ supported-algorithms
202202

203203
Provides the compression algorithms that are supported, a comma separate list
204204
of values. This will allow |TS| to selectively support ``gzip``, ``deflate``,
205-
and brotli (``br``) compression. The default is ``gzip``. Multiple algorithms can
206-
be selected using ',' delimiter, for instance, ``supported-algorithms
207-
deflate,gzip,br``. Note that this list must **not** contain any white-spaces!
205+
brotli (``br``), and zstd (``zstd``) compression. The default is ``gzip``.
206+
Multiple algorithms can be selected using ',' delimiter, for instance,
207+
``supported-algorithms deflate,gzip,br,zstd``. Note that this list must **not**
208+
contain any white-spaces!
209+
210+
============== =================================================================
211+
Algorithm Description
212+
============== =================================================================
213+
gzip Standard gzip compression (default, widely supported)
214+
deflate Deflate compression (RFC 1951)
215+
br Brotli compression (modern, efficient)
216+
zstd Zstandard compression (fast, high compression ratio)
217+
============== =================================================================
208218

209219
Note that if :ts:cv:`proxy.config.http.normalize_ae` is ``1``, only gzip will
210-
be considered, and if it is ``2``, only br or gzip will be considered.
220+
be considered, if it is ``2``, only br or gzip will be considered, if it is ``4``,
221+
only zstd, br, or gzip will be considered, and if it is ``5``, all combinations
222+
of zstd, br, and gzip will be considered.
223+
224+
gzip-compression-level
225+
-----------------------
226+
227+
Sets the compression level for gzip compression. Valid values are 1-9, where
228+
1 is fastest compression (lowest compression ratio) and 9 is slowest compression
229+
(highest compression ratio). The default is 6, which provides a good balance
230+
between compression speed and ratio.
231+
232+
brotli-compression-level
233+
-------------------------
234+
235+
Sets the compression level for Brotli compression. Valid values are 0-11, where
236+
0 is fastest compression (lowest compression ratio) and 11 is slowest compression
237+
(highest compression ratio). The default is 6, which provides a good balance
238+
between compression speed and ratio.
239+
240+
brotli-lgwin
241+
------------
242+
243+
Sets the window size for Brotli compression. Valid values are 10-24, where
244+
larger values provide better compression but use more memory. The default is 16.
245+
This parameter controls the sliding window size used during compression:
246+
247+
- 10: 1KB window (fastest, least memory)
248+
- 16: 64KB window (default, good balance)
249+
- 24: 16MB window (slowest, most memory, best compression)
250+
251+
zstd-compression-level
252+
----------------------
253+
254+
Sets the compression level for Zstandard compression. Valid values are 1-22, where
255+
1 is fastest compression (lowest compression ratio) and 22 is slowest compression
256+
(highest compression ratio). The default is 12, which provides an excellent
257+
balance between compression speed and ratio for web content.
211258

212259
Examples
213260
========
@@ -224,6 +271,10 @@ might create a configuration with the following options::
224271
compressible-status-code 200, 206
225272
minimum-content-length 860
226273
flush false
274+
gzip-compression-level 6
275+
brotli-compression-level 6
276+
brotli-lgwin 16
277+
zstd-compression-level 12
227278

228279
# Now set a configuration for www.example.com
229280
[www.example.com]
@@ -242,14 +293,38 @@ might create a configuration with the following options::
242293
flush true
243294
supported-algorithms gzip,deflate
244295

245-
# Supports brotli compression
296+
# Supports brotli compression with custom settings
246297
[brotli.compress.com]
247298
enabled true
248299
compressible-content-type text/*
249300
compressible-content-type application/json
250301
content_type_ignore_parameters true
251302
flush true
252303
supported-algorithms br,gzip
304+
brotli-compression-level 8
305+
brotli-lgwin 20
306+
307+
# Supports zstd compression for high efficiency
308+
[zstd.compress.com]
309+
enabled true
310+
compressible-content-type text/*
311+
compressible-content-type application/json
312+
compressible-content-type application/javascript
313+
flush true
314+
supported-algorithms zstd,gzip
315+
zstd-compression-level 15
316+
317+
# Supports all compression algorithms with optimized settings
318+
[all.compress.com]
319+
enabled true
320+
compressible-content-type text/*
321+
compressible-content-type application/json
322+
flush true
323+
supported-algorithms zstd,br,gzip,deflate
324+
gzip-compression-level 7
325+
brotli-compression-level 9
326+
brotli-lgwin 18
327+
zstd-compression-level 10
253328

254329
# This origin does it all
255330
[bar.example.com]

doc/developer-guide/plugins/http-headers/header-functions.en.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ headers.
9292
``TS_HTTP_VALUE_GZIP``
9393
"gzip"
9494

95+
``TS_HTTP_VALUE_ZSTD``
96+
"zstd"
97+
9598
``TS_HTTP_VALUE_IDENTITY``
9699
"identity"
97100

doc/release-notes/whats-new.en.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ Plugins
185185
* xdebug - ``--enable`` option to selectively enable features has been added
186186
* system_stats - Stats about memory have been added
187187
* slice plugin - This plugin was promoted to stable.
188+
* compress plugin - Added support for Zstandard (zstd) compression algorithm.
188189

189190
JSON-RPC
190191
^^^^^^^^

include/proxy/hdrs/HTTP.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ extern c_str_view HTTP_VALUE_COMPRESS;
368368
extern c_str_view HTTP_VALUE_DEFLATE;
369369
extern c_str_view HTTP_VALUE_GZIP;
370370
extern c_str_view HTTP_VALUE_BROTLI;
371+
extern c_str_view HTTP_VALUE_ZSTD;
371372
extern c_str_view HTTP_VALUE_IDENTITY;
372373
extern c_str_view HTTP_VALUE_KEEP_ALIVE;
373374
extern c_str_view HTTP_VALUE_MAX_AGE;

include/proxy/hdrs/MIME.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,8 @@ extern c_str_view MIME_VALUE_COMPRESS;
602602
extern c_str_view MIME_VALUE_DEFLATE;
603603
extern c_str_view MIME_VALUE_GZIP;
604604
extern c_str_view MIME_VALUE_BROTLI;
605+
extern c_str_view MIME_VALUE_ZSTD;
606+
605607
extern c_str_view MIME_VALUE_IDENTITY;
606608
extern c_str_view MIME_VALUE_KEEP_ALIVE;
607609
extern c_str_view MIME_VALUE_MAX_AGE;

0 commit comments

Comments
 (0)