diff options
| author | Andrew Clayton <a.clayton@nginx.com> | 2024-11-20 16:13:46 +0000 |
|---|---|---|
| committer | Andrew Clayton <a.clayton@nginx.com> | 2024-11-29 00:45:24 +0000 |
| commit | 9e836e683f1125955e6d69afd90e8fac328f1b4b (patch) | |
| tree | ad54b2a09d66ae9e6472b89703c2c8293d943571 /src | |
| parent | fd7d4c695777d3e34a4af9741600b591f8bbef79 (diff) | |
| download | unit-9e836e683f1125955e6d69afd90e8fac328f1b4b.tar.gz unit-9e836e683f1125955e6d69afd90e8fac328f1b4b.tar.bz2 | |
http: Add zlib compression support
This adds support for both deflate & gzip compressors.
Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/nxt_http_compression.c | 20 | ||||
| -rw-r--r-- | src/nxt_http_compression.h | 20 | ||||
| -rw-r--r-- | src/nxt_zlib.c | 89 |
3 files changed, 129 insertions, 0 deletions
diff --git a/src/nxt_http_compression.c b/src/nxt_http_compression.c index d2ee1332..0c2931a9 100644 --- a/src/nxt_http_compression.c +++ b/src/nxt_http_compression.c @@ -26,6 +26,10 @@ typedef struct nxt_http_comp_ctx_s nxt_http_comp_ctx_t; enum nxt_http_comp_scheme_e { NXT_HTTP_COMP_SCHEME_IDENTITY = 0, +#if NXT_HAVE_ZLIB + NXT_HTTP_COMP_SCHEME_DEFLATE, + NXT_HTTP_COMP_SCHEME_GZIP, +#endif /* keep last */ NXT_HTTP_COMP_SCHEME_UNKNOWN @@ -85,6 +89,22 @@ static const nxt_http_comp_type_t compressors[] = { { .token = nxt_string("identity"), .scheme = NXT_HTTP_COMP_SCHEME_IDENTITY, +#if NXT_HAVE_ZLIB + }, { + .token = nxt_string("deflate"), + .scheme = NXT_HTTP_COMP_SCHEME_DEFLATE, + .def_compr = NXT_HTTP_COMP_ZLIB_DEFAULT_LEVEL, + .comp_min = NXT_HTTP_COMP_ZLIB_COMP_MIN, + .comp_max = NXT_HTTP_COMP_ZLIB_COMP_MAX, + .cops = &nxt_comp_deflate_ops, + }, { + .token = nxt_string("gzip"), + .scheme = NXT_HTTP_COMP_SCHEME_GZIP, + .def_compr = NXT_HTTP_COMP_ZLIB_DEFAULT_LEVEL, + .comp_min = NXT_HTTP_COMP_ZLIB_COMP_MIN, + .comp_max = NXT_HTTP_COMP_ZLIB_COMP_MAX, + .cops = &nxt_comp_gzip_ops, +#endif }, }; diff --git a/src/nxt_http_compression.h b/src/nxt_http_compression.h index 3d84cb1d..c67cd001 100644 --- a/src/nxt_http_compression.h +++ b/src/nxt_http_compression.h @@ -12,12 +12,23 @@ #include <stdint.h> #include <stdbool.h> +#if NXT_HAVE_ZLIB +#include <zlib.h> +#endif + #include <nxt_main.h> #include <nxt_router.h> #include <nxt_string.h> #include <nxt_conf.h> +#if NXT_HAVE_ZLIB +#define NXT_HTTP_COMP_ZLIB_DEFAULT_LEVEL Z_DEFAULT_COMPRESSION +#define NXT_HTTP_COMP_ZLIB_COMP_MIN Z_DEFAULT_COMPRESSION +#define NXT_HTTP_COMP_ZLIB_COMP_MAX Z_BEST_COMPRESSION +#endif + + typedef struct nxt_http_comp_compressor_ctx_s nxt_http_comp_compressor_ctx_t; typedef struct nxt_http_comp_operations_s nxt_http_comp_operations_t; @@ -25,6 +36,9 @@ struct nxt_http_comp_compressor_ctx_s { int8_t level; union { +#if NXT_HAVE_ZLIB + z_stream zlib_ctx; +#endif }; }; @@ -39,6 +53,12 @@ struct nxt_http_comp_operations_s { }; +#if NXT_HAVE_ZLIB +extern const nxt_http_comp_operations_t nxt_comp_deflate_ops; +extern const nxt_http_comp_operations_t nxt_comp_gzip_ops; +#endif + + extern bool nxt_http_comp_wants_compression(void); extern bool nxt_http_comp_compressor_is_valid(const nxt_str_t *token); extern nxt_int_t nxt_http_comp_check_compression(nxt_task_t *task, diff --git a/src/nxt_zlib.c b/src/nxt_zlib.c new file mode 100644 index 00000000..191d32ec --- /dev/null +++ b/src/nxt_zlib.c @@ -0,0 +1,89 @@ +/* + * + */ + +#include <stddef.h> +#include <stdint.h> +#include <stdbool.h> + +#include <zlib.h> + +#include "nxt_http_compression.h" + + +static void +nxt_zlib_gzip_init(nxt_http_comp_compressor_ctx_t *ctx) +{ + int ret; + z_stream *z = &ctx->zlib_ctx; + + *z = (z_stream){}; + + ret = deflateInit2(z, ctx->level, Z_DEFLATED, 9 + 16, 8, + Z_DEFAULT_STRATEGY); +} + + +static void +nxt_zlib_deflate_init(nxt_http_comp_compressor_ctx_t *ctx) +{ + int ret; + z_stream *z = &ctx->zlib_ctx; + + *z = (z_stream){}; + + ret = deflateInit2(z, ctx->level, Z_DEFLATED, 9, 8, Z_DEFAULT_STRATEGY); +} + + +static size_t +nxt_zlib_bound(const nxt_http_comp_compressor_ctx_t *ctx, size_t in_len) +{ + z_stream *z = (z_stream *)&ctx->zlib_ctx; + + return deflateBound(z, in_len); +} + + +static ssize_t +nxt_zlib_deflate(nxt_http_comp_compressor_ctx_t *ctx, const uint8_t *in_buf, + size_t in_len, uint8_t *out_buf, size_t out_len, bool last) +{ + int ret; + size_t compressed_bytes; + z_stream *z = &ctx->zlib_ctx; + + z->avail_in = in_len; + z->next_in = (z_const Bytef *)in_buf; + + z->avail_out = out_len; + z->next_out = out_buf; + + compressed_bytes = z->total_out; + + ret = deflate(z, last ? Z_FINISH : Z_SYNC_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_BUF_ERROR) { + deflateEnd(z); + printf("%s: ret = %d\n", __func__, ret); + return -1; + } + + if (last) + deflateEnd(z); + + return z->total_out - compressed_bytes; +} + + +const nxt_http_comp_operations_t nxt_comp_deflate_ops = { + .init = nxt_zlib_deflate_init, + .bound = nxt_zlib_bound, + .deflate = nxt_zlib_deflate, +}; + + +const nxt_http_comp_operations_t nxt_comp_gzip_ops = { + .init = nxt_zlib_gzip_init, + .bound = nxt_zlib_bound, + .deflate = nxt_zlib_deflate, +}; |
