Skip to content

Commit 1cc7236

Browse files
committed
[WIP] HTTP Compression Support
1 parent 90542db commit 1cc7236

17 files changed

+1279
-2
lines changed

auto/compression

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
2+
# Copyright (C) Alejandro Colomar
3+
# Copyright (C) Andrew Clayton
4+
# Copyright (C) NGINX, Inc.
5+
6+
7+
NXT_HAVE_ZLIB=no
8+
NXT_ZLIB_CFLAGS=
9+
NXT_ZLIB_LIBS=
10+
11+
NXT_HAVE_ZSTD=no
12+
NXT_ZSTD_CFLAGS=
13+
NXT_ZSTD_LIBS=
14+
15+
NXT_HAVE_BROTLI=no
16+
NXT_BROTLI_CFLAGS=
17+
NXT_BROTLI_LIBS=
18+
19+
20+
if [ $NXT_ZLIB = YES ]; then
21+
NXT_ZLIB_CFLAGS="$(pkgconf --cflags-only-I zlib 2>/dev/null || echo "")"
22+
NXT_ZLIB_LIBS="$(pkgconf --libs zlib 2>/dev/null || echo "-lz")"
23+
24+
nxt_feature="zlib"
25+
nxt_feature_name=NXT_HAVE_ZLIB
26+
nxt_feature_run=no
27+
nxt_feature_incs=$NXT_ZLIB_CFLAGS
28+
nxt_feature_libs=$NXT_ZLIB_LIBS
29+
nxt_feature_test="#include <stdio.h>
30+
31+
#include <zlib.h>
32+
33+
int main(void) {
34+
puts(zlibVersion());
35+
return 0;
36+
}"
37+
. auto/feature
38+
39+
if [ $nxt_found = yes ]; then
40+
NXT_HAVE_ZLIB=YES
41+
echo " + zlib version: $(pkgconf --modversion zlib)"
42+
fi
43+
fi
44+
45+
46+
if [ $NXT_ZSTD = YES ]; then
47+
NXT_ZSTD_CFLAGS="$(pkgconf --cflags-only-I libzstd 2>/dev/null || echo "")"
48+
NXT_ZSTD_LIBS="$(pkgconf --libs libzstd 2>/dev/null || echo "-lzstd")"
49+
50+
nxt_feature="zstd"
51+
nxt_feature_name=NXT_HAVE_ZSTD
52+
nxt_feature_run=no
53+
nxt_feature_incs=$NXT_ZSTD_CFLAGS
54+
nxt_feature_libs=$NXT_ZSTD_LIBS
55+
nxt_feature_test="#include <stdio.h>
56+
57+
#include <zstd.h>
58+
59+
int main(void) {
60+
printf(\"zstd version: %u\n\", ZSTD_versionNumber());
61+
return 0;
62+
}"
63+
. auto/feature
64+
65+
if [ $nxt_found = yes ]; then
66+
NXT_HAVE_ZSTD=YES
67+
echo " + zstd version: $(pkgconf --modversion libzstd)"
68+
fi
69+
fi
70+
71+
72+
if [ $NXT_BROTLI = YES ]; then
73+
NXT_BROTLI_CFLAGS="$(pkgconf --cflags-only-I libbrotlienc 2>/dev/null || echo "")"
74+
NXT_BROTLI_LIBS="$(pkgconf --libs libbrotlienc 2>/dev/null || echo "-lbrotlienc")"
75+
76+
nxt_feature="brotli"
77+
nxt_feature_name=NXT_HAVE_BROTLI
78+
nxt_feature_run=no
79+
nxt_feature_incs=$NXT_BROTLI_CFLAGS
80+
nxt_feature_libs=$NXT_BROTLI_LIBS
81+
nxt_feature_test="#include <stdio.h>
82+
83+
#include <brotli/encode.h>
84+
85+
int main(void) {
86+
printf(\"brotli version: %d\n\",
87+
BrotliEncoderVersion());
88+
return 0;
89+
}"
90+
. auto/feature
91+
92+
if [ $nxt_found = yes ]; then
93+
NXT_HAVE_BROTLI=YES
94+
echo " + brotli version: $(pkgconf --modversion libbrotlienc)"
95+
fi
96+
fi

auto/help

+4
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ cat << END
5050

5151
--openssl enable OpenSSL library usage
5252

53+
--zlib enable zlib compression
54+
--zstd enable zstd compression
55+
--brotli enable brotli compression
56+
5357
--njs enable njs library usage
5458

5559
--debug enable debug logging

auto/options

+8
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ NXT_GNUTLS=NO
2626
NXT_CYASSL=NO
2727
NXT_POLARSSL=NO
2828

29+
NXT_ZLIB=NO
30+
NXT_ZSTD=NO
31+
NXT_BROTLI=NO
32+
2933
NXT_NJS=NO
3034

3135
NXT_TEST_BUILD_EPOLL=NO
@@ -111,6 +115,10 @@ do
111115
--cyassl) NXT_CYASSL=YES ;;
112116
--polarssl) NXT_POLARSSL=YES ;;
113117

