comparison src/http/modules/ngx_http_limit_req_module.c @ 2374:7b11f9a1bfe1

rename "lz" to "lr" in variable names
author Igor Sysoev <igor@sysoev.ru>
date Mon, 08 Dec 2008 14:13:36 +0000
parents b56a9ba4824d
children 95004b25476c
comparison
equal deleted inserted replaced
2373:f4603d71f532 2374:7b11f9a1bfe1
36 ngx_uint_t nodelay;/* unsigned nodelay:1 */ 36 ngx_uint_t nodelay;/* unsigned nodelay:1 */
37 } ngx_http_limit_req_conf_t; 37 } ngx_http_limit_req_conf_t;
38 38
39 39
40 static void ngx_http_limit_req_delay(ngx_http_request_t *r); 40 static void ngx_http_limit_req_delay(ngx_http_request_t *r);
41 static ngx_int_t ngx_http_limit_req_lookup(ngx_http_limit_req_conf_t *lzcf, 41 static ngx_int_t ngx_http_limit_req_lookup(ngx_http_limit_req_conf_t *lrcf,
42 ngx_uint_t hash, u_char *data, size_t len, ngx_http_limit_req_node_t **lzp); 42 ngx_uint_t hash, u_char *data, size_t len, ngx_http_limit_req_node_t **lrp);
43 static void ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, 43 static void ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx,
44 ngx_uint_t n); 44 ngx_uint_t n);
45 45
46 static void *ngx_http_limit_req_create_conf(ngx_conf_t *cf); 46 static void *ngx_http_limit_req_create_conf(ngx_conf_t *cf);
47 static char *ngx_http_limit_req_merge_conf(ngx_conf_t *cf, void *parent, 47 static char *ngx_http_limit_req_merge_conf(ngx_conf_t *cf, void *parent,
113 ngx_uint_t excess; 113 ngx_uint_t excess;
114 ngx_time_t *tp; 114 ngx_time_t *tp;
115 ngx_rbtree_node_t *node; 115 ngx_rbtree_node_t *node;
116 ngx_http_variable_value_t *vv; 116 ngx_http_variable_value_t *vv;
117 ngx_http_limit_req_ctx_t *ctx; 117 ngx_http_limit_req_ctx_t *ctx;
118 ngx_http_limit_req_node_t *lz; 118 ngx_http_limit_req_node_t *lr;
119 ngx_http_limit_req_conf_t *lzcf; 119 ngx_http_limit_req_conf_t *lrcf;
120 120
121 if (r->main->limit_req_set) { 121 if (r->main->limit_req_set) {
122 return NGX_DECLINED; 122 return NGX_DECLINED;
123 } 123 }
124 124
125 lzcf = ngx_http_get_module_loc_conf(r, ngx_http_limit_req_module); 125 lrcf = ngx_http_get_module_loc_conf(r, ngx_http_limit_req_module);
126 126
127 if (lzcf->shm_zone == NULL) { 127 if (lrcf->shm_zone == NULL) {
128 return NGX_DECLINED; 128 return NGX_DECLINED;
129 } 129 }
130 130
131 ctx = lzcf->shm_zone->data; 131 ctx = lrcf->shm_zone->data;
132 132
133 vv = ngx_http_get_indexed_variable(r, ctx->index); 133 vv = ngx_http_get_indexed_variable(r, ctx->index);
134 134
135 if (vv == NULL || vv->not_found) { 135 if (vv == NULL || vv->not_found) {
136 return NGX_DECLINED; 136 return NGX_DECLINED;
156 156
157 ngx_shmtx_lock(&ctx->shpool->mutex); 157 ngx_shmtx_lock(&ctx->shpool->mutex);
158 158
159 ngx_http_limit_req_expire(ctx, 1); 159 ngx_http_limit_req_expire(ctx, 1);
160 160
161 rc = ngx_http_limit_req_lookup(lzcf, hash, vv->data, len, &lz); 161 rc = ngx_http_limit_req_lookup(lrcf, hash, vv->data, len, &lr);
162 162
163 if (lz) { 163 if (lr) {
164 ngx_queue_remove(&lz->queue); 164 ngx_queue_remove(&lr->queue);
165 165
166 ngx_queue_insert_head(ctx->queue, &lz->queue); 166 ngx_queue_insert_head(ctx->queue, &lr->queue);
167 167
168 excess = lz->excess; 168 excess = lr->excess;
169 169
170 } else { 170 } else {
171 excess = 0; 171 excess = 0;
172 } 172 }
173 173
185 } 185 }
186 186
187 if (rc == NGX_AGAIN) { 187 if (rc == NGX_AGAIN) {
188 ngx_shmtx_unlock(&ctx->shpool->mutex); 188 ngx_shmtx_unlock(&ctx->shpool->mutex);
189 189
190 if (lzcf->nodelay) { 190 if (lrcf->nodelay) {
191 return NGX_DECLINED; 191 return NGX_DECLINED;
192 } 192 }
193 193
194 ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, 194 ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
195 "delaying request, excess: %ui.%03ui", 195 "delaying request, excess: %ui.%03ui",
226 ngx_shmtx_unlock(&ctx->shpool->mutex); 226 ngx_shmtx_unlock(&ctx->shpool->mutex);
227 return NGX_HTTP_SERVICE_UNAVAILABLE; 227 return NGX_HTTP_SERVICE_UNAVAILABLE;
228 } 228 }
229 } 229 }
230 230
231 lz = (ngx_http_limit_req_node_t *) &node->color; 231 lr = (ngx_http_limit_req_node_t *) &node->color;
232 232
233 node->key = hash; 233 node->key = hash;
234 lz->len = (u_char) len; 234 lr->len = (u_char) len;
235 235
236 tp = ngx_timeofday(); 236 tp = ngx_timeofday();
237 lz->last = (ngx_msec_t) (tp->sec * 1000 + tp->msec); 237 lr->last = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
238 238
239 lz->excess = 0; 239 lr->excess = 0;
240 ngx_memcpy(lz->data, vv->data, len); 240 ngx_memcpy(lr->data, vv->data, len);
241 241
242 ngx_rbtree_insert(ctx->rbtree, node); 242 ngx_rbtree_insert(ctx->rbtree, node);
243 243
244 ngx_queue_insert_head(ctx->queue, &lz->queue); 244 ngx_queue_insert_head(ctx->queue, &lr->queue);
245 245
246 done: 246 done:
247 247
248 ngx_shmtx_unlock(&ctx->shpool->mutex); 248 ngx_shmtx_unlock(&ctx->shpool->mutex);
249 249
272 static void 272 static void
273 ngx_http_limit_req_rbtree_insert_value(ngx_rbtree_node_t *temp, 273 ngx_http_limit_req_rbtree_insert_value(ngx_rbtree_node_t *temp,
274 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) 274 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
275 { 275 {
276 ngx_rbtree_node_t **p; 276 ngx_rbtree_node_t **p;
277 ngx_http_limit_req_node_t *lzn, *lznt; 277 ngx_http_limit_req_node_t *lrn, *lrnt;
278 278
279 for ( ;; ) { 279 for ( ;; ) {
280 280
281 if (node->key < temp->key) { 281 if (node->key < temp->key) {
282 282
286 286
287 p = &temp->right; 287 p = &temp->right;
288 288
289 } else { /* node->key == temp->key */ 289 } else { /* node->key == temp->key */
290 290
291 lzn = (ngx_http_limit_req_node_t *) &node->color; 291 lrn = (ngx_http_limit_req_node_t *) &node->color;
292 lznt = (ngx_http_limit_req_node_t *) &temp->color; 292 lrnt = (ngx_http_limit_req_node_t *) &temp->color;
293 293
294 p = (ngx_memn2cmp(lzn->data, lznt->data, lzn->len, lznt->len) < 0) 294 p = (ngx_memn2cmp(lrn->data, lrnt->data, lrn->len, lrnt->len) < 0)
295 ? &temp->left : &temp->right; 295 ? &temp->left : &temp->right;
296 } 296 }
297 297
298 if (*p == sentinel) { 298 if (*p == sentinel) {
299 break; 299 break;
309 ngx_rbt_red(node); 309 ngx_rbt_red(node);
310 } 310 }
311 311
312 312
313 static ngx_int_t 313 static ngx_int_t
314 ngx_http_limit_req_lookup(ngx_http_limit_req_conf_t *lzcf, ngx_uint_t hash, 314 ngx_http_limit_req_lookup(ngx_http_limit_req_conf_t *lrcf, ngx_uint_t hash,
315 u_char *data, size_t len, ngx_http_limit_req_node_t **lzp) 315 u_char *data, size_t len, ngx_http_limit_req_node_t **lrp)
316 { 316 {
317 ngx_int_t rc, excess; 317 ngx_int_t rc, excess;
318 ngx_time_t *tp; 318 ngx_time_t *tp;
319 ngx_msec_t now; 319 ngx_msec_t now;
320 ngx_msec_int_t ms; 320 ngx_msec_int_t ms;
321 ngx_rbtree_node_t *node, *sentinel; 321 ngx_rbtree_node_t *node, *sentinel;
322 ngx_http_limit_req_ctx_t *ctx; 322 ngx_http_limit_req_ctx_t *ctx;
323 ngx_http_limit_req_node_t *lz; 323 ngx_http_limit_req_node_t *lr;
324 324
325 ctx = lzcf->shm_zone->data; 325 ctx = lrcf->shm_zone->data;
326 326
327 node = ctx->rbtree->root; 327 node = ctx->rbtree->root;
328 sentinel = ctx->rbtree->sentinel; 328 sentinel = ctx->rbtree->sentinel;
329 329
330 while (node != sentinel) { 330 while (node != sentinel) {
340 } 340 }
341 341
342 /* hash == node->key */ 342 /* hash == node->key */
343 343
344 do { 344 do {
345 lz = (ngx_http_limit_req_node_t *) &node->color; 345 lr = (ngx_http_limit_req_node_t *) &node->color;
346 346
347 rc = ngx_memn2cmp(data, lz->data, len, (size_t) lz->len); 347 rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len);
348 348
349 if (rc == 0) { 349 if (rc == 0) {
350 350
351 tp = ngx_timeofday(); 351 tp = ngx_timeofday();
352 352
353 now = (ngx_msec_t) (tp->sec * 1000 + tp->msec); 353 now = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
354 ms = (ngx_msec_int_t) (now - lz->last); 354 ms = (ngx_msec_int_t) (now - lr->last);
355 355
356 excess = lz->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000; 356 excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
357 357
358 if (excess < 0) { 358 if (excess < 0) {
359 excess = 0; 359 excess = 0;
360 } 360 }
361 361
362 lz->excess = excess; 362 lr->excess = excess;
363 lz->last = now; 363 lr->last = now;
364 364
365 *lzp = lz; 365 *lrp = lr;
366 366
367 if ((ngx_uint_t) excess > lzcf->burst) { 367 if ((ngx_uint_t) excess > lrcf->burst) {
368 return NGX_BUSY; 368 return NGX_BUSY;
369 } 369 }
370 370
371 if (excess) { 371 if (excess) {
372 return NGX_AGAIN; 372 return NGX_AGAIN;
380 } while (node != sentinel && hash == node->key); 380 } while (node != sentinel && hash == node->key);
381 381
382 break; 382 break;
383 } 383 }
384 384
385 *lzp = NULL; 385 *lrp = NULL;
386 386
387 return NGX_DECLINED; 387 return NGX_DECLINED;
388 } 388 }
389 389
390 390
395 ngx_time_t *tp; 395 ngx_time_t *tp;
396 ngx_msec_t now; 396 ngx_msec_t now;
397 ngx_queue_t *q; 397 ngx_queue_t *q;
398 ngx_msec_int_t ms; 398 ngx_msec_int_t ms;
399 ngx_rbtree_node_t *node; 399 ngx_rbtree_node_t *node;
400 ngx_http_limit_req_node_t *lz; 400 ngx_http_limit_req_node_t *lr;
401 401
402 tp = ngx_timeofday(); 402 tp = ngx_timeofday();
403 403
404 now = (ngx_msec_t) (tp->sec * 1000 + tp->msec); 404 now = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
405 405
415 return; 415 return;
416 } 416 }
417 417
418 q = ngx_queue_last(ctx->queue); 418 q = ngx_queue_last(ctx->queue);
419 419
420 lz = ngx_queue_data(q, ngx_http_limit_req_node_t, queue); 420 lr = ngx_queue_data(q, ngx_http_limit_req_node_t, queue);
421 421
422 if (n++ != 0) { 422 if (n++ != 0) {
423 423
424 ms = (ngx_msec_int_t) (now - lz->last); 424 ms = (ngx_msec_int_t) (now - lr->last);
425 ms = ngx_abs(ms); 425 ms = ngx_abs(ms);
426 426
427 if (ms < 60000) { 427 if (ms < 60000) {
428 return; 428 return;
429 } 429 }
430 430
431 excess = lz->excess - ctx->rate * ms / 1000; 431 excess = lr->excess - ctx->rate * ms / 1000;
432 432
433 if (excess > 0) { 433 if (excess > 0) {
434 return; 434 return;
435 } 435 }
436 } 436 }
437 437
438 ngx_queue_remove(q); 438 ngx_queue_remove(q);
439 439
440 node = (ngx_rbtree_node_t *) 440 node = (ngx_rbtree_node_t *)
441 ((u_char *) lz - offsetof(ngx_rbtree_node_t, color)); 441 ((u_char *) lr - offsetof(ngx_rbtree_node_t, color));
442 442
443 ngx_rbtree_delete(ctx->rbtree, node); 443 ngx_rbtree_delete(ctx->rbtree, node);
444 444
445 ngx_slab_free_locked(ctx->shpool, node); 445 ngx_slab_free_locked(ctx->shpool, node);
446 } 446 }
669 669
670 670
671 static char * 671 static char *
672 ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 672 ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
673 { 673 {
674 ngx_http_limit_req_conf_t *lzcf = conf; 674 ngx_http_limit_req_conf_t *lrcf = conf;
675 675
676 ngx_int_t burst; 676 ngx_int_t burst;
677 ngx_str_t *value, s; 677 ngx_str_t *value, s;
678 ngx_uint_t i; 678 ngx_uint_t i;
679 679
680 if (lzcf->shm_zone) { 680 if (lrcf->shm_zone) {
681 return "is duplicate"; 681 return "is duplicate";
682 } 682 }
683 683
684 value = cf->args->elts; 684 value = cf->args->elts;
685 685
690 if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { 690 if (ngx_strncmp(value[i].data, "zone=", 5) == 0) {
691 691
692 s.len = value[i].len - 5; 692 s.len = value[i].len - 5;
693 s.data = value[i].data + 5; 693 s.data = value[i].data + 5;
694 694
695 lzcf->shm_zone = ngx_shared_memory_add(cf, &s, 0, 695 lrcf->shm_zone = ngx_shared_memory_add(cf, &s, 0,
696 &ngx_http_limit_req_module); 696 &ngx_http_limit_req_module);
697 if (lzcf->shm_zone == NULL) { 697 if (lrcf->shm_zone == NULL) {
698 return NGX_CONF_ERROR; 698 return NGX_CONF_ERROR;
699 } 699 }
700 700
701 continue; 701 continue;
702 } 702 }
712 712
713 continue; 713 continue;
714 } 714 }
715 715
716 if (ngx_strncmp(value[i].data, "nodelay", 7) == 0) { 716 if (ngx_strncmp(value[i].data, "nodelay", 7) == 0) {
717 lzcf->nodelay = 1; 717 lrcf->nodelay = 1;
718 continue; 718 continue;
719 } 719 }
720 720
721 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 721 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
722 "invalid parameter \"%V\"", &value[i]); 722 "invalid parameter \"%V\"", &value[i]);
723 return NGX_CONF_ERROR; 723 return NGX_CONF_ERROR;
724 } 724 }
725 725
726 if (lzcf->shm_zone == NULL) { 726 if (lrcf->shm_zone == NULL) {
727 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 727 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
728 "\"%V\" must have \"zone\" parameter", 728 "\"%V\" must have \"zone\" parameter",
729 &cmd->name); 729 &cmd->name);
730 return NGX_CONF_ERROR; 730 return NGX_CONF_ERROR;
731 } 731 }
732 732
733 if (lzcf->shm_zone->data == NULL) { 733 if (lrcf->shm_zone->data == NULL) {
734 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 734 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
735 "unknown limit_req_zone \"%V\"", 735 "unknown limit_req_zone \"%V\"",
736 &lzcf->shm_zone->name); 736 &lrcf->shm_zone->name);
737 return NGX_CONF_ERROR; 737 return NGX_CONF_ERROR;
738 } 738 }
739 739
740 lzcf->burst = burst * 1000; 740 lrcf->burst = burst * 1000;
741 741
742 return NGX_CONF_OK; 742 return NGX_CONF_OK;
743 } 743 }
744 744
745 745