Mercurial > hg > nginx
comparison src/http/modules/ngx_http_limit_req_module.c @ 3779:57aecfdcac3d
an excess was logged as 0.000 if requests were limited without delay:
*) use a real excess value instead of non-updated limit_req rbtree node field,
*) move inactivity queue handling inside ngx_http_limit_req_lookup()
since the node is not required outside the lookup function;
the bug has been introduced in r3184
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 13 Oct 2010 20:58:41 +0000 |
parents | eb156d98a9fa |
children | d94d7104f598 |
comparison
equal
deleted
inserted
replaced
3778:d29e8060ca0c | 3779:57aecfdcac3d |
---|---|
49 } ngx_http_limit_req_conf_t; | 49 } ngx_http_limit_req_conf_t; |
50 | 50 |
51 | 51 |
52 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); |
53 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, |
54 ngx_uint_t hash, u_char *data, size_t len, ngx_http_limit_req_node_t **lrp); | 54 ngx_uint_t hash, u_char *data, size_t len, ngx_uint_t *ep); |
55 static void ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, | 55 static void ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, |
56 ngx_uint_t n); | 56 ngx_uint_t n); |
57 | 57 |
58 static void *ngx_http_limit_req_create_conf(ngx_conf_t *cf); | 58 static void *ngx_http_limit_req_create_conf(ngx_conf_t *cf); |
59 static char *ngx_http_limit_req_merge_conf(ngx_conf_t *cf, void *parent, | 59 static char *ngx_http_limit_req_merge_conf(ngx_conf_t *cf, void *parent, |
184 | 184 |
185 ngx_shmtx_lock(&ctx->shpool->mutex); | 185 ngx_shmtx_lock(&ctx->shpool->mutex); |
186 | 186 |
187 ngx_http_limit_req_expire(ctx, 1); | 187 ngx_http_limit_req_expire(ctx, 1); |
188 | 188 |
189 rc = ngx_http_limit_req_lookup(lrcf, hash, vv->data, len, &lr); | 189 rc = ngx_http_limit_req_lookup(lrcf, hash, vv->data, len, &excess); |
190 | |
191 if (lr) { | |
192 ngx_queue_remove(&lr->queue); | |
193 | |
194 ngx_queue_insert_head(&ctx->sh->queue, &lr->queue); | |
195 | |
196 excess = lr->excess; | |
197 | |
198 } else { | |
199 excess = 0; | |
200 } | |
201 | 190 |
202 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 191 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
203 "limit_req: %i %ui.%03ui", rc, excess / 1000, excess % 1000); | 192 "limit_req: %i %ui.%03ui", rc, excess / 1000, excess % 1000); |
204 | 193 |
205 if (rc == NGX_BUSY) { | 194 if (rc == NGX_BUSY) { |
354 } | 343 } |
355 | 344 |
356 | 345 |
357 static ngx_int_t | 346 static ngx_int_t |
358 ngx_http_limit_req_lookup(ngx_http_limit_req_conf_t *lrcf, ngx_uint_t hash, | 347 ngx_http_limit_req_lookup(ngx_http_limit_req_conf_t *lrcf, ngx_uint_t hash, |
359 u_char *data, size_t len, ngx_http_limit_req_node_t **lrp) | 348 u_char *data, size_t len, ngx_uint_t *ep) |
360 { | 349 { |
361 ngx_int_t rc, excess; | 350 ngx_int_t rc, excess; |
362 ngx_time_t *tp; | 351 ngx_time_t *tp; |
363 ngx_msec_t now; | 352 ngx_msec_t now; |
364 ngx_msec_int_t ms; | 353 ngx_msec_int_t ms; |
389 lr = (ngx_http_limit_req_node_t *) &node->color; | 378 lr = (ngx_http_limit_req_node_t *) &node->color; |
390 | 379 |
391 rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len); | 380 rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len); |
392 | 381 |
393 if (rc == 0) { | 382 if (rc == 0) { |
383 ngx_queue_remove(&lr->queue); | |
384 ngx_queue_insert_head(&ctx->sh->queue, &lr->queue); | |
394 | 385 |
395 tp = ngx_timeofday(); | 386 tp = ngx_timeofday(); |
396 | 387 |
397 now = (ngx_msec_t) (tp->sec * 1000 + tp->msec); | 388 now = (ngx_msec_t) (tp->sec * 1000 + tp->msec); |
398 ms = (ngx_msec_int_t) (now - lr->last); | 389 ms = (ngx_msec_int_t) (now - lr->last); |
401 | 392 |
402 if (excess < 0) { | 393 if (excess < 0) { |
403 excess = 0; | 394 excess = 0; |
404 } | 395 } |
405 | 396 |
397 *ep = excess; | |
398 | |
406 if ((ngx_uint_t) excess > lrcf->burst) { | 399 if ((ngx_uint_t) excess > lrcf->burst) { |
407 *lrp = lr; | |
408 return NGX_BUSY; | 400 return NGX_BUSY; |
409 } | 401 } |
410 | 402 |
411 lr->excess = excess; | 403 lr->excess = excess; |
412 lr->last = now; | 404 lr->last = now; |
413 | |
414 *lrp = lr; | |
415 | 405 |
416 if (excess) { | 406 if (excess) { |
417 return NGX_AGAIN; | 407 return NGX_AGAIN; |
418 } | 408 } |
419 | 409 |
425 } while (node != sentinel && hash == node->key); | 415 } while (node != sentinel && hash == node->key); |
426 | 416 |
427 break; | 417 break; |
428 } | 418 } |
429 | 419 |
430 *lrp = NULL; | 420 *ep = 0; |
431 | 421 |
432 return NGX_DECLINED; | 422 return NGX_DECLINED; |
433 } | 423 } |
434 | 424 |
435 | 425 |