]> git.kaiwu.me - haproxy.git/commit
OPTIM: flt-http-comp: only flush the compressor after the last DATA block
authorWilly Tarreau <w@1wt.eu>
Sun, 1 Nov 2026 13:39:14 +0000 (14:39 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 3 Nov 2026 08:33:56 +0000 (09:33 +0100)
commitfcee2555fc9c512ecd923cb4b0426dcf4a686727
tree2b579a26cbd06a9934a3615f9fd12f468703f081
parent7fe515c3dd6bfb2e72ae840f2da43048bf48e5df
OPTIM: flt-http-comp: only flush the compressor after the last DATA block

comp_http_payload() used to call the compressor's flush() after each DATA
block, which emits a synchronization point (an EOB and an empty stored
block, up to 5 bytes) and closes the current huffman block each time.
Worse, with slz, and before recent commit a0b37fb470 ("BUG/MEDIUM:
compression: fix incompatibility between compression and large-buffers"),
add_data() only queued the data and flush() is where they were compressed,
so each block was compressed on its own, without being able to reference
the previous ones, since slz keeps no context between calls.

Now flush() is only called when no other DATA block follows in this
pass, so that the client still gets everything while we're waiting for
more data. With zlib, which compresses in add_data(), the last bits are
simply kept for the next block. With slz, all DATA blocks of the pass
are queued (the first one by reference, the following ones copied into
a contiguous buffer, as add_data() already does) and compressed at once
with their whole context. The first block's data are still referenced
after the block is removed or emptied, which is fine since this does not
touch the data area, and they are copied when the second block is added.

The difference is only visible when several DATA blocks are processed
in the same pass, e.g. a 1 MB HTML response made of 256-byte chunks
shrinks from 405057 to 402030 bytes (-0.7%) at level 1.
src/flt_http_comp.c