Mercurial > hg > nginx-mail
diff src/http/modules/ngx_http_limit_req_module.c @ 520:549994537f15 NGINX_0_7_52
nginx 0.7.52
*) Feature: the first native Windows binary release.
*) Bugfix: in processing HEAD method while caching.
*) Bugfix: in processing the "If-Modified-Since", "If-Range", etc.
client request header lines while caching.
*) Bugfix: now the "Set-Cookie" and "P3P" header lines are hidden in
cacheable responses.
*) Bugfix: if nginx was built with the ngx_http_perl_module and with a
perl which supports threads, then during a master process exit the
message "panic: MUTEX_LOCK" might be issued.
*) Bugfix: nginx could not be built --without-http-cache; the bug had
appeared in 0.7.48.
*) Bugfix: nginx could not be built on platforms different from i386,
amd64, sparc, and ppc; the bug had appeared in 0.7.42.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 20 Apr 2009 00:00:00 +0400 |
parents | 56baf312c1b5 |
children | f39b9e29530d |
line wrap: on
line diff
--- a/src/http/modules/ngx_http_limit_req_module.c +++ b/src/http/modules/ngx_http_limit_req_module.c @@ -10,30 +10,39 @@ typedef struct { - u_char color; - u_char dummy; - u_short len; - ngx_queue_t queue; - ngx_msec_t last; - ngx_uint_t excess; /* integer value, 1 corresponds to 0.001 r/s */ - u_char data[1]; + u_char color; + u_char dummy; + u_short len; + ngx_queue_t queue; + ngx_msec_t last; + /* integer value, 1 corresponds to 0.001 r/s */ + ngx_uint_t excess; + u_char data[1]; } ngx_http_limit_req_node_t; typedef struct { - ngx_rbtree_t *rbtree; - ngx_queue_t *queue; - ngx_slab_pool_t *shpool; - ngx_uint_t rate; /* integer value, 1 corresponds to 0.001 r/s */ - ngx_int_t index; - ngx_str_t var; + ngx_rbtree_t rbtree; + ngx_rbtree_node_t sentinel; + ngx_queue_t queue; +} ngx_http_limit_req_shctx_t; + + +typedef struct { + ngx_http_limit_req_shctx_t *sh; + ngx_slab_pool_t *shpool; + /* integer value, 1 corresponds to 0.001 r/s */ + ngx_uint_t rate; + ngx_int_t index; + ngx_str_t var; } ngx_http_limit_req_ctx_t; typedef struct { - ngx_shm_zone_t *shm_zone; - ngx_uint_t burst; /* integer value, 1 corresponds to 0.001 r/s */ - ngx_uint_t nodelay;/* unsigned nodelay:1 */ + ngx_shm_zone_t *shm_zone; + /* integer value, 1 corresponds to 0.001 r/s */ + ngx_uint_t burst; + ngx_uint_t nodelay;/* unsigned nodelay:1 */ } ngx_http_limit_req_conf_t; @@ -163,7 +172,7 @@ ngx_http_limit_req_handler(ngx_http_requ if (lr) { ngx_queue_remove(&lr->queue); - ngx_queue_insert_head(ctx->queue, &lr->queue); + ngx_queue_insert_head(&ctx->sh->queue, &lr->queue); excess = lr->excess; @@ -179,7 +188,7 @@ ngx_http_limit_req_handler(ngx_http_requ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "limiting requests, excess: %ui.%03ui by zone \"%V\"", - excess / 1000, excess % 1000, &lrcf->shm_zone->name); + excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name); return NGX_HTTP_SERVICE_UNAVAILABLE; } @@ -193,7 +202,7 @@ ngx_http_limit_req_handler(ngx_http_requ ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, "delaying request, excess: %ui.%03ui, by zone \"%V\"", - excess / 1000, excess % 1000, &lrcf->shm_zone->name); + excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name); if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; @@ -239,9 +248,9 @@ ngx_http_limit_req_handler(ngx_http_requ lr->excess = 0; ngx_memcpy(lr->data, vv->data, len); - ngx_rbtree_insert(ctx->rbtree, node); + ngx_rbtree_insert(&ctx->sh->rbtree, node); - ngx_queue_insert_head(ctx->queue, &lr->queue); + ngx_queue_insert_head(&ctx->sh->queue, &lr->queue); done: @@ -324,8 +333,8 @@ ngx_http_limit_req_lookup(ngx_http_limit ctx = lrcf->shm_zone->data; - node = ctx->rbtree->root; - sentinel = ctx->rbtree->sentinel; + node = ctx->sh->rbtree.root; + sentinel = ctx->sh->rbtree.sentinel; while (node != sentinel) { @@ -411,11 +420,11 @@ ngx_http_limit_req_expire(ngx_http_limit while (n < 3) { - if (ngx_queue_empty(ctx->queue)) { + if (ngx_queue_empty(&ctx->sh->queue)) { return; } - q = ngx_queue_last(ctx->queue); + q = ngx_queue_last(&ctx->sh->queue); lr = ngx_queue_data(q, ngx_http_limit_req_node_t, queue); @@ -440,7 +449,7 @@ ngx_http_limit_req_expire(ngx_http_limit node = (ngx_rbtree_node_t *) ((u_char *) lr - offsetof(ngx_rbtree_node_t, color)); - ngx_rbtree_delete(ctx->rbtree, node); + ngx_rbtree_delete(&ctx->sh->rbtree, node); ngx_slab_free_locked(ctx->shpool, node); } @@ -453,7 +462,6 @@ ngx_http_limit_req_init_zone(ngx_shm_zon ngx_http_limit_req_ctx_t *octx = data; size_t len; - ngx_rbtree_node_t *sentinel; ngx_http_limit_req_ctx_t *ctx; ctx = shm_zone->data; @@ -463,12 +471,11 @@ ngx_http_limit_req_init_zone(ngx_shm_zon ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0, "limit_req \"%V\" uses the \"%V\" variable " "while previously it used the \"%V\" variable", - &shm_zone->name, &ctx->var, &octx->var); + &shm_zone->shm.name, &ctx->var, &octx->var); return NGX_ERROR; } - ctx->rbtree = octx->rbtree; - ctx->queue = octx->queue; + ctx->sh = octx->sh; ctx->shpool = octx->shpool; return NGX_OK; @@ -476,27 +483,25 @@ ngx_http_limit_req_init_zone(ngx_shm_zon ctx->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; - ctx->rbtree = ngx_slab_alloc(ctx->shpool, sizeof(ngx_rbtree_t)); - if (ctx->rbtree == NULL) { - return NGX_ERROR; + if (shm_zone->shm.exists) { + ctx->sh = ctx->shpool->data; + + return NGX_OK; } - sentinel = ngx_slab_alloc(ctx->shpool, sizeof(ngx_rbtree_node_t)); - if (sentinel == NULL) { + ctx->sh = ngx_slab_alloc(ctx->shpool, sizeof(ngx_http_limit_req_shctx_t)); + if (ctx->sh == NULL) { return NGX_ERROR; } - ngx_rbtree_init(ctx->rbtree, sentinel, + ctx->shpool->data = ctx->sh; + + ngx_rbtree_init(&ctx->sh->rbtree, &ctx->sh->sentinel, ngx_http_limit_req_rbtree_insert_value); - ctx->queue = ngx_slab_alloc(ctx->shpool, sizeof(ngx_queue_t)); - if (ctx->queue == NULL) { - return NGX_ERROR; - } + ngx_queue_init(&ctx->sh->queue); - ngx_queue_init(ctx->queue); - - len = sizeof(" in limit_req zone \"\"") + shm_zone->name.len; + len = sizeof(" in limit_req zone \"\"") + shm_zone->shm.name.len; ctx->shpool->log_ctx = ngx_slab_alloc(ctx->shpool, len); if (ctx->shpool->log_ctx == NULL) { @@ -504,7 +509,7 @@ ngx_http_limit_req_init_zone(ngx_shm_zon } ngx_sprintf(ctx->shpool->log_ctx, " in limit_req zone \"%V\"%Z", - &shm_zone->name); + &shm_zone->shm.name); return NGX_OK; } @@ -574,6 +579,8 @@ ngx_http_limit_req_zone(ngx_conf_t *cf, p = (u_char *) ngx_strchr(name.data, ':'); if (p) { + *p = '\0'; + name.len = p - name.data; p++; @@ -744,7 +751,7 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_c if (lrcf->shm_zone->data == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unknown limit_req_zone \"%V\"", - &lrcf->shm_zone->name); + &lrcf->shm_zone->shm.name); return NGX_CONF_ERROR; }