Skip to content

Commit 804ca81

Browse files
committed
http: Add support for brotli compression
Signed-off-by: Andrew Clayton <[email protected]>
1 parent 511b217 commit 804ca81

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed

src/nxt_brotli.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright (C) Andrew Clayton
3+
* Copyright (C) F5, Inc.
4+
*/
5+
6+
#include <stddef.h>
7+
#include <stdint.h>
8+
#include <stdbool.h>
9+
10+
#include <brotli/encode.h>
11+
12+
#include "nxt_http_compression.h"
13+
14+
15+
static int
16+
nxt_brotli_init(nxt_http_comp_compressor_ctx_t *ctx)
17+
{
18+
BrotliEncoderState **brotli = &ctx->brotli_ctx;
19+
20+
*brotli = BrotliEncoderCreateInstance(NULL, NULL, NULL);
21+
if (*brotli == NULL) {
22+
return -1;
23+
}
24+
BrotliEncoderSetParameter(*brotli, BROTLI_PARAM_QUALITY, ctx->level);
25+
26+
return 0;
27+
}
28+
29+
30+
static size_t
31+
nxt_brotli_bound(const nxt_http_comp_compressor_ctx_t *ctx, size_t in_len)
32+
{
33+
return BrotliEncoderMaxCompressedSize(in_len);
34+
}
35+
36+
37+
static ssize_t
38+
nxt_brotli_compress(nxt_http_comp_compressor_ctx_t *ctx, const uint8_t *in_buf,
39+
size_t in_len, uint8_t *out_buf, size_t out_len, bool last)
40+
{
41+
bool ok;
42+
size_t out_bytes = out_len;
43+
BrotliEncoderState *brotli = ctx->brotli_ctx;
44+
45+
ok = BrotliEncoderCompressStream(brotli, BROTLI_OPERATION_PROCESS,
46+
&in_len, &in_buf, &out_bytes, &out_buf,
47+
NULL);
48+
if (!ok) {
49+
return -1;
50+
}
51+
52+
ok = BrotliEncoderCompressStream(brotli, BROTLI_OPERATION_FLUSH,
53+
&in_len, &in_buf, &out_bytes, &out_buf,
54+
NULL);
55+
if (!ok) {
56+
return -1;
57+
}
58+
59+
if (last) {
60+
ok = BrotliEncoderCompressStream(brotli, BROTLI_OPERATION_FINISH,
61+
&in_len, &in_buf, &out_bytes,
62+
&out_buf, NULL);
63+
if (!ok) {
64+
return -1;
65+
}
66+
67+
BrotliEncoderDestroyInstance(brotli);
68+
}
69+
70+
return out_len - out_bytes;
71+
}
72+
73+
74+
const nxt_http_comp_operations_t nxt_http_comp_brotli_ops = {
75+
.init = nxt_brotli_init,
76+
.bound = nxt_brotli_bound,
77+
.deflate = nxt_brotli_compress,
78+
};

src/nxt_http_compression.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ enum nxt_http_comp_scheme_e {
3434
#if NXT_HAVE_ZSTD
3535
NXT_HTTP_COMP_SCHEME_ZSTD,
3636
#endif
37+
#if NXT_HAVE_BROTLI
38+
NXT_HTTP_COMP_SCHEME_BROTLI,
39+
#endif
3740

3841
/* keep last */
3942
NXT_HTTP_COMP_SCHEME_UNKNOWN
@@ -120,6 +123,15 @@ static const nxt_http_comp_type_t nxt_http_comp_compressors[] = {
120123
.comp_min = NXT_HTTP_COMP_ZSTD_COMP_MIN,
121124
.comp_max = NXT_HTTP_COMP_ZSTD_COMP_MAX,
122125
.cops = &nxt_http_comp_zstd_ops,
126+
#endif
127+
#if NXT_HAVE_BROTLI
128+
}, {
129+
.token = nxt_string("br"),
130+
.scheme = NXT_HTTP_COMP_SCHEME_BROTLI,
131+
.def_compr = NXT_HTTP_COMP_BROTLI_DEFAULT_LEVEL,
132+
.comp_min = NXT_HTTP_COMP_BROTLI_COMP_MIN,
133+
.comp_max = NXT_HTTP_COMP_BROTLI_COMP_MAX,
134+
.cops = &nxt_http_comp_brotli_ops,
123135
#endif
124136
},
125137
};

src/nxt_http_compression.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
#include <zstd.h>
2121
#endif
2222

23+
#if NXT_HAVE_BROTLI
24+
#include <brotli/encode.h>
25+
#endif
26+
2327
#include <nxt_main.h>
2428
#include <nxt_router.h>
2529
#include <nxt_string.h>
@@ -36,6 +40,11 @@
3640
#define NXT_HTTP_COMP_ZSTD_COMP_MIN (-7)
3741
#define NXT_HTTP_COMP_ZSTD_COMP_MAX 22
3842
#endif
43+
#if NXT_HAVE_BROTLI
44+
#define NXT_HTTP_COMP_BROTLI_DEFAULT_LEVEL BROTLI_DEFAULT_QUALITY
45+
#define NXT_HTTP_COMP_BROTLI_COMP_MIN BROTLI_MIN_QUALITY
46+
#define NXT_HTTP_COMP_BROTLI_COMP_MAX BROTLI_MAX_QUALITY
47+
#endif
3948

4049

4150
typedef struct nxt_http_comp_compressor_ctx_s nxt_http_comp_compressor_ctx_t;
@@ -50,6 +59,9 @@ struct nxt_http_comp_compressor_ctx_s {
5059
#endif
5160
#if NXT_HAVE_ZSTD
5261
ZSTD_CStream *zstd_ctx;
62+
#endif
63+
#if NXT_HAVE_BROTLI
64+
BrotliEncoderState *brotli_ctx;
5365
#endif
5466
};
5567
};
@@ -73,6 +85,10 @@ extern const nxt_http_comp_operations_t nxt_http_comp_gzip_ops;
7385
extern const nxt_http_comp_operations_t nxt_http_comp_zstd_ops;
7486
#endif
7587

88+
#if NXT_HAVE_BROTLI
89+
extern const nxt_http_comp_operations_t nxt_http_comp_brotli_ops;
90+
#endif
91+
7692

7793
extern bool nxt_http_comp_wants_compression(void);
7894
extern bool nxt_http_comp_compressor_is_valid(const nxt_str_t *token);

0 commit comments

Comments
 (0)