diff options
| -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 | 88 |
3 files changed, 128 insertions, 0 deletions
diff --git a/src/nxt_http_compression.c b/src/nxt_http_compression.c index f35afeff..2ce415fe 100644 --- a/src/nxt_http_compression.c +++ b/src/nxt_http_compression.c @@ -27,6 +27,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 @@ -89,6 +93,22 @@ static const nxt_http_comp_type_t nxt_http_comp_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_http_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_http_comp_gzip_ops, +#endif }, }; diff --git a/src/nxt_http_compression.h b/src/nxt_http_compression.h index 4e63d34d..abfecd92 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 }; }; @@ -38,6 +52,12 @@ struct nxt_http_comp_operations_s { }; +#if NXT_HAVE_ZLIB +extern const nxt_http_comp_operations_t nxt_http_comp_deflate_ops; +extern const nxt_http_comp_operations_t nxt_http_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..ad1957ea --- /dev/null +++ b/src/nxt_zlib.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) Andrew Clayton + * Copyright (C) F5, Inc. + */ + +#include <stddef.h> +#include <stdint.h> +#include <stdbool.h> + +#include <zlib.h> + +#include "nxt_http_compression.h" + + +static int +nxt_zlib_gzip_init(nxt_http_comp_compressor_ctx_t *ctx) +{ + z_stream *z = &ctx->zlib_ctx; + + *z = (z_stream){}; + + return deflateInit2(z, ctx->level, Z_DEFLATED, 9 + 16, 8, + Z_DEFAULT_STRATEGY); +} + + +static int +nxt_zlib_deflate_init(nxt_http_comp_compressor_ctx_t *ctx) +{ + z_stream *z = &ctx->zlib_ctx; + + *z = (z_stream){}; + + return 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); + return -1; + } + + if (last) { + deflateEnd(z); + } + + return z->total_out - compressed_bytes; +} + + +const nxt_http_comp_operations_t nxt_http_comp_deflate_ops = { + .init = nxt_zlib_deflate_init, + .bound = nxt_zlib_bound, + .deflate = nxt_zlib_deflate, +}; + + +const nxt_http_comp_operations_t nxt_http_comp_gzip_ops = { + .init = nxt_zlib_gzip_init, + .bound = nxt_zlib_bound, + .deflate = nxt_zlib_deflate, +}; |
