Skip to content

Add Zstandard compression support and update tests #12201

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

JakeChampion
Copy link

@JakeChampion JakeChampion commented Apr 18, 2025

This pull request 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 test coverage.

Key Features

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

Accept-Encoding header normalization:

  • Extend proxy.config.http.normalize_ae configuration to support values 4 and 5 for zstd normalization
  • Update HTTP transaction cache matching to handle zstd encoding

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

Improved cache matching:

  • Fix Accept-Encoding quality calculation logic in HTTP transaction cache
  • Replace multiplicative quality combining with minimum quality selection
  • Remove problematic gzip-specific fallback logic that caused cache inconsistencies
  • Ensure proper cache behavior for all compression algorithms

Test Coverage

  • Comprehensive compress plugin tests covering zstd compression scenarios
  • Accept-Encoding normalization tests for all zstd combinations
  • Updated golden files to include zstd compression test results
  • New compress3.config for zstd-specific plugin configuration
  • Test all combinations of zstd, br, and gzip in various scenarios
  • Cache matching tests demonstrate correct behavior without workarounds

Standards Compliance

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 existing caching and content negotiation mechanisms.

Configuration

New normalization modes:

  • proxy.config.http.normalize_ae = 4: Prioritize zstd, fallback to br then gzip
  • proxy.config.http.normalize_ae = 5: Support all combinations of zstd, br, and gzip

Benefits

  • Improved compression ratios compared to gzip
  • Better performance than brotli for compression speed
  • Reduced bandwidth usage and faster page loads
  • Seamless integration with existing ATS infrastructure

@JakeChampion JakeChampion marked this pull request as ready for review April 18, 2025 18:34
@masaori335 masaori335 self-requested a review April 18, 2025 23:25
@masaori335 masaori335 added the compress compress plugin label Apr 18, 2025
@masaori335 masaori335 added this to the 10.2.0 milestone Apr 18, 2025
@masaori335
Copy link
Contributor

[approve ci]

@JakeChampion
Copy link
Author

@masaori335 do you know which files I need to modify to install zstd on the osx used in the Jenkins job?

@masaori335
Copy link
Contributor

We need to ask @ezelkow1 to install the package in the osx env, I guess.

However, this PR has #if HAVE_ZSTD_F check, why it's failing?

@cmcfarlen cmcfarlen self-requested a review April 21, 2025 22:23
@JakeChampion JakeChampion force-pushed the zstd branch 2 times, most recently from 0167bf5 to 74cd8b5 Compare April 22, 2025 07:51
@JakeChampion
Copy link
Author

We need to ask @ezelkow1 to install the package in the osx env, I guess.

However, this PR has #if HAVE_ZSTD_F check, why it's failing?

thank you, _F was a mistake, it was meant to be _H

@JakeChampion JakeChampion force-pushed the zstd branch 4 times, most recently from 308032c to c598282 Compare April 22, 2025 10:12
@JakeChampion
Copy link
Author

Looks like all the FreeBSD machines for CI are offline

Copy link
Contributor

@shukitchan shukitchan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really appreciate it if you can please add some documentation to the changes.

Thanks.

@cmcfarlen
Copy link
Contributor

Hi! This doesn't compile for me. I added a line to include/tscore/ink_config.cmake.in so HAVE_ZSTD_H would be truthy for the CPP macros. This lit up that code, but then there were several compiler errors:

/Users/cmcfarlen/projects/oss/trafficserver/plugins/compress/compress.cc:203:9: error: no member named 'zstd_ctx' in 'Data'; did you mean 'zstd_cctx'?
  203 |   data->zstd_ctx = nullptr;
      |         ^~~~~~~~
      |         zstd_cctx
/Users/cmcfarlen/projects/oss/trafficserver/plugins/compress/misc.h:93:14: note: 'zstd_cctx' declared here
   93 |   ZSTD_CCtx *zstd_cctx;
      |              ^
/Users/cmcfarlen/projects/oss/trafficserver/plugins/compress/compress.cc:206:11: error: no member named 'zstd_ctx' in 'Data'; did you mean 'zstd_cctx'?
  206 |     data->zstd_ctx = ZSTD_createCCtx();
      |           ^~~~~~~~
      |           zstd_cctx
