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