summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrew Clayton <a.clayton@nginx.com>2024-11-20 17:02:22 +0000
committerAndrew Clayton <a.clayton@nginx.com>2025-04-14 18:11:53 +0100
commit85a00914df5d603649b5177a2bca07f0314d6488 (patch)
treea373d3eed7c4307af38341431dc6c025e2d76e2a
parentc9b2ecd28407538d3ef0b48bba944440695196ed (diff)
downloadunit-85a00914df5d603649b5177a2bca07f0314d6488.tar.gz
unit-85a00914df5d603649b5177a2bca07f0314d6488.tar.bz2
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 <a.clayton@nginx.com>
-rw-r--r--src/nxt_conf_validation.c93
-rw-r--r--src/nxt_router.c10
2 files changed, 103 insertions, 0 deletions
diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c
index a0b4992f..8324a441 100644
--- a/src/nxt_conf_validation.c
+++ b/src/nxt_conf_validation.c
@@ -13,6 +13,7 @@
#include <nxt_http.h>
#include <nxt_sockaddr.h>
#include <nxt_http_route_addr.h>
+#include <nxt_http_compression.h>
#include <nxt_regex.h>
@@ -140,6 +141,12 @@ static nxt_int_t nxt_conf_vldt_threads(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data);
static nxt_int_t nxt_conf_vldt_thread_stack_size(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data);
+static nxt_int_t nxt_conf_vldt_compressors(nxt_conf_validation_t *vldt,
+ nxt_conf_value_t *value, void *data);
+static nxt_int_t nxt_conf_vldt_compression(nxt_conf_validation_t *vldt,
+ nxt_conf_value_t *value);
+static nxt_int_t nxt_conf_vldt_compression_encoding(nxt_conf_validation_t *vldt,
+ nxt_conf_value_t *value, void *data);
static nxt_int_t nxt_conf_vldt_routes(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data);
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[];
#endif
static nxt_conf_vldt_object_t nxt_conf_vldt_websocket_members[];
static nxt_conf_vldt_object_t nxt_conf_vldt_static_members[];
+static nxt_conf_vldt_object_t nxt_conf_vldt_compression_members[];
+static nxt_conf_vldt_object_t nxt_conf_vldt_compressor_members[];
static nxt_conf_vldt_object_t nxt_conf_vldt_forwarded_members[];
static nxt_conf_vldt_object_t nxt_conf_vldt_client_ip_members[];
#if (NXT_TLS)
@@ -403,6 +412,11 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_http_members[] = {
}, {
.name = nxt_string("chunked_transform"),
.type = NXT_CONF_VLDT_BOOLEAN,
+ }, {
+ .name = nxt_string("compression"),
+ .type = NXT_CONF_VLDT_OBJECT,
+ .validator = nxt_conf_vldt_object,
+ .u.members = nxt_conf_vldt_compression_members,
},
NXT_CONF_VLDT_END
@@ -465,6 +479,39 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_static_members[] = {
};
+static nxt_conf_vldt_object_t nxt_conf_vldt_compression_members[] = {
+ {
+ .name = nxt_string("types"),
+ .type = NXT_CONF_VLDT_STRING | NXT_CONF_VLDT_ARRAY,
+ .validator = nxt_conf_vldt_match_patterns,
+ }, {
+ .name = nxt_string("compressors"),
+ .type = NXT_CONF_VLDT_OBJECT | NXT_CONF_VLDT_ARRAY,
+ .validator = nxt_conf_vldt_compressors,
+ },
+
+ NXT_CONF_VLDT_END
+};
+
+
+static nxt_conf_vldt_object_t nxt_conf_vldt_compressor_members[] = {
+ {
+ .name = nxt_string("encoding"),
+ .type = NXT_CONF_VLDT_STRING,
+ .flags = NXT_CONF_VLDT_REQUIRED,
+ .validator = nxt_conf_vldt_compression_encoding,
+ }, {
+ .name = nxt_string("level"),
+ .type = NXT_CONF_VLDT_INTEGER,
+ }, {
+ .name = nxt_string("min_length"),
+ .type = NXT_CONF_VLDT_INTEGER,
+ },
+
+ NXT_CONF_VLDT_END
+};
+
+
static nxt_conf_vldt_object_t nxt_conf_vldt_listener_members[] = {
{
.name = nxt_string("pass"),
@@ -2271,6 +2318,52 @@ nxt_conf_vldt_thread_stack_size(nxt_conf_validation_t *vldt,
static nxt_int_t
+nxt_conf_vldt_compressors(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
+ void *data)
+{
+ if (nxt_conf_type(value) == NXT_CONF_ARRAY) {
+ return nxt_conf_vldt_array_iterator(vldt, value,
+ &nxt_conf_vldt_compression);
+ }
+
+ /* NXT_CONF_OBJECT */
+
+ return nxt_conf_vldt_object_iterator(vldt, value,
+ &nxt_conf_vldt_compressor_members);
+}
+
+
+static nxt_int_t
+nxt_conf_vldt_compression(nxt_conf_validation_t *vldt, nxt_conf_value_t *value)
+{
+ if (nxt_conf_type(value) != NXT_CONF_OBJECT) {
+ return nxt_conf_vldt_error(vldt,
+ "The \"compressors\" array must contain "
+ "only object values.");
+ }
+
+ return nxt_conf_vldt_object(vldt, value, nxt_conf_vldt_compressor_members);
+}
+
+
+static nxt_int_t
+nxt_conf_vldt_compression_encoding(nxt_conf_validation_t *vldt,
+ nxt_conf_value_t *value, void *data)
+{
+ nxt_str_t token;
+
+ nxt_conf_get_string(value, &token);
+
+ if (nxt_http_comp_compressor_is_valid(&token)) {
+ return NXT_OK;
+ }
+
+ return nxt_conf_vldt_error(vldt, "\"%V\" is not a supported compressor.",
+ &token);
+}
+
+
+static nxt_int_t
nxt_conf_vldt_routes(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
void *data)
{
diff --git a/src/nxt_router.c b/src/nxt_router.c
index 44ea823b..d2486c9f 100644
--- a/src/nxt_router.c
+++ b/src/nxt_router.c
@@ -21,6 +21,7 @@
#include <nxt_router_request.h>
#include <nxt_app_queue.h>
#include <nxt_port_queue.h>
+#include <nxt_http_compression.h>
#define NXT_SHARED_PORT_ID 0xFFFFu
@@ -1680,6 +1681,8 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
static const nxt_str_t static_path = nxt_string("/settings/http/static");
static const nxt_str_t websocket_path =
nxt_string("/settings/http/websocket");
+ static const nxt_str_t compression_path =
+ nxt_string("/settings/http/compression");
static const nxt_str_t forwarded_path = nxt_string("/forwarded");
static const nxt_str_t client_ip_path = nxt_string("/client_ip");
#if (NXT_HAVE_OTEL)
@@ -2044,6 +2047,8 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
nxt_str_null(&skcf->body_temp_path);
if (http != NULL) {
+ nxt_conf_value_t *comp;
+
ret = nxt_conf_map_object(mp, http, nxt_router_http_conf,
nxt_nitems(nxt_router_http_conf),
skcf);
@@ -2051,6 +2056,11 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
nxt_alert(task, "http map error");
goto fail;
}
+
+ comp = nxt_conf_get_path(root, &compression_path);
+ if (comp != NULL) {
+ nxt_http_comp_compression_init(task, rtcf, comp);
+ }
}
if (websocket != NULL) {