Skip to content

Commit

Permalink
http: Wire up HTTP compression support to the config system
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
ac000 committed Nov 28, 2024
1 parent c4bbe07 commit fdbaced
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 0 deletions.
93 changes: 93 additions & 0 deletions src/nxt_conf_validation.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>


Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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"),
Expand Down Expand Up @@ -2270,6 +2317,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)
Expand Down
10 changes: 10 additions & 0 deletions src/nxt_router.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -2044,13 +2047,20 @@ 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);
if (ret != NXT_OK) {
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) {
Expand Down

0 comments on commit fdbaced

Please sign in to comment.