69 static void *ngx_http_limit_req_create_conf(
ngx_conf_t *cf);
70 static char *ngx_http_limit_req_merge_conf(
ngx_conf_t *cf,
void *parent,
97 ngx_http_limit_req_zone,
114 &ngx_http_limit_req_log_levels },
121 &ngx_http_limit_req_status_bounds },
129 ngx_http_limit_req_init,
137 ngx_http_limit_req_create_conf,
138 ngx_http_limit_req_merge_conf
144 &ngx_http_limit_req_module_ctx,
145 ngx_http_limit_req_commands,
182 #if (NGX_SUPPRESS_WARN)
206 "the value of the \"%V\" variable "
207 "is more than 65535 bytes: \"%v\"",
212 hash = ngx_crc32_short(vv->
data, len);
216 rc = ngx_http_limit_req_lookup(limit, hash, vv->
data, len, &excess,
222 "limit_req[%ui]: %i %ui.%03ui",
223 n, rc, excess / 1000, excess % 1000);
240 "limiting requests, excess: %ui.%03ui by zone \"%V\"",
241 excess / 1000, excess % 1000,
248 if (ctx->
node == NULL) {
270 delay = ngx_http_limit_req_account(limits, n, &excess, &limit);
277 "delaying request, excess: %ui.%03ui, by zone \"%V\"",
334 if (node->
key < temp->
key) {
338 }
else if (node->
key > temp->
key) {
351 if (*p == sentinel) {
360 node->
left = sentinel;
361 node->
right = sentinel;
387 while (node != sentinel) {
389 if (hash < node->key) {
394 if (hash > node->
key) {
436 node = (rc < 0) ? node->
left : node->
right;
445 ngx_http_limit_req_expire(ctx, 1);
450 ngx_http_limit_req_expire(ctx, 0);
462 lr->
len = (u_char) len;
499 if (excess == 0 || (*limit)->nodelay) {
503 ctx = (*limit)->shm_zone->data;
504 max_delay = excess * 1000 / ctx->
rate;
536 if (limits[n].nodelay) {
540 delay = excess * 1000 / ctx->
rate;
542 if (delay > max_delay) {
623 ngx_http_limit_req_init_zone(
ngx_shm_zone_t *shm_zone,
void *data)
630 ctx = shm_zone->
data;
635 "limit_req \"%V\" uses the \"%V\" variable "
636 "while previously it used the \"%V\" variable",
656 if (ctx->
sh == NULL) {
663 ngx_http_limit_req_rbtree_insert_value);
667 len =
sizeof(
" in limit_req zone \"\"") + shm_zone->
shm.
name.
len;
682 ngx_http_limit_req_create_conf(
ngx_conf_t *cf)
705 ngx_http_limit_req_merge_conf(
ngx_conf_t *cf,
void *parent,
void *child)
757 "invalid zone size \"%V\"", &value[i]);
770 "invalid zone size \"%V\"", &value[i]);
776 "zone \"%V\" is too small", &value[i]);
786 p = value[
i].
data + len - 3;
797 rate =
ngx_atoi(value[i].data + 5, len - 5);
800 "invalid rate \"%V\"", &value[i]);
807 if (value[i].data[0] ==
'$') {
828 "invalid parameter \"%V\"", &value[i]);
834 "\"%V\" must have \"zone\" parameter",
841 "no variable is defined for %V \"%V\"",
846 ctx->
rate = rate * 1000 / scale;
849 &ngx_http_limit_req_module);
850 if (shm_zone == NULL) {
854 if (shm_zone->
data) {
855 ctx = shm_zone->
data;
858 "%V \"%V\" is already bound to variable \"%V\"",
863 shm_zone->
init = ngx_http_limit_req_init_zone;
864 shm_zone->
data = ctx;
895 &ngx_http_limit_req_module);
896 if (shm_zone == NULL) {
903 if (
ngx_strncmp(value[i].data,
"burst=", 6) == 0) {
905 burst =
ngx_atoi(value[i].data + 6, value[i].len - 6);
908 "invalid burst rate \"%V\"", &value[i]);
915 if (
ngx_strncmp(value[i].data,
"nodelay", 7) == 0) {
921 "invalid parameter \"%V\"", &value[i]);
925 if (shm_zone == NULL) {
927 "\"%V\" must have \"zone\" parameter",
932 if (shm_zone->
data == NULL) {
934 "unknown limit_req_zone \"%V\"",
941 if (limits == NULL) {
942 if (ngx_array_init(&lrcf->
limits, cf->
pool, 1,
951 if (shm_zone == limits[i].shm_zone) {
952 return "is duplicate";
962 limit->
burst = burst * 1000;
982 *h = ngx_http_limit_req_handler;