Skip to content

Commit f706ecb

Browse files
committed
Use configured compression levels for gzip and brotli
Previously, gzip and brotli compression used hardcoded levels even when custom levels were configured via `HostConfiguration` Split initialization into `data_alloc()` and `transform_init()` so that gzip uses `hc->zlib_compression_level()`, and brotli uses `hc->brotli_compression_level()` and `hc->brotli_lgw_size()` Also adds proper error handling if encoder initialization fails
1 parent bb4b904 commit f706ecb

File tree

5 files changed

+83
-20
lines changed

5 files changed

+83
-20
lines changed

plugins/compress/brotli_compress.cc

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@
3232

3333
namespace Brotli
3434
{
35-
const int BROTLI_COMPRESSION_LEVEL = 6;
36-
const int BROTLI_LGW = 16;
37-
3835
static bool
3936
compress_operation(Data *data, const char *upstream_buffer, int64_t upstream_length, BrotliEncoderOperation op)
4037
{
@@ -77,13 +74,7 @@ compress_operation(Data *data, const char *upstream_buffer, int64_t upstream_len
7774
void
7875
data_alloc(Data *data)
7976
{
80-
debug("brotli compression. Create Brotli Encoder Instance.");
81-
data->bstrm.br = BrotliEncoderCreateInstance(nullptr, nullptr, nullptr);
82-
if (!data->bstrm.br) {
83-
fatal("Brotli Encoder Instance Failed");
84-
}
85-
BrotliEncoderSetParameter(data->bstrm.br, BROTLI_PARAM_QUALITY, BROTLI_COMPRESSION_LEVEL);
86-
BrotliEncoderSetParameter(data->bstrm.br, BROTLI_PARAM_LGWIN, BROTLI_LGW);
77+
data->bstrm.br = nullptr;
8778
data->bstrm.next_in = nullptr;
8879
data->bstrm.avail_in = 0;
8980
data->bstrm.total_in = 0;
@@ -92,10 +83,44 @@ data_alloc(Data *data)
9283
data->bstrm.total_out = 0;
9384
}
9485

86+
bool
87+
transform_init(Data *data)
88+
{
89+
debug("brotli compression: creating Brotli Encoder Instance");
90+
data->bstrm.br = BrotliEncoderCreateInstance(nullptr, nullptr, nullptr);
91+
if (!data->bstrm.br) {
92+
error("brotli-transform: failed to create Brotli Encoder Instance");
93+
return false;
94+
}
95+
96+
int compression_level = data->hc->brotli_compression_level();
97+
int lgwin = data->hc->brotli_lgw_size();
98+
99+
if (!BrotliEncoderSetParameter(data->bstrm.br, BROTLI_PARAM_QUALITY, compression_level)) {
100+
error("brotli-transform: failed to set compression level %d", compression_level);
101+
BrotliEncoderDestroyInstance(data->bstrm.br);
102+
data->bstrm.br = nullptr;
103+
return false;
104+
}
105+
106+
if (!BrotliEncoderSetParameter(data->bstrm.br, BROTLI_PARAM_LGWIN, lgwin)) {
107+
error("brotli-transform: failed to set window size %d", lgwin);
108+
BrotliEncoderDestroyInstance(data->bstrm.br);
109+
data->bstrm.br = nullptr;
110+
return false;
111+
}
112+
113+
debug("brotli compression context initialized with level %d, lgwin %d", compression_level, lgwin);
114+
return true;
115+
}
116+
95117
void
96118
data_destroy(Data *data)
97119
{
98-
BrotliEncoderDestroyInstance(data->bstrm.br);
120+
if (data->bstrm.br) {
121+
BrotliEncoderDestroyInstance(data->bstrm.br);
122+
data->bstrm.br = nullptr;
123+
}
99124
}
100125

101126
void

plugins/compress/brotli_compress.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ void data_alloc(Data *data);
3535
// Destroy brotli compression context
3636
void data_destroy(Data *data);
3737

38+
// Configure the context with compression level. Returns true when ready.
39+
bool transform_init(Data *data);
40+
3841
// Compress one chunk of data
3942
void transform_one(Data *data, const char *upstream_buffer, int64_t upstream_length);
4043

plugins/compress/compress.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,10 +337,31 @@ compress_transform_init(TSCont contp, Data *data)
337337
data->downstream_vio = TSVConnWrite(downstream_conn, contp, data->downstream_reader, INT64_MAX);
338338
}
339339

340+
// Initialize algorithm-specific compression encoders with configured levels
341+
if ((data->compression_type & (COMPRESSION_TYPE_GZIP | COMPRESSION_TYPE_DEFLATE)) &&
342+
(data->compression_algorithms & (ALGORITHM_GZIP | ALGORITHM_DEFLATE))) {
343+
if (!Gzip::transform_init(data)) {
344+
error("Failed to configure gzip/deflate compression context");
345+
TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
346+
return;
347+
}
348+
}
349+
350+
#if HAVE_BROTLI_ENCODE_H
351+
if (data->compression_type & COMPRESSION_TYPE_BROTLI && (data->compression_algorithms & ALGORITHM_BROTLI)) {
352+
if (!Brotli::transform_init(data)) {
353+
error("Failed to configure brotli compression context");
354+
TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
355+
return;
356+
}
357+
}
358+
#endif
359+
340360
#if HAVE_ZSTD_H
341361
if (data->compression_type & COMPRESSION_TYPE_ZSTD && (data->compression_algorithms & ALGORITHM_ZSTD)) {
342362
if (!Zstd::transform_init(data)) {
343363
error("Failed to configure Zstandard compression context");
364+
TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
344365
return;
345366
}
346367
}

plugins/compress/gzip_compress.cc

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ extern const char *dictionary;
3535

3636
namespace Gzip
3737
{
38-
const int ZLIB_COMPRESSION_LEVEL = 6;
3938
voidpf
4039
gzip_alloc(voidpf /* opaque ATS_UNUSED */, uInt items, uInt size)
4140
{
@@ -51,11 +50,6 @@ gzip_free(voidpf /* opaque ATS_UNUSED */, voidpf address)
5150
void
5251
data_alloc(Data *data)
5352
{
54-
int window_bits = WINDOW_BITS_GZIP;
55-
if (data->compression_type & COMPRESSION_TYPE_DEFLATE) {
56-
window_bits = WINDOW_BITS_DEFLATE;
57-
}
58-
5953
data->zstrm.next_in = Z_NULL;
6054
data->zstrm.avail_in = 0;
6155
data->zstrm.total_in = 0;
@@ -66,19 +60,36 @@ data_alloc(Data *data)
6660
data->zstrm.zfree = Gzip::gzip_free;
6761
data->zstrm.opaque = (voidpf) nullptr;
6862
data->zstrm.data_type = Z_ASCII;
63+
}
64+
65+
bool
66+
transform_init(Data *data)
67+
{
68+
int window_bits = WINDOW_BITS_GZIP;
69+
if (data->compression_type & COMPRESSION_TYPE_DEFLATE) {
70+
window_bits = WINDOW_BITS_DEFLATE;
71+
}
72+
73+
int compression_level = data->hc->zlib_compression_level();
74+
debug("gzip compression context initialized with level %d", compression_level);
6975

70-
int err = deflateInit2(&data->zstrm, ZLIB_COMPRESSION_LEVEL, Z_DEFLATED, window_bits, ZLIB_MEMLEVEL, Z_DEFAULT_STRATEGY);
76+
int err = deflateInit2(&data->zstrm, compression_level, Z_DEFLATED, window_bits, ZLIB_MEMLEVEL, Z_DEFAULT_STRATEGY);
7177

7278
if (err != Z_OK) {
73-
fatal("gzip-transform: ERROR: deflateInit (%d)!", err);
79+
error("gzip-transform: deflateInit2 failed (%d)", err);
80+
return false;
7481
}
7582

7683
if (Compress::dictionary) {
7784
err = deflateSetDictionary(&data->zstrm, reinterpret_cast<const Bytef *>(Compress::dictionary), strlen(Compress::dictionary));
7885
if (err != Z_OK) {
79-
fatal("gzip-transform: ERROR: deflateSetDictionary (%d)!", err);
86+
error("gzip-transform: deflateSetDictionary failed (%d)", err);
87+
deflateEnd(&data->zstrm);
88+
return false;
8089
}
8190
}
91+
92+
return true;
8293
}
8394

8495
void

plugins/compress/gzip_compress.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ void data_alloc(Data *data);
3939
// Destroy gzip/deflate compression context
4040
void data_destroy(Data *data);
4141

42+
// Configure the context with compression level. Returns true when ready.
43+
bool transform_init(Data *data);
44+
4245
// Compress one chunk of data
4346
void transform_one(Data *data, const char *upstream_buffer, int64_t upstream_length);
4447

0 commit comments

Comments
 (0)