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