fix(gzip): skip decompression for nginx-delegated gzip in log collect#13098
Open
sihyeonn wants to merge 1 commit intoapache:masterfrom
Open
fix(gzip): skip decompression for nginx-delegated gzip in log collect#13098sihyeonn wants to merge 1 commit intoapache:masterfrom
sihyeonn wants to merge 1 commit intoapache:masterfrom
Conversation
When the gzip plugin delegates compression to the nginx gzip module via set_gzip(), the Content-Encoding header is set immediately in header_filter, but the actual compression happens in nginx's output filter chain after body_filter_by_lua completes. This causes log-util's collect_body() to see Content-Encoding: gzip and attempt to decompress a body that is still plaintext, resulting in "INFLATE: data error" warnings. Set ctx.gzip_set flag after successful set_gzip() and check it in collect_body() to skip decompression, storing the raw body directly. This follows the same pattern as ctx.brotli_matched in the brotli plugin. Closes apache#13093 Signed-off-by: Sihyeon Jang <sihyeon.jang@navercorp.com>
There was a problem hiding this comment.
Pull request overview
Updates response-body collection logic used by APISIX logger plugins to account for responses where APISIX gzip is enabled, avoiding unnecessary (and potentially incorrect) content-decoding attempts.
Changes:
- Mark requests where the
gzipplugin successfully enables gzip viactx.gzip_set. - Skip response-body decoding in
log-util.collect_bodywhenctx.gzip_setis present.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| apisix/utils/log-util.lua | Avoids attempting to decode response bodies based on Content-Encoding when APISIX gzip has been enabled for the request. |
| apisix/plugins/gzip.lua | Sets ctx.gzip_set after successfully calling response.set_gzip() so downstream logging can adjust behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
154
to
+165
| local ok, err = response.set_gzip({ | ||
| buffer_num = buffers.number, | ||
| buffer_size = buffers.size, | ||
| compress_level = conf.comp_level, | ||
| }) | ||
| if not ok then | ||
| core.log.error("failed to set gzip: ", err) | ||
| return | ||
| end | ||
|
|
||
| ctx.gzip_set = true | ||
|
|
Comment on lines
376
to
379
| local response_encoding = ngx_header["Content-Encoding"] | ||
| if not response_encoding then | ||
| if not response_encoding or ctx.gzip_set then | ||
| ctx.resp_body = final_body | ||
| return |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Closes #13093
When the gzip plugin delegates compression to the nginx gzip module via
response.set_gzip(), theContent-Encoding: gzipheader is set immediately duringheader_filter, but the actual compression happens in nginx's output filter chain afterbody_filter_by_luacompletes.This causes
log-util.collect_body()to seeContent-Encoding: gzipand attempt to decompress a body that is still plaintext, resulting in repeatedINFLATE: data errorwarnings in the error log.Root cause
The execution order is:
Content-Encoding: gzipcollect_body(), sees gzip header, tries to inflate plaintext → errorFix
Set
ctx.gzip_set = truein the gzip plugin after successfulset_gzip(), and check this flag incollect_body()to skip decompression. The raw (uncompressed) body is stored directly for logging.This follows the same pattern as
ctx.brotli_matchedused by the brotli plugin.