comparison src/http/modules/ngx_http_limit_conn_module.c @ 7594:359b0ea2b067

Limit conn: limit_conn_dry_run directive. A new directive limit_conn_dry_run allows enabling the dry run mode. In this mode connections are not rejected, but reject status is logged as usual.
author Roman Arutyunyan <arut@nginx.com>
date Tue, 19 Nov 2019 11:30:41 +0300
parents f01ab2dbcfdc
children 9606d93aa586
comparison
equal deleted inserted replaced
7593:e84fb4991d74 7594:359b0ea2b067
38 38
39 typedef struct { 39 typedef struct {
40 ngx_array_t limits; 40 ngx_array_t limits;
41 ngx_uint_t log_level; 41 ngx_uint_t log_level;
42 ngx_uint_t status_code; 42 ngx_uint_t status_code;
43 ngx_flag_t dry_run;
43 } ngx_http_limit_conn_conf_t; 44 } ngx_http_limit_conn_conf_t;
44 45
45 46
46 static ngx_rbtree_node_t *ngx_http_limit_conn_lookup(ngx_rbtree_t *rbtree, 47 static ngx_rbtree_node_t *ngx_http_limit_conn_lookup(ngx_rbtree_t *rbtree,
47 ngx_str_t *key, uint32_t hash); 48 ngx_str_t *key, uint32_t hash);
99 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 100 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
100 ngx_conf_set_num_slot, 101 ngx_conf_set_num_slot,
101 NGX_HTTP_LOC_CONF_OFFSET, 102 NGX_HTTP_LOC_CONF_OFFSET,
102 offsetof(ngx_http_limit_conn_conf_t, status_code), 103 offsetof(ngx_http_limit_conn_conf_t, status_code),
103 &ngx_http_limit_conn_status_bounds }, 104 &ngx_http_limit_conn_status_bounds },
105
106 { ngx_string("limit_conn_dry_run"),
107 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
108 ngx_conf_set_flag_slot,
109 NGX_HTTP_LOC_CONF_OFFSET,
110 offsetof(ngx_http_limit_conn_conf_t, dry_run),
111 NULL },
104 112
105 ngx_null_command 113 ngx_null_command
106 }; 114 };
107 115
108 116
198 node = ngx_slab_alloc_locked(shpool, n); 206 node = ngx_slab_alloc_locked(shpool, n);
199 207
200 if (node == NULL) { 208 if (node == NULL) {
201 ngx_shmtx_unlock(&shpool->mutex); 209 ngx_shmtx_unlock(&shpool->mutex);
202 ngx_http_limit_conn_cleanup_all(r->pool); 210 ngx_http_limit_conn_cleanup_all(r->pool);
211
212 if (lccf->dry_run) {
213 return NGX_DECLINED;
214 }
215
203 return lccf->status_code; 216 return lccf->status_code;
204 } 217 }
205 218
206 lc = (ngx_http_limit_conn_node_t *) &node->color; 219 lc = (ngx_http_limit_conn_node_t *) &node->color;
207 220
219 if ((ngx_uint_t) lc->conn >= limits[i].conn) { 232 if ((ngx_uint_t) lc->conn >= limits[i].conn) {
220 233
221 ngx_shmtx_unlock(&shpool->mutex); 234 ngx_shmtx_unlock(&shpool->mutex);
222 235
223 ngx_log_error(lccf->log_level, r->connection->log, 0, 236 ngx_log_error(lccf->log_level, r->connection->log, 0,
224 "limiting connections by zone \"%V\"", 237 "limiting connections%s by zone \"%V\"",
238 lccf->dry_run ? ", dry run," : "",
225 &limits[i].shm_zone->shm.name); 239 &limits[i].shm_zone->shm.name);
226 240
227 ngx_http_limit_conn_cleanup_all(r->pool); 241 ngx_http_limit_conn_cleanup_all(r->pool);
242
243 if (lccf->dry_run) {
244 return NGX_DECLINED;
245 }
246
228 return lccf->status_code; 247 return lccf->status_code;
229 } 248 }
230 249
231 lc->conn++; 250 lc->conn++;
232 } 251 }
464 * conf->limits.elts = NULL; 483 * conf->limits.elts = NULL;
465 */ 484 */
466 485
467 conf->log_level = NGX_CONF_UNSET_UINT; 486 conf->log_level = NGX_CONF_UNSET_UINT;
468 conf->status_code = NGX_CONF_UNSET_UINT; 487 conf->status_code = NGX_CONF_UNSET_UINT;
488 conf->dry_run = NGX_CONF_UNSET;
469 489
470 return conf; 490 return conf;
471 } 491 }
472 492
473 493
482 } 502 }
483 503
484 ngx_conf_merge_uint_value(conf->log_level, prev->log_level, NGX_LOG_ERR); 504 ngx_conf_merge_uint_value(conf->log_level, prev->log_level, NGX_LOG_ERR);
485 ngx_conf_merge_uint_value(conf->status_code, prev->status_code, 505 ngx_conf_merge_uint_value(conf->status_code, prev->status_code,
486 NGX_HTTP_SERVICE_UNAVAILABLE); 506 NGX_HTTP_SERVICE_UNAVAILABLE);
507
508 ngx_conf_merge_value(conf->dry_run, prev->dry_run, 0);
487 509
488 return NGX_CONF_OK; 510 return NGX_CONF_OK;
489 } 511 }
490 512
491 513