118+
--zlib) NXT_ZLIB=YES ;;
119+
--zstd) NXT_ZSTD=YES ;;
120+
--brotli) NXT_BROTLI=YES ;;
121+
114122
--njs) NXT_NJS=YES ;;
115123

116124
--test-build-epoll) NXT_TEST_BUILD_EPOLL=YES ;;

auto/sources

+16
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ NXT_LIB_SRCS=" \
107107
src/nxt_http_websocket.c \
108108
src/nxt_h1proto_websocket.c \
109109
src/nxt_fs.c \
110+
src/nxt_http_compression.c \
110111
"
111112

112113

@@ -211,6 +212,21 @@ if [ $NXT_POLARSSL = YES ]; then
211212
fi
212213

213214

215+
if [ "$NXT_HAVE_ZLIB" = "YES" ]; then
216+
NXT_LIB_SRCS="$NXT_LIB_SRCS src/nxt_zlib.c"
217+
fi
218+
219+
220+
if [ "$NXT_HAVE_ZSTD" = "YES" ]; then
221+
NXT_LIB_SRCS="$NXT_LIB_SRCS src/nxt_zstd.c"
222+
fi
223+
224+
225+
if [ "$NXT_HAVE_BROTLI" = "YES" ]; then
226+
NXT_LIB_SRCS="$NXT_LIB_SRCS src/nxt_brotli.c"
227+
fi
228+
229+
214230
if [ "$NXT_REGEX" = "YES" ]; then
215231
if [ "$NXT_HAVE_PCRE2" = "YES" ]; then
216232
NXT_LIB_SRCS="$NXT_LIB_SRCS $NXT_LIB_PCRE2_SRCS"

auto/summary

+3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ Unit configuration summary:
2828
IPv6 support: .............. $NXT_INET6
2929
Unix domain sockets support: $NXT_UNIX_DOMAIN
3030
TLS support: ............... $NXT_OPENSSL
31+
zlib support: .............. $NXT_ZLIB
32+
zstd support: .............. $NXT_ZSTD
33+
brotli support: ............ $NXT_BROTLI
3134
Regex support: ............. $NXT_REGEX
3235
njs support: ............... $NXT_NJS
3336

configure

+5-2
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ NXT_LIBRT=
127127
. auto/unix
128128
. auto/os/conf
129129
. auto/ssltls
130+
. auto/compression
130131

131132
if [ $NXT_REGEX = YES ]; then
132133
. auto/pcre
@@ -168,11 +169,13 @@ END
168169

169170
NXT_LIB_AUX_CFLAGS="$NXT_OPENSSL_CFLAGS $NXT_GNUTLS_CFLAGS \\
170171
$NXT_CYASSL_CFLAGS $NXT_POLARSSL_CFLAGS \\
171-
$NXT_PCRE_CFLAGS"
172+
$NXT_PCRE_CFLAGS $NXT_ZLIB_CFLAGS $NXT_ZSTD_CFLAGS \\
173+
$NXT_BROTLI_CFLAGS"
172174

