Mercurial > hg > nginx-ranges
comparison src/http/modules/ngx_http_limit_req_module.c @ 544:f7ec98e3caeb NGINX_0_8_18
nginx 0.8.18
*) Feature: the "read_ahead" directive.
*) Feature: now several "perl_modules" directive may be used.
*) Feature: the "limit_req_log_level" and "limit_conn_log_level"
directives.
*) Bugfix: now "limit_req" directive conforms to the leaky bucket
algorithm.
Thanks to Maxim Dounin.
*) Bugfix: nginx did not work on Linux/sparc.
Thanks to Marcus Ramberg.
*) Bugfix: nginx sent '\0' in a "Location" response header line on
MKCOL request.
Thanks to Xie Zhenye.
*) Bugfix: zero status code was logged instead of 499 status code; the
bug had appeared in 0.8.11.
*) Bugfix: socket leak; the bug had appeared in 0.8.11.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 06 Oct 2009 00:00:00 +0400 |
parents | e8b686f230a8 |
children | a52c99698e7f |
comparison
equal
deleted
inserted
replaced
543:7688992d2abb | 544:f7ec98e3caeb |
---|---|
40 | 40 |
41 typedef struct { | 41 typedef struct { |
42 ngx_shm_zone_t *shm_zone; | 42 ngx_shm_zone_t *shm_zone; |
43 /* integer value, 1 corresponds to 0.001 r/s */ | 43 /* integer value, 1 corresponds to 0.001 r/s */ |
44 ngx_uint_t burst; | 44 ngx_uint_t burst; |
45 ngx_uint_t nodelay;/* unsigned nodelay:1 */ | 45 ngx_uint_t limit_log_level; |
46 ngx_uint_t delay_log_level; | |
47 | |
48 ngx_uint_t nodelay; /* unsigned nodelay:1 */ | |
46 } ngx_http_limit_req_conf_t; | 49 } ngx_http_limit_req_conf_t; |
47 | 50 |
48 | 51 |
49 static void ngx_http_limit_req_delay(ngx_http_request_t *r); | 52 static void ngx_http_limit_req_delay(ngx_http_request_t *r); |
50 static ngx_int_t ngx_http_limit_req_lookup(ngx_http_limit_req_conf_t *lrcf, | 53 static ngx_int_t ngx_http_limit_req_lookup(ngx_http_limit_req_conf_t *lrcf, |
60 static char *ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, | 63 static char *ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, |
61 void *conf); | 64 void *conf); |
62 static ngx_int_t ngx_http_limit_req_init(ngx_conf_t *cf); | 65 static ngx_int_t ngx_http_limit_req_init(ngx_conf_t *cf); |
63 | 66 |
64 | 67 |
68 static ngx_conf_enum_t ngx_http_limit_req_log_levels[] = { | |
69 { ngx_string("info"), NGX_LOG_INFO }, | |
70 { ngx_string("notice"), NGX_LOG_NOTICE }, | |
71 { ngx_string("warn"), NGX_LOG_WARN }, | |
72 { ngx_string("error"), NGX_LOG_ERR }, | |
73 { ngx_null_string, 0 } | |
74 }; | |
75 | |
76 | |
65 static ngx_command_t ngx_http_limit_req_commands[] = { | 77 static ngx_command_t ngx_http_limit_req_commands[] = { |
66 | 78 |
67 { ngx_string("limit_req_zone"), | 79 { ngx_string("limit_req_zone"), |
68 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE3, | 80 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE3, |
69 ngx_http_limit_req_zone, | 81 ngx_http_limit_req_zone, |
75 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123, | 87 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123, |
76 ngx_http_limit_req, | 88 ngx_http_limit_req, |
77 NGX_HTTP_LOC_CONF_OFFSET, | 89 NGX_HTTP_LOC_CONF_OFFSET, |
78 0, | 90 0, |
79 NULL }, | 91 NULL }, |
92 | |
93 { ngx_string("limit_req_log_level"), | |
94 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
95 ngx_conf_set_enum_slot, | |
96 NGX_HTTP_LOC_CONF_OFFSET, | |
97 offsetof(ngx_http_limit_req_conf_t, limit_log_level), | |
98 &ngx_http_limit_req_log_levels }, | |
80 | 99 |
81 ngx_null_command | 100 ngx_null_command |
82 }; | 101 }; |
83 | 102 |
84 | 103 |
184 "limit_req: %i %ui.%03ui", rc, excess / 1000, excess % 1000); | 203 "limit_req: %i %ui.%03ui", rc, excess / 1000, excess % 1000); |
185 | 204 |
186 if (rc == NGX_BUSY) { | 205 if (rc == NGX_BUSY) { |
187 ngx_shmtx_unlock(&ctx->shpool->mutex); | 206 ngx_shmtx_unlock(&ctx->shpool->mutex); |
188 | 207 |
189 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 208 ngx_log_error(lrcf->limit_log_level, r->connection->log, 0, |
190 "limiting requests, excess: %ui.%03ui by zone \"%V\"", | 209 "limiting requests, excess: %ui.%03ui by zone \"%V\"", |
191 excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name); | 210 excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name); |
192 | 211 |
193 return NGX_HTTP_SERVICE_UNAVAILABLE; | 212 return NGX_HTTP_SERVICE_UNAVAILABLE; |
194 } | 213 } |
198 | 217 |
199 if (lrcf->nodelay) { | 218 if (lrcf->nodelay) { |
200 return NGX_DECLINED; | 219 return NGX_DECLINED; |
201 } | 220 } |
202 | 221 |
203 ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, | 222 ngx_log_error(lrcf->delay_log_level, r->connection->log, 0, |
204 "delaying request, excess: %ui.%03ui, by zone \"%V\"", | 223 "delaying request, excess: %ui.%03ui, by zone \"%V\"", |
205 excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name); | 224 excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name); |
206 | 225 |
207 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { | 226 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { |
208 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 227 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
377 now = (ngx_msec_t) (tp->sec * 1000 + tp->msec); | 396 now = (ngx_msec_t) (tp->sec * 1000 + tp->msec); |
378 ms = (ngx_msec_int_t) (now - lr->last); | 397 ms = (ngx_msec_int_t) (now - lr->last); |
379 | 398 |
380 excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000; | 399 excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000; |
381 | 400 |
401 if ((ngx_uint_t) excess > lrcf->burst) { | |
402 *lrp = lr; | |
403 return NGX_BUSY; | |
404 } | |
405 | |
382 if (excess < 0) { | 406 if (excess < 0) { |
383 excess = 0; | 407 excess = 0; |
384 } | 408 } |
385 | 409 |
386 lr->excess = excess; | 410 lr->excess = excess; |
387 lr->last = now; | 411 lr->last = now; |
388 | 412 |
389 *lrp = lr; | 413 *lrp = lr; |
390 | |
391 if ((ngx_uint_t) excess > lrcf->burst) { | |
392 return NGX_BUSY; | |
393 } | |
394 | 414 |
395 if (excess) { | 415 if (excess) { |
396 return NGX_AGAIN; | 416 return NGX_AGAIN; |
397 } | 417 } |
398 | 418 |
546 * conf->shm_zone = NULL; | 566 * conf->shm_zone = NULL; |
547 * conf->burst = 0; | 567 * conf->burst = 0; |
548 * conf->nodelay = 0; | 568 * conf->nodelay = 0; |
549 */ | 569 */ |
550 | 570 |
571 conf->limit_log_level = NGX_CONF_UNSET_UINT; | |
572 | |
551 return conf; | 573 return conf; |
552 } | 574 } |
553 | 575 |
554 | 576 |
555 static char * | 577 static char * |
559 ngx_http_limit_req_conf_t *conf = child; | 581 ngx_http_limit_req_conf_t *conf = child; |
560 | 582 |
561 if (conf->shm_zone == NULL) { | 583 if (conf->shm_zone == NULL) { |
562 *conf = *prev; | 584 *conf = *prev; |
563 } | 585 } |
586 | |
587 ngx_conf_merge_uint_value(conf->limit_log_level, prev->limit_log_level, | |
588 NGX_LOG_ERR); | |
589 | |
590 conf->delay_log_level = (conf->limit_log_level == NGX_LOG_INFO) ? | |
591 NGX_LOG_INFO : conf->limit_log_level + 1; | |
564 | 592 |
565 return NGX_CONF_OK; | 593 return NGX_CONF_OK; |
566 } | 594 } |
567 | 595 |
568 | 596 |