[PATCH] Conditional application of limit_conn directive
turchanov at farpost.com
turchanov at farpost.com
Tue Sep 22 06:53:25 UTC 2020
Patch with tests will follow
# HG changeset patch
# User Sergei Turchanov <turchanov at farpost.com>
# Date 1600756248 -36000
# Tue Sep 22 16:30:48 2020 +1000
# Node ID 2cf4e00bb96b17142a82e5f1868197465cf5c194
# Parent 052ecc68d35038b1b4adde12efe6249a92055f09
Conditional application of limit_conn directive
Implemented conditional application of limit_conn directive.
Since limit_conn directive cannot be used inside 'if' block, an optional
parameter 'if=condition' was introduced to control whether the limit is
applied or not. The limit will not be applied if the condition evaluates
to "0" or an empty string.
diff -r 052ecc68d350 -r 2cf4e00bb96b
src/http/modules/ngx_http_limit_conn_module.c
--- a/src/http/modules/ngx_http_limit_conn_module.c Wed Sep 16 18:26:25
2020 +0300
+++ b/src/http/modules/ngx_http_limit_conn_module.c Tue Sep 22 16:30:48
2020 +1000
@@ -45,6 +45,7 @@
typedef struct {
ngx_shm_zone_t *shm_zone;
ngx_uint_t conn;
+ ngx_http_complex_value_t *filter;
} ngx_http_limit_conn_limit_t;
@@ -98,7 +99,7 @@
NULL },
{ ngx_string("limit_conn"),
-
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
ngx_http_limit_conn,
NGX_HTTP_LOC_CONF_OFFSET,
0,
@@ -181,7 +182,7 @@
{
size_t n;
uint32_t hash;
- ngx_str_t key;
+ ngx_str_t key, val;
ngx_uint_t i;
ngx_rbtree_node_t *node;
ngx_pool_cleanup_t *cln;
@@ -199,6 +200,16 @@
limits = lccf->limits.elts;
for (i = 0; i < lccf->limits.nelts; i++) {
+ if (limits[i].filter) {
+ if (ngx_http_complex_value(r, limits[i].filter, &val) !=
NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ if (val.len == 0 || (val.len == 1 && val.data[0] == '0')) {
+ continue;
+ }
+ }
+
ctx = limits[i].shm_zone->data;
if (ngx_http_complex_value(r, &ctx->key, &key) != NGX_OK) {
@@ -662,11 +673,12 @@
static char *
ngx_http_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- ngx_shm_zone_t *shm_zone;
- ngx_http_limit_conn_conf_t *lccf = conf;
- ngx_http_limit_conn_limit_t *limit, *limits;
+ ngx_shm_zone_t *shm_zone;
+ ngx_http_limit_conn_conf_t *lccf = conf;
+ ngx_http_limit_conn_limit_t *limit, *limits;
+ ngx_http_compile_complex_value_t ccv;
- ngx_str_t *value;
+ ngx_str_t *value, s;
ngx_int_t n;
ngx_uint_t i;
@@ -712,10 +724,38 @@
if (limit == NULL) {
return NGX_CONF_ERROR;
}
+ ngx_memzero(limit, sizeof(ngx_http_limit_conn_limit_t));
limit->conn = n;
limit->shm_zone = shm_zone;
+ if (cf->args->nelts == 4) {
+ if (ngx_strncmp(value[3].data, "if=", 3) == 0) {
+ s.len = value[3].len - 3;
+ s.data = value[3].data + 3;
+
+ ngx_memzero(&ccv,
sizeof(ngx_http_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = &s;
+ ccv.complex_value = ngx_palloc(cf->pool,
+
sizeof(ngx_http_complex_value_t));
+ if (ccv.complex_value == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ limit->filter = ccv.complex_value;
+ } else {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter \"%V\"", &value[3]);
+ return NGX_CONF_ERROR;
+ }
+ }
+
return NGX_CONF_OK;
}
More information about the nginx-devel
mailing list