173175
NXT_LIB_AUX_LIBS="$NXT_OPENSSL_LIBS $NXT_GNUTLS_LIBS \\
174176
$NXT_CYASSL_LIBS $NXT_POLARSSL_LIBS \\
175-
$NXT_PCRE_LIB"
177+
$NXT_PCRE_LIB $NXT_ZLIB_LIBS $NXT_ZSTD_LIBS \\
178+
$NXT_BROTLI_LIBS"
176179

177180
if [ $NXT_NJS != NO ]; then
178181
. auto/njs

src/nxt_brotli.c

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
*
3+
*/
4+
5+
/* XXX Remove */
6+
#define _GNU_SOURCE
7+
#include <unistd.h>
8+
9+
10+
#include <stddef.h>
11+
#include <stdint.h>
12+
#include <stdbool.h>
13+
14+
#include <brotli/encode.h>
15+
16+
#include <nxt_http_compression.h>
17+
18+
static void nxt_brotli_free(const nxt_http_comp_compressor_ctx_t *ctx)
19+
{
20+
BrotliEncoderState *brotli = ctx->brotli_ctx;
21+
22+
BrotliEncoderDestroyInstance(brotli);
23+
}
24+
25+
static void nxt_brotli_init(nxt_http_comp_compressor_ctx_t *ctx)
26+
{
27+
BrotliEncoderState **brotli = &ctx->brotli_ctx;
28+
29+
*brotli = BrotliEncoderCreateInstance(NULL, NULL, NULL);
30+
BrotliEncoderSetParameter(*brotli, BROTLI_PARAM_QUALITY, ctx->level);
31+
32+
printf("%7d %s: brotli compression level [%d]\n", gettid(), __func__,
33+
ctx->level);
34+
}
35+
36+
static size_t nxt_brotli_bound(const nxt_http_comp_compressor_ctx_t *ctx,
37+
size_t in_len)
38+
{
39+
return BrotliEncoderMaxCompressedSize(in_len);
40+
}
41+
42+
static ssize_t nxt_brotli_compress(nxt_http_comp_compressor_ctx_t *ctx,
43+
const uint8_t *in_buf, size_t in_len,
44+
uint8_t *out_buf, size_t out_len, bool last)
45+
{
46+
bool ok;
47+
size_t out_bytes;
48+
uint8_t *outp;
49+
BrotliEncoderState *brotli = ctx->brotli_ctx;
50+
51+
printf("%7d %s: last/%s\n", gettid(), __func__, last ? "true" : "false");
52+
printf("%7d %s: in_len [%lu] out_len [%lu]\n", gettid(), __func__,
53+
in_len, out_len);
54+
55+
outp = out_buf;
56+
57+
ok = BrotliEncoderCompressStream(brotli, BROTLI_OPERATION_PROCESS,
58+
&in_len, &in_buf, &out_bytes, &outp,
59+
NULL);
60+
61+
ok = BrotliEncoderCompressStream(brotli, BROTLI_OPERATION_FLUSH,
62+
&in_len, &in_buf, &out_bytes, &outp,
63+
NULL);
64+
65+
printf("%7d %s: in_len [%lu] out_len [%lu] out_bytes [%lu]\n", gettid(),
66+
__func__, in_len, out_len, out_bytes);
67+
if (last) {
68+
ok = BrotliEncoderCompressStream(brotli, BROTLI_OPERATION_FINISH,
69+
&in_len, &in_buf, &out_bytes, &outp,
70+
NULL);
71+
nxt_brotli_free(ctx);
72+
}
73+
74+
printf("%7d %s: in_len [%lu] out_len [%lu] out_bytes [%lu]\n", gettid(),
75+
__func__, in_len, out_len, out_bytes);
76+
printf("%7d %s: buf [%p] outp [%p]\n", gettid(), __func__, out_buf, outp);
77+
78+
return out_len - out_bytes;
79+
}
80+
81+
const nxt_http_comp_operations_t nxt_comp_brotli_ops = {
82+
.init = nxt_brotli_init,
83+
.bound = nxt_brotli_bound,
84+
.deflate = nxt_brotli_compress,
85+
.free_ctx = nxt_brotli_free,
86+
};

0 commit comments

Comments
 (0)