Skip to content

Commit 85a0091

Browse files
committed
http: Wire up HTTP compression support to the config system
This exposes a new "settings.http.compression" configuration object. Under which are types & compressors objects. types is used to specify what MIME types should be considered compressible. compressors is used to configure an array of compressors that are available. For each of these, you specify the encoding, e.g gzip and optional level and min_length parameters. Where level is what compression level to use and min_length is the minimum length of data that should be compressed. By default the default compression level for the specified compressor is used and there is no minimum data length considered for compression. It may look something like "settings": { "http": { "server_version": true, "static": { "mime_types": { "text/x-c": [ ".c", ".h" ] } }, "compression": { "types": [ "text/*" ], "compressors": [ { "encoding": "gzip", "level": 3, "min_length": 2048 }, { "encoding": "deflate", "min_length": 1024 }, { "encoding": "zstd", "min_length": 2048 }, { "encoding": "br", "min_length": 256 } ] } } }, Currently this is a global option that will effect both static and application responses. In future it should be possible to add per-application (and perhaps even per-static) configuration. Signed-off-by: Andrew Clayton <[email protected]>
1 parent c9b2ecd commit 85a0091

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed

src/nxt_conf_validation.c

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <nxt_http.h>
1414
#include <nxt_sockaddr.h>
1515
#include <nxt_http_route_addr.h>
16+
#include <nxt_http_compression.h>
1617
#include <nxt_regex.h>
1718

1819

