Mercurial > hg > nginx
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 |