/Users/cmcfarlen/projects/oss/trafficserver/plugins/compress/misc.h:93:14: note: 'zstd_cctx' declared here
   93 |   ZSTD_CCtx *zstd_cctx;
      |              ^
/Users/cmcfarlen/projects/oss/trafficserver/plugins/compress/compress.cc:207:16: error: no member named 'zstd_ctx' in 'Data'; did you mean 'zstd_cctx'?
  207 |     if (!data->zstd_ctx) {
      |                ^~~~~~~~
      |                zstd_cctx
/Users/cmcfarlen/projects/oss/trafficserver/plugins/compress/misc.h:93:14: note: 'zstd_cctx' declared here
   93 |   ZSTD_CCtx *zstd_cctx;
      |              ^

Please include this patch in your PR to enable the ZSTD code. Thanks!

diff --git a/include/tscore/ink_config.h.cmake.in b/include/tscore/ink_config.h.cmake.in
index 634ed94c3..7da0771fd 100644
--- a/include/tscore/ink_config.h.cmake.in
+++ b/include/tscore/ink_config.h.cmake.in
@@ -184,3 +184,5 @@ const int DEFAULT_STACKSIZE = @DEFAULT_STACK_SIZE@;
 #cmakedefine YAMLCPP_LIB_VERSION "@YAMLCPP_LIB_VERSION@"

 #cmakedefine01 TS_HAS_CRIPTS
+
+#cmakedefine HAVE_ZSTD_H 1

Copy link
Contributor

@cmcfarlen cmcfarlen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please patch ink_config.h and resolve compiler issues.

@JakeChampion JakeChampion force-pushed the zstd branch 3 times, most recently from 4b8603e to 72c0dbf Compare May 28, 2025 19:48
@bryancall
Copy link
Contributor

[approve ci autest]

@JakeChampion
Copy link
Author

@bryancall i think this is ready to review now 🙏

@JakeChampion JakeChampion force-pushed the zstd branch 11 times, most recently from 6a9110b to 6c3f2ca Compare July 15, 2025 17:06
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.
This patch fixes the Accept-Encoding quality calculation logic in the
HTTP transaction cache and updates test files to reflect the corrected
behavior, removing workarounds for previously broken cache matching.

Cache quality calculation improvements:
- Replace multiplicative quality combining with minimum quality
  selection for multiple content encodings
- Simplify wildcard matching to return quality directly
- Remove gzip-specific fallback logic that bypassed normal quality
  calculation and caused inconsistent cache behavior

Test updates for corrected behavior:
- Remove NOTICE comments describing broken cache matching behavior
- Update test expectations to match correct cache responses instead
  of workaround responses
- Fix cache hit/miss expectations for multi-encoding scenarios
- Add missing Content-Encoding headers in server responses
- Update response identifiers to match the actual cached alternates

Specific test corrections:
- "br, compress, gzip" now correctly matches "Br-Gzip-Accept-Encoding"
  instead of falling back to "Gzip-Accept-Encoding"
- "zstd, compress, gzip" now correctly matches "Zstd-Gzip-Accept-Encoding"
  instead of falling back to "Gzip-Accept-Encoding"
- "zstd, gzip;q=0.8" now correctly matches "Zstd-Gzip-Accept-Encoding"
  instead of falling back to "Gzip-Accept-Encoding"
- Individual encoding requests now create proper cache alternates
  instead of incorrectly matching empty encoding alternates

The previous multiplicative quality calculation (q_a * q_b) was causing
unexpectedly low quality scores and incorrect cache alternate selection.
The new minimum quality approach ensures that multi-encoding responses
are properly cached and matched according to HTTP content negotiation
standards.

All test cases now pass without workarounds and demonstrate correct
cache behavior for all compression algorithms (gzip, brotli, zstd)
across various Accept-Encoding
@JakeChampion JakeChampion force-pushed the zstd branch 3 times, most recently from 107214f to 1a4fc19 Compare July 15, 2025 21:19
JakeChampion and others added 4 commits July 16, 2025 09:39
- Add support for configurable compression levels per host:
  * gzip-compression-level (1-9, default 6)
  * brotli-compression-level (0-11, default 6)
  * brotli-lgwin (10-24, default 16)
  * zstd-compression-level (1-22, default 12)

This enables fine-tuning compression performance vs. speed trade-offs
on a per-host basis
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

5 participants