@@ -140,6 +141,12 @@ static nxt_int_t nxt_conf_vldt_threads(nxt_conf_validation_t *vldt,
140141
nxt_conf_value_t *value, void *data);
141142
static nxt_int_t nxt_conf_vldt_thread_stack_size(nxt_conf_validation_t *vldt,
142143
nxt_conf_value_t *value, void *data);
144+
static nxt_int_t nxt_conf_vldt_compressors(nxt_conf_validation_t *vldt,
145+
nxt_conf_value_t *value, void *data);
146+
static nxt_int_t nxt_conf_vldt_compression(nxt_conf_validation_t *vldt,
147+
nxt_conf_value_t *value);
148+
static nxt_int_t nxt_conf_vldt_compression_encoding(nxt_conf_validation_t *vldt,
149+
nxt_conf_value_t *value, void *data);
143150
static nxt_int_t nxt_conf_vldt_routes(nxt_conf_validation_t *vldt,
144151
nxt_conf_value_t *value, void *data);
145152
static nxt_int_t nxt_conf_vldt_routes_member(nxt_conf_validation_t *vldt,
@@ -263,6 +270,8 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_otel_members[];
263270
#endif
264271
static nxt_conf_vldt_object_t nxt_conf_vldt_websocket_members[];
265272
static nxt_conf_vldt_object_t nxt_conf_vldt_static_members[];
273+
static nxt_conf_vldt_object_t nxt_conf_vldt_compression_members[];
274+
static nxt_conf_vldt_object_t nxt_conf_vldt_compressor_members[];
266275
static nxt_conf_vldt_object_t nxt_conf_vldt_forwarded_members[];
267276
static nxt_conf_vldt_object_t nxt_conf_vldt_client_ip_members[];
268277
#if (NXT_TLS)
@@ -403,6 +412,11 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_http_members[] = {
403412
}, {
404413
.name = nxt_string("chunked_transform"),
405414
.type = NXT_CONF_VLDT_BOOLEAN,
415+
}, {
416+
.name = nxt_string("compression"),
417+
.type = NXT_CONF_VLDT_OBJECT,
418+
.validator = nxt_conf_vldt_object,
419+
.u.members = nxt_conf_vldt_compression_members,
406420
},
407421

408422
NXT_CONF_VLDT_END
@@ -465,6 +479,39 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_static_members[] = {
465479
};
466480

467481

482+
static nxt_conf_vldt_object_t nxt_conf_vldt_compression_members[] = {
483+
{
484+
.name = nxt_string("types"),
485+
.type = NXT_CONF_VLDT_STRING | NXT_CONF_VLDT_ARRAY,
486+
.validator = nxt_conf_vldt_match_patterns,
487+
}, {
488+
.name = nxt_string("compressors"),
489+
.type = NXT_CONF_VLDT_OBJECT | NXT_CONF_VLDT_ARRAY,
490+
.validator = nxt_conf_vldt_compressors,
491+
},
492+
493+
NXT_CONF_VLDT_END
494+
};
495+
496+
497+
static nxt_conf_vldt_object_t nxt_conf_vldt_compressor_members[] = {
498+
{
499+
.name = nxt_string("encoding"),
500+
.type = NXT_CONF_VLDT_STRING,
501+
.flags = NXT_CONF_VLDT_REQUIRED,
502+
.validator = nxt_conf_vldt_compression_encoding,
503+
}, {
504+
.name = nxt_string("level"),
505+
.type = NXT_CONF_VLDT_INTEGER,
506+
}, {
507+
.name = nxt_string("min_length"),
508+
.type = NXT_CONF_VLDT_INTEGER,
509+
},
510+
511+
NXT_CONF_VLDT_END
512+
};
513+
514+
468515
static nxt_conf_vldt_object_t nxt_conf_vldt_listener_members[] = {
469516
{
470517
.name = nxt_string("pass"),
@@ -2270,6 +2317,52 @@ nxt_conf_vldt_thread_stack_size(nxt_conf_validation_t *vldt,
22702317
}
22712318

22722319

2320+
static nxt_int_t
2321+
nxt_conf_vldt_compressors(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
2322+
void *data)
2323+
{
2324+
if (nxt_conf_type(value) == NXT_CONF_ARRAY) {
2325+
return nxt_conf_vldt_array_iterator(vldt, value,
2326+
&nxt_conf_vldt_compression);
2327+
}
2328+
2329+
/* NXT_CONF_OBJECT */
2330+
2331+
return nxt_conf_vldt_object_iterator(vldt, value,
2332+
&nxt_conf_vldt_compressor_members);
2333+
}
2334+
2335+
2336+
static nxt_int_t
2337+
nxt_conf_vldt_compression(nxt_conf_validation_t *vldt, nxt_conf_value_t *value)
2338+
{
2339+
if (nxt_conf_type(value) != NXT_CONF_OBJECT) {
2340+
return nxt_conf_vldt_error(vldt,
2341+
"The \"compressors\" array must contain "
2342+
"only object values.");
2343+
}
2344+
2345+
return nxt_conf_vldt_object(vldt, value, nxt_conf_vldt_compressor_members);
2346+
}
2347+
2348+
2349+
static nxt_int_t
2350+
nxt_conf_vldt_compression_encoding(nxt_conf_validation_t *vldt,
2351+
nxt_conf_value_t *value, void *data)
2352+
{
2353+
nxt_str_t token;
2354+
2355+
nxt_conf_get_string(value, &token);
2356+
2357+
if (nxt_http_comp_compressor_is_valid(&token)) {
2358+
return NXT_OK;
2359+
}
2360+
2361+
return nxt_conf_vldt_error(vldt, "\"%V\" is not a supported compressor.",
2362+
&token);
2363+
}
2364+
2365+
22732366
static nxt_int_t
22742367
nxt_conf_vldt_routes(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
22752368
void *data)

src/nxt_router.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <nxt_router_request.h>
2222
#include <nxt_app_queue.h>
2323
#include <nxt_port_queue.h>
24+
#include <nxt_http_compression.h>
2425

2526
#define NXT_SHARED_PORT_ID 0xFFFFu
2627

@@ -1680,6 +1681,8 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
16801681
static const nxt_str_t static_path = nxt_string("/settings/http/static");
16811682
static const nxt_str_t websocket_path =
16821683
nxt_string("/settings/http/websocket");
1684+
static const nxt_str_t compression_path =
1685+
nxt_string("/settings/http/compression");
16831686
static const nxt_str_t forwarded_path = nxt_string("/forwarded");
16841687
static const nxt_str_t client_ip_path = nxt_string("/client_ip");
16851688
#if (NXT_HAVE_OTEL)
@@ -2044,13 +2047,20 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
20442047
nxt_str_null(&skcf->body_temp_path);
20452048

20462049
if (http != NULL) {
2050+
nxt_conf_value_t *comp;
2051+
20472052
ret = nxt_conf_map_object(mp, http, nxt_router_http_conf,
20482053
nxt_nitems(nxt_router_http_conf),
20492054
skcf);
20502055
if (ret != NXT_OK) {
20512056
nxt_alert(task, "http map error");
20522057
goto fail;
20532058
}
2059+
2060+
comp = nxt_conf_get_path(root, &compression_path);
2061+
if (comp != NULL) {
2062+
nxt_http_comp_compression_init(task, rtcf, comp);
2063+
}
20542064
}
20552065

20562066
if (websocket != NULL) {

0 commit comments

Comments
 (0)