comparison src/http/modules/ngx_http_limit_req_module.c @ 7515:2db68852d6a0

Limit req: limit_req_dry_run directive. A new directive limit_req_dry_run allows enabling the dry run mode. In this mode requests are neither rejected nor delayed, but reject/delay status is logged as usual.
author Roman Arutyunyan <arut@nginx.com>
date Wed, 05 Jun 2019 19:55:27 +0300
parents d6ca744c727e
children 776d1bebdca2
comparison
equal deleted inserted replaced
7514:319242d2ddc9 7515:2db68852d6a0
51 typedef struct { 51 typedef struct {
52 ngx_array_t limits; 52 ngx_array_t limits;
53 ngx_uint_t limit_log_level; 53 ngx_uint_t limit_log_level;
54 ngx_uint_t delay_log_level; 54 ngx_uint_t delay_log_level;
55 ngx_uint_t status_code; 55 ngx_uint_t status_code;
56 ngx_flag_t dry_run;
56 } ngx_http_limit_req_conf_t; 57 } ngx_http_limit_req_conf_t;
57 58
58 59
59 static void ngx_http_limit_req_delay(ngx_http_request_t *r); 60 static void ngx_http_limit_req_delay(ngx_http_request_t *r);
60 static ngx_int_t ngx_http_limit_req_lookup(ngx_http_limit_req_limit_t *limit, 61 static ngx_int_t ngx_http_limit_req_lookup(ngx_http_limit_req_limit_t *limit,
115 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 116 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
116 ngx_conf_set_num_slot, 117 ngx_conf_set_num_slot,
117 NGX_HTTP_LOC_CONF_OFFSET, 118 NGX_HTTP_LOC_CONF_OFFSET,
118 offsetof(ngx_http_limit_req_conf_t, status_code), 119 offsetof(ngx_http_limit_req_conf_t, status_code),
119 &ngx_http_limit_req_status_bounds }, 120 &ngx_http_limit_req_status_bounds },
121
122 { ngx_string("limit_req_dry_run"),
123 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
124 ngx_conf_set_flag_slot,
125 NGX_HTTP_LOC_CONF_OFFSET,
126 offsetof(ngx_http_limit_req_conf_t, dry_run),
127 NULL },
120 128
121 ngx_null_command 129 ngx_null_command
122 }; 130 };
123 131
124 132
228 236
229 if (rc == NGX_BUSY || rc == NGX_ERROR) { 237 if (rc == NGX_BUSY || rc == NGX_ERROR) {
230 238
231 if (rc == NGX_BUSY) { 239 if (rc == NGX_BUSY) {
232 ngx_log_error(lrcf->limit_log_level, r->connection->log, 0, 240 ngx_log_error(lrcf->limit_log_level, r->connection->log, 0,
233 "limiting requests, excess: %ui.%03ui by zone \"%V\"", 241 "limiting requests%s, excess: %ui.%03ui by zone \"%V\"",
234 excess / 1000, excess % 1000, 242 lrcf->dry_run ? ", dry run" : "",
235 &limit->shm_zone->shm.name); 243 excess / 1000, excess % 1000,
244 &limit->shm_zone->shm.name);
236 } 245 }
237 246
238 while (n--) { 247 while (n--) {
239 ctx = limits[n].shm_zone->data; 248 ctx = limits[n].shm_zone->data;
240 249
249 ngx_shmtx_unlock(&ctx->shpool->mutex); 258 ngx_shmtx_unlock(&ctx->shpool->mutex);
250 259
251 ctx->node = NULL; 260 ctx->node = NULL;
252 } 261 }
253 262
263 if (lrcf->dry_run) {
264 return NGX_DECLINED;
265 }
266
254 return lrcf->status_code; 267 return lrcf->status_code;
255 } 268 }
256 269
257 /* rc == NGX_AGAIN || rc == NGX_OK */ 270 /* rc == NGX_AGAIN || rc == NGX_OK */
258 271
265 if (!delay) { 278 if (!delay) {
266 return NGX_DECLINED; 279 return NGX_DECLINED;
267 } 280 }
268 281
269 ngx_log_error(lrcf->delay_log_level, r->connection->log, 0, 282 ngx_log_error(lrcf->delay_log_level, r->connection->log, 0,
270 "delaying request, excess: %ui.%03ui, by zone \"%V\"", 283 "delaying request%s, excess: %ui.%03ui, by zone \"%V\"",
284 lrcf->dry_run ? ", dry run" : "",
271 excess / 1000, excess % 1000, &limit->shm_zone->shm.name); 285 excess / 1000, excess % 1000, &limit->shm_zone->shm.name);
286
287 if (lrcf->dry_run) {
288 return NGX_DECLINED;
289 }
272 290
273 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { 291 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
274 return NGX_HTTP_INTERNAL_SERVER_ERROR; 292 return NGX_HTTP_INTERNAL_SERVER_ERROR;
275 } 293 }
276 294
709 * conf->limits.elts = NULL; 727 * conf->limits.elts = NULL;
710 */ 728 */
711 729
712 conf->limit_log_level = NGX_CONF_UNSET_UINT; 730 conf->limit_log_level = NGX_CONF_UNSET_UINT;
713 conf->status_code = NGX_CONF_UNSET_UINT; 731 conf->status_code = NGX_CONF_UNSET_UINT;
732 conf->dry_run = NGX_CONF_UNSET;
714 733
715 return conf; 734 return conf;
716 } 735 }
717 736
718 737
732 conf->delay_log_level = (conf->limit_log_level == NGX_LOG_INFO) ? 751 conf->delay_log_level = (conf->limit_log_level == NGX_LOG_INFO) ?
733 NGX_LOG_INFO : conf->limit_log_level + 1; 752 NGX_LOG_INFO : conf->limit_log_level + 1;
734 753
735 ngx_conf_merge_uint_value(conf->status_code, prev->status_code, 754 ngx_conf_merge_uint_value(conf->status_code, prev->status_code,
736 NGX_HTTP_SERVICE_UNAVAILABLE); 755 NGX_HTTP_SERVICE_UNAVAILABLE);
756
757 ngx_conf_merge_value(conf->dry_run, prev->dry_run, 0);
737 758
738 return NGX_CONF_OK; 759 return NGX_CONF_OK;
739 } 760 }
740 761
741 762