annotate src/http/modules/ngx_http_limit_req_module.c @ 4811:21d1e3bcb356

Added three missing checks for NULL after ngx_array_push() calls. Found by Coverity.
author Valentin Bartenev <vbart@nginx.com>
date Wed, 08 Aug 2012 12:03:46 +0000
parents 778ef9c3fd2d
children 949ea3d3cd1a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
2 /*
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
3 * Copyright (C) Igor Sysoev
4412
d620f497c50f Copyright updated.
Maxim Konovalov <maxim@nginx.com>
parents: 4399
diff changeset
4 * Copyright (C) Nginx, Inc.
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
5 */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
6
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
7
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
8 #include <ngx_config.h>
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
9 #include <ngx_core.h>
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
10 #include <ngx_http.h>
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
11
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
12
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
13 typedef struct {
2720
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
14 u_char color;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
15 u_char dummy;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
16 u_short len;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
17 ngx_queue_t queue;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
18 ngx_msec_t last;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
19 /* integer value, 1 corresponds to 0.001 r/s */
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
20 ngx_uint_t excess;
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
21 ngx_uint_t count;
2720
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
22 u_char data[1];
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
23 } ngx_http_limit_req_node_t;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
24
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
25
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
26 typedef struct {
2720
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
27 ngx_rbtree_t rbtree;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
28 ngx_rbtree_node_t sentinel;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
29 ngx_queue_t queue;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
30 } ngx_http_limit_req_shctx_t;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
31
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
32
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
33 typedef struct {
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
34 ngx_http_limit_req_shctx_t *sh;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
35 ngx_slab_pool_t *shpool;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
36 /* integer value, 1 corresponds to 0.001 r/s */
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
37 ngx_uint_t rate;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
38 ngx_int_t index;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
39 ngx_str_t var;
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
40 ngx_http_limit_req_node_t *node;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
41 } ngx_http_limit_req_ctx_t;
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
42
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
43
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
44 typedef struct {
2720
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
45 ngx_shm_zone_t *shm_zone;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
46 /* integer value, 1 corresponds to 0.001 r/s */
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
47 ngx_uint_t burst;
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
48 ngx_uint_t nodelay; /* unsigned nodelay:1 */
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
49 } ngx_http_limit_req_limit_t;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
50
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
51
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
52 typedef struct {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
53 ngx_array_t limits;
3185
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
54 ngx_uint_t limit_log_level;
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
55 ngx_uint_t delay_log_level;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
56 } ngx_http_limit_req_conf_t;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
57
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
58
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
59 static void ngx_http_limit_req_delay(ngx_http_request_t *r);
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
60 static ngx_int_t ngx_http_limit_req_lookup(ngx_http_limit_req_limit_t *limit,
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
61 ngx_uint_t hash, u_char *data, size_t len, ngx_uint_t *ep,
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
62 ngx_uint_t account);
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
63 static ngx_msec_t ngx_http_limit_req_account(ngx_http_limit_req_limit_t *limits,
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
64 ngx_uint_t n, ngx_uint_t *ep, ngx_http_limit_req_limit_t **limit);
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
65 static void ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx,
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
66 ngx_uint_t n);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
67
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
68 static void *ngx_http_limit_req_create_conf(ngx_conf_t *cf);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
69 static char *ngx_http_limit_req_merge_conf(ngx_conf_t *cf, void *parent,
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
70 void *child);
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
71 static char *ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd,
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
72 void *conf);
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
73 static char *ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd,
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
74 void *conf);
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
75 static ngx_int_t ngx_http_limit_req_init(ngx_conf_t *cf);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
76
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
77
3185
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
78 static ngx_conf_enum_t ngx_http_limit_req_log_levels[] = {
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
79 { ngx_string("info"), NGX_LOG_INFO },
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
80 { ngx_string("notice"), NGX_LOG_NOTICE },
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
81 { ngx_string("warn"), NGX_LOG_WARN },
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
82 { ngx_string("error"), NGX_LOG_ERR },
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
83 { ngx_null_string, 0 }
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
84 };
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
85
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
86
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
87 static ngx_command_t ngx_http_limit_req_commands[] = {
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
88
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
89 { ngx_string("limit_req_zone"),
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
90 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE3,
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
91 ngx_http_limit_req_zone,
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
92 0,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
93 0,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
94 NULL },
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
95
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
96 { ngx_string("limit_req"),
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
97 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
98 ngx_http_limit_req,
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
99 NGX_HTTP_LOC_CONF_OFFSET,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
100 0,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
101 NULL },
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
102
3185
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
103 { ngx_string("limit_req_log_level"),
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
104 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
105 ngx_conf_set_enum_slot,
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
106 NGX_HTTP_LOC_CONF_OFFSET,
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
107 offsetof(ngx_http_limit_req_conf_t, limit_log_level),
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
108 &ngx_http_limit_req_log_levels },
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
109
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
110 ngx_null_command
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
111 };
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
112
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
113
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
114 static ngx_http_module_t ngx_http_limit_req_module_ctx = {
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
115 NULL, /* preconfiguration */
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
116 ngx_http_limit_req_init, /* postconfiguration */
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
117
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
118 NULL, /* create main configuration */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
119 NULL, /* init main configuration */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
120
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
121 NULL, /* create server configuration */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
122 NULL, /* merge server configuration */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
123
4499
778ef9c3fd2d Fixed spelling in single-line comments.
Ruslan Ermilov <ru@nginx.com>
parents: 4497
diff changeset
124 ngx_http_limit_req_create_conf, /* create location configuration */
778ef9c3fd2d Fixed spelling in single-line comments.
Ruslan Ermilov <ru@nginx.com>
parents: 4497
diff changeset
125 ngx_http_limit_req_merge_conf /* merge location configuration */
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
126 };
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
127
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
128
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
129 ngx_module_t ngx_http_limit_req_module = {
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
130 NGX_MODULE_V1,
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
131 &ngx_http_limit_req_module_ctx, /* module context */
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
132 ngx_http_limit_req_commands, /* module directives */
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
133 NGX_HTTP_MODULE, /* module type */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
134 NULL, /* init master */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
135 NULL, /* init module */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
136 NULL, /* init process */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
137 NULL, /* init thread */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
138 NULL, /* exit thread */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
139 NULL, /* exit process */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
140 NULL, /* exit master */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
141 NGX_MODULE_V1_PADDING
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
142 };
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
143
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
144
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
145 static ngx_int_t
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
146 ngx_http_limit_req_handler(ngx_http_request_t *r)
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
147 {
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
148 size_t len;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
149 uint32_t hash;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
150 ngx_int_t rc;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
151 ngx_uint_t n, excess;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
152 ngx_msec_t delay;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
153 ngx_http_variable_value_t *vv;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
154 ngx_http_limit_req_ctx_t *ctx;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
155 ngx_http_limit_req_conf_t *lrcf;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
156 ngx_http_limit_req_limit_t *limit, *limits;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
157
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
158 if (r->main->limit_req_set) {
984
dd128232e6ba count connection once per request
Igor Sysoev <igor@sysoev.ru>
parents: 981
diff changeset
159 return NGX_DECLINED;
dd128232e6ba count connection once per request
Igor Sysoev <igor@sysoev.ru>
parents: 981
diff changeset
160 }
dd128232e6ba count connection once per request
Igor Sysoev <igor@sysoev.ru>
parents: 981
diff changeset
161
2374
7b11f9a1bfe1 rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents: 2313
diff changeset
162 lrcf = ngx_http_get_module_loc_conf(r, ngx_http_limit_req_module);
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
163 limits = lrcf->limits.elts;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
164
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
165 excess = 0;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
166
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
167 rc = NGX_DECLINED;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
168
4424
aacd7356c197 Limit req: unbreak compilation with MSVC.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4420
diff changeset
169 #if (NGX_SUPPRESS_WARN)
aacd7356c197 Limit req: unbreak compilation with MSVC.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4420
diff changeset
170 limit = NULL;
aacd7356c197 Limit req: unbreak compilation with MSVC.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4420
diff changeset
171 #endif
aacd7356c197 Limit req: unbreak compilation with MSVC.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4420
diff changeset
172
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
173 for (n = 0; n < lrcf->limits.nelts; n++) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
174
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
175 limit = &limits[n];
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
176
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
177 ctx = limit->shm_zone->data;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
178
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
179 vv = ngx_http_get_indexed_variable(r, ctx->index);
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
180
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
181 if (vv == NULL || vv->not_found) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
182 continue;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
183 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
184
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
185 len = vv->len;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
186
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
187 if (len == 0) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
188 continue;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
189 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
190
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
191 if (len > 65535) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
192 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
193 "the value of the \"%V\" variable "
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
194 "is more than 65535 bytes: \"%v\"",
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
195 &ctx->var, vv);
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
196 continue;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
197 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
198
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
199 hash = ngx_crc32_short(vv->data, len);
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
200
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
201 ngx_shmtx_lock(&ctx->shpool->mutex);
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
202
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
203 rc = ngx_http_limit_req_lookup(limit, hash, vv->data, len, &excess,
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
204 (n == lrcf->limits.nelts - 1));
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
205
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
206 ngx_shmtx_unlock(&ctx->shpool->mutex);
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
207
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
208 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
209 "limit_req[%ui]: %i %ui.%03ui",
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
210 n, rc, excess / 1000, excess % 1000);
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
211
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
212 if (rc != NGX_AGAIN) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
213 break;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
214 }
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
215 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
216
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
217 if (rc == NGX_DECLINED) {
1011
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
218 return NGX_DECLINED;
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
219 }
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
220
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
221 r->main->limit_req_set = 1;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
222
4418
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
223 if (rc == NGX_BUSY || rc == NGX_ERROR) {
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
224
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
225 if (rc == NGX_BUSY) {
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
226 ngx_log_error(lrcf->limit_log_level, r->connection->log, 0,
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
227 "limiting requests, excess: %ui.%03ui by zone \"%V\"",
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
228 excess / 1000, excess % 1000,
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
229 &limit->shm_zone->shm.name);
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
230 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
231
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
232 while (n--) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
233 ctx = limits[n].shm_zone->data;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
234
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
235 if (ctx->node == NULL) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
236 continue;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
237 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
238
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
239 ngx_shmtx_lock(&ctx->shpool->mutex);
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
240
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
241 ctx->node->count--;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
242
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
243 ngx_shmtx_unlock(&ctx->shpool->mutex);
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
244
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
245 ctx->node = NULL;
4418
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
246 }
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
247
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
248 return NGX_HTTP_SERVICE_UNAVAILABLE;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
249 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
250
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
251 /* rc == NGX_AGAIN || rc == NGX_OK */
2300
159136c9808d *) correct leaky bucket implementation
Igor Sysoev <igor@sysoev.ru>
parents: 2294
diff changeset
252
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
253 if (rc == NGX_AGAIN) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
254 excess = 0;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
255 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
256
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
257 delay = ngx_http_limit_req_account(limits, n, &excess, &limit);
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
258
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
259 if (!delay) {
3780
d94d7104f598 change order of limit_req lookup result processing
Igor Sysoev <igor@sysoev.ru>
parents: 3779
diff changeset
260 return NGX_DECLINED;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
261 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
262
3780
d94d7104f598 change order of limit_req lookup result processing
Igor Sysoev <igor@sysoev.ru>
parents: 3779
diff changeset
263 ngx_log_error(lrcf->delay_log_level, r->connection->log, 0,
d94d7104f598 change order of limit_req lookup result processing
Igor Sysoev <igor@sysoev.ru>
parents: 3779
diff changeset
264 "delaying request, excess: %ui.%03ui, by zone \"%V\"",
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
265 excess / 1000, excess % 1000, &limit->shm_zone->shm.name);
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
266
3780
d94d7104f598 change order of limit_req lookup result processing
Igor Sysoev <igor@sysoev.ru>
parents: 3779
diff changeset
267 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
d94d7104f598 change order of limit_req lookup result processing
Igor Sysoev <igor@sysoev.ru>
parents: 3779
diff changeset
268 return NGX_HTTP_INTERNAL_SERVER_ERROR;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
269 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
270
3780
d94d7104f598 change order of limit_req lookup result processing
Igor Sysoev <igor@sysoev.ru>
parents: 3779
diff changeset
271 r->read_event_handler = ngx_http_test_reading;
d94d7104f598 change order of limit_req lookup result processing
Igor Sysoev <igor@sysoev.ru>
parents: 3779
diff changeset
272 r->write_event_handler = ngx_http_limit_req_delay;
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
273 ngx_add_timer(r->connection->write, delay);
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
274
3780
d94d7104f598 change order of limit_req lookup result processing
Igor Sysoev <igor@sysoev.ru>
parents: 3779
diff changeset
275 return NGX_AGAIN;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
276 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
277
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
278
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
279 static void
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
280 ngx_http_limit_req_delay(ngx_http_request_t *r)
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
281 {
2972
c5ad288f851d fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
282 ngx_event_t *wev;
c5ad288f851d fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
283
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
284 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2973
70c8b2d28d1d style fix
Igor Sysoev <igor@sysoev.ru>
parents: 2972
diff changeset
285 "limit_req delay");
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
286
2972
c5ad288f851d fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
287 wev = r->connection->write;
c5ad288f851d fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
288
c5ad288f851d fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
289 if (!wev->timedout) {
c5ad288f851d fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
290
c5ad288f851d fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
291 if (ngx_handle_write_event(wev, 0) != NGX_OK) {
c5ad288f851d fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
292 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
c5ad288f851d fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
293 }
c5ad288f851d fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
294
c5ad288f851d fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
295 return;
c5ad288f851d fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
296 }
c5ad288f851d fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
297
c5ad288f851d fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
298 wev->timedout = 0;
c5ad288f851d fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
299
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
300 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
301 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
302 return;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
303 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
304
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
305 r->read_event_handler = ngx_http_block_reading;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
306 r->write_event_handler = ngx_http_core_run_phases;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
307
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
308 ngx_http_core_run_phases(r);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
309 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
310
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
311
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
312 static void
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
313 ngx_http_limit_req_rbtree_insert_value(ngx_rbtree_node_t *temp,
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
314 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
315 {
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
316 ngx_rbtree_node_t **p;
2374
7b11f9a1bfe1 rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents: 2313
diff changeset
317 ngx_http_limit_req_node_t *lrn, *lrnt;
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
318
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
319 for ( ;; ) {
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
320
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
321 if (node->key < temp->key) {
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
322
1743
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
323 p = &temp->left;
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
324
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
325 } else if (node->key > temp->key) {
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
326
1743
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
327 p = &temp->right;
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
328
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
329 } else { /* node->key == temp->key */
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
330
2374
7b11f9a1bfe1 rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents: 2313
diff changeset
331 lrn = (ngx_http_limit_req_node_t *) &node->color;
7b11f9a1bfe1 rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents: 2313
diff changeset
332 lrnt = (ngx_http_limit_req_node_t *) &temp->color;
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
333
2374
7b11f9a1bfe1 rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents: 2313
diff changeset
334 p = (ngx_memn2cmp(lrn->data, lrnt->data, lrn->len, lrnt->len) < 0)
1743
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
335 ? &temp->left : &temp->right;
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
336 }
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
337
1743
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
338 if (*p == sentinel) {
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
339 break;
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
340 }
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
341
1743
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
342 temp = *p;
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
343 }
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
344
1743
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
345 *p = node;
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
346 node->parent = temp;
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
347 node->left = sentinel;
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
348 node->right = sentinel;
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
349 ngx_rbt_red(node);
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
350 }
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
351
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
352
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
353 static ngx_int_t
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
354 ngx_http_limit_req_lookup(ngx_http_limit_req_limit_t *limit, ngx_uint_t hash,
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
355 u_char *data, size_t len, ngx_uint_t *ep, ngx_uint_t account)
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
356 {
4418
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
357 size_t size;
2313
b56a9ba4824d use integer instead of float
Igor Sysoev <igor@sysoev.ru>
parents: 2312
diff changeset
358 ngx_int_t rc, excess;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
359 ngx_time_t *tp;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
360 ngx_msec_t now;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
361 ngx_msec_int_t ms;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
362 ngx_rbtree_node_t *node, *sentinel;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
363 ngx_http_limit_req_ctx_t *ctx;
2374
7b11f9a1bfe1 rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents: 2313
diff changeset
364 ngx_http_limit_req_node_t *lr;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
365
4418
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
366 tp = ngx_timeofday();
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
367 now = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
368
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
369 ctx = limit->shm_zone->data;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
370
2720
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
371 node = ctx->sh->rbtree.root;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
372 sentinel = ctx->sh->rbtree.sentinel;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
373
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
374 while (node != sentinel) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
375
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
376 if (hash < node->key) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
377 node = node->left;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
378 continue;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
379 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
380
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
381 if (hash > node->key) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
382 node = node->right;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
383 continue;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
384 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
385
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
386 /* hash == node->key */
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
387
4497
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
388 lr = (ngx_http_limit_req_node_t *) &node->color;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
389
4497
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
390 rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len);
3191
30f841e2536d fix r3184
Igor Sysoev <igor@sysoev.ru>
parents: 3185
diff changeset
391
4497
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
392 if (rc == 0) {
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
393 ngx_queue_remove(&lr->queue);
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
394 ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
3183
b87542338ac3 make limit_req to conform to the leaky bucket algorithm
Igor Sysoev <igor@sysoev.ru>
parents: 2973
diff changeset
395
4497
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
396 ms = (ngx_msec_int_t) (now - lr->last);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
397
4497
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
398 excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
399
4497
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
400 if (excess < 0) {
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
401 excess = 0;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
402 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
403
4497
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
404 *ep = excess;
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
405
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
406 if ((ngx_uint_t) excess > limit->burst) {
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
407 return NGX_BUSY;
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
408 }
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
409
4497
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
410 if (account) {
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
411 lr->excess = excess;
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
412 lr->last = now;
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
413 return NGX_OK;
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
414 }
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
415
4497
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
416 lr->count++;
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
417
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
418 ctx->node = lr;
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
419
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
420 return NGX_AGAIN;
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
421 }
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
422
95ab6658654a Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4424
diff changeset
423 node = (rc < 0) ? node->left : node->right;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
424 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
425
3779
57aecfdcac3d an excess was logged as 0.000 if requests were limited without delay:
Igor Sysoev <igor@sysoev.ru>
parents: 3525
diff changeset
426 *ep = 0;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
427
4418
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
428 size = offsetof(ngx_rbtree_node_t, color)
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
429 + offsetof(ngx_http_limit_req_node_t, data)
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
430 + len;
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
431
4419
7084faa7a4b4 Limit req: number of cleanup calls reduced.
Valentin Bartenev <vbart@nginx.com>
parents: 4418
diff changeset
432 ngx_http_limit_req_expire(ctx, 1);
7084faa7a4b4 Limit req: number of cleanup calls reduced.
Valentin Bartenev <vbart@nginx.com>
parents: 4418
diff changeset
433
4418
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
434 node = ngx_slab_alloc_locked(ctx->shpool, size);
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
435
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
436 if (node == NULL) {
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
437 ngx_http_limit_req_expire(ctx, 0);
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
438
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
439 node = ngx_slab_alloc_locked(ctx->shpool, size);
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
440 if (node == NULL) {
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
441 return NGX_ERROR;
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
442 }
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
443 }
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
444
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
445 node->key = hash;
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
446
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
447 ngx_rbtree_insert(&ctx->sh->rbtree, node);
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
448
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
449 lr = (ngx_http_limit_req_node_t *) &node->color;
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
450
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
451 ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
452
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
453 lr->len = (u_char) len;
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
454 lr->excess = 0;
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
455
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
456 ngx_memcpy(lr->data, data, len);
aac79fc948cc Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents: 4417
diff changeset
457
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
458 if (account) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
459 lr->last = now;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
460 lr->count = 0;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
461 return NGX_OK;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
462 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
463
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
464 lr->last = 0;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
465 lr->count = 1;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
466
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
467 ctx->node = lr;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
468
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
469 return NGX_AGAIN;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
470 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
471
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
472
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
473 static ngx_msec_t
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
474 ngx_http_limit_req_account(ngx_http_limit_req_limit_t *limits, ngx_uint_t n,
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
475 ngx_uint_t *ep, ngx_http_limit_req_limit_t **limit)
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
476 {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
477 ngx_int_t excess;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
478 ngx_time_t *tp;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
479 ngx_msec_t now, delay, max_delay;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
480 ngx_msec_int_t ms;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
481 ngx_http_limit_req_ctx_t *ctx;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
482 ngx_http_limit_req_node_t *lr;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
483
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
484 excess = *ep;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
485
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
486 if (excess == 0 || (*limit)->nodelay) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
487 max_delay = 0;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
488
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
489 } else {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
490 ctx = (*limit)->shm_zone->data;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
491 max_delay = excess * 1000 / ctx->rate;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
492 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
493
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
494 while (n--) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
495 ctx = limits[n].shm_zone->data;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
496 lr = ctx->node;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
497
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
498 if (lr == NULL) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
499 continue;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
500 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
501
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
502 ngx_shmtx_lock(&ctx->shpool->mutex);
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
503
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
504 tp = ngx_timeofday();
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
505
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
506 now = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
507 ms = (ngx_msec_int_t) (now - lr->last);
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
508
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
509 excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
510
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
511 if (excess < 0) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
512 excess = 0;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
513 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
514
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
515 lr->last = now;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
516 lr->excess = excess;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
517 lr->count--;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
518
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
519 ngx_shmtx_unlock(&ctx->shpool->mutex);
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
520
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
521 ctx->node = NULL;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
522
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
523 if (limits[n].nodelay) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
524 continue;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
525 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
526
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
527 delay = excess * 1000 / ctx->rate;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
528
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
529 if (delay > max_delay) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
530 max_delay = delay;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
531 *ep = excess;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
532 *limit = &limits[n];
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
533 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
534 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
535
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
536 return max_delay;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
537 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
538
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
539
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
540 static void
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
541 ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, ngx_uint_t n)
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
542 {
2313
b56a9ba4824d use integer instead of float
Igor Sysoev <igor@sysoev.ru>
parents: 2312
diff changeset
543 ngx_int_t excess;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
544 ngx_time_t *tp;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
545 ngx_msec_t now;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
546 ngx_queue_t *q;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
547 ngx_msec_int_t ms;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
548 ngx_rbtree_node_t *node;
2374
7b11f9a1bfe1 rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents: 2313
diff changeset
549 ngx_http_limit_req_node_t *lr;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
550
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
551 tp = ngx_timeofday();
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
552
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
553 now = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
554
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
555 /*
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
556 * n == 1 deletes one or two zero rate entries
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
557 * n == 0 deletes oldest entry by force
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
558 * and one or two zero rate entries
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
559 */
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
560
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
561 while (n < 3) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
562
2720
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
563 if (ngx_queue_empty(&ctx->sh->queue)) {
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
564 return;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
565 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
566
2720
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
567 q = ngx_queue_last(&ctx->sh->queue);
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
568
2374
7b11f9a1bfe1 rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents: 2313
diff changeset
569 lr = ngx_queue_data(q, ngx_http_limit_req_node_t, queue);
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
570
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
571 if (lr->count) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
572
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
573 /*
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
574 * There is not much sense in looking further,
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
575 * because we bump nodes on the lookup stage.
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
576 */
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
577
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
578 return;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
579 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
580
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
581 if (n++ != 0) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
582
2374
7b11f9a1bfe1 rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents: 2313
diff changeset
583 ms = (ngx_msec_int_t) (now - lr->last);
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
584 ms = ngx_abs(ms);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
585
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
586 if (ms < 60000) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
587 return;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
588 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
589
2374
7b11f9a1bfe1 rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents: 2313
diff changeset
590 excess = lr->excess - ctx->rate * ms / 1000;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
591
2313
b56a9ba4824d use integer instead of float
Igor Sysoev <igor@sysoev.ru>
parents: 2312
diff changeset
592 if (excess > 0) {
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
593 return;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
594 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
595 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
596
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
597 ngx_queue_remove(q);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
598
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
599 node = (ngx_rbtree_node_t *)
2374
7b11f9a1bfe1 rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents: 2313
diff changeset
600 ((u_char *) lr - offsetof(ngx_rbtree_node_t, color));
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
601
2720
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
602 ngx_rbtree_delete(&ctx->sh->rbtree, node);
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
603
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
604 ngx_slab_free_locked(ctx->shpool, node);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
605 }
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
606 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
607
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
608
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
609 static ngx_int_t
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
610 ngx_http_limit_req_init_zone(ngx_shm_zone_t *shm_zone, void *data)
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
611 {
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
612 ngx_http_limit_req_ctx_t *octx = data;
993
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
613
2611
2bce3f6416c6 improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents: 2376
diff changeset
614 size_t len;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
615 ngx_http_limit_req_ctx_t *ctx;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
616
993
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
617 ctx = shm_zone->data;
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
618
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
619 if (octx) {
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
620 if (ngx_strcmp(ctx->var.data, octx->var.data) != 0) {
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
621 ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0,
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
622 "limit_req \"%V\" uses the \"%V\" variable "
993
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
623 "while previously it used the \"%V\" variable",
2716
d5896f6608e8 move zone name from ngx_shm_zone_t to ngx_shm_t to use Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2612
diff changeset
624 &shm_zone->shm.name, &ctx->var, &octx->var);
993
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
625 return NGX_ERROR;
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
626 }
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
627
2720
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
628 ctx->sh = octx->sh;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
629 ctx->shpool = octx->shpool;
993
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
630
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
631 return NGX_OK;
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
632 }
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
633
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
634 ctx->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
635
2720
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
636 if (shm_zone->shm.exists) {
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
637 ctx->sh = ctx->shpool->data;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
638
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
639 return NGX_OK;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
640 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
641
2720
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
642 ctx->sh = ngx_slab_alloc(ctx->shpool, sizeof(ngx_http_limit_req_shctx_t));
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
643 if (ctx->sh == NULL) {
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
644 return NGX_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
645 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
646
2720
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
647 ctx->shpool->data = ctx->sh;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
648
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
649 ngx_rbtree_init(&ctx->sh->rbtree, &ctx->sh->sentinel,
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
650 ngx_http_limit_req_rbtree_insert_value);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
651
2720
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
652 ngx_queue_init(&ctx->sh->queue);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
653
2716
d5896f6608e8 move zone name from ngx_shm_zone_t to ngx_shm_t to use Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2612
diff changeset
654 len = sizeof(" in limit_req zone \"\"") + shm_zone->shm.name.len;
2611
2bce3f6416c6 improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents: 2376
diff changeset
655
2bce3f6416c6 improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents: 2376
diff changeset
656 ctx->shpool->log_ctx = ngx_slab_alloc(ctx->shpool, len);
2bce3f6416c6 improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents: 2376
diff changeset
657 if (ctx->shpool->log_ctx == NULL) {
2bce3f6416c6 improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents: 2376
diff changeset
658 return NGX_ERROR;
2bce3f6416c6 improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents: 2376
diff changeset
659 }
2bce3f6416c6 improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents: 2376
diff changeset
660
2bce3f6416c6 improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents: 2376
diff changeset
661 ngx_sprintf(ctx->shpool->log_ctx, " in limit_req zone \"%V\"%Z",
2716
d5896f6608e8 move zone name from ngx_shm_zone_t to ngx_shm_t to use Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2612
diff changeset
662 &shm_zone->shm.name);
2611
2bce3f6416c6 improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents: 2376
diff changeset
663
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
664 return NGX_OK;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
665 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
666
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
667
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
668 static void *
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
669 ngx_http_limit_req_create_conf(ngx_conf_t *cf)
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
670 {
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
671 ngx_http_limit_req_conf_t *conf;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
672
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
673 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_req_conf_t));
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
674 if (conf == NULL) {
2912
c7d57b539248 return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents: 2720
diff changeset
675 return NULL;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
676 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
677
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
678 /*
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
679 * set by ngx_pcalloc():
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
680 *
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
681 * conf->limits.elts = NULL;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
682 */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
683
3185
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
684 conf->limit_log_level = NGX_CONF_UNSET_UINT;
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
685
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
686 return conf;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
687 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
688
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
689
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
690 static char *
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
691 ngx_http_limit_req_merge_conf(ngx_conf_t *cf, void *parent, void *child)
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
692 {
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
693 ngx_http_limit_req_conf_t *prev = parent;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
694 ngx_http_limit_req_conf_t *conf = child;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
695
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
696 if (conf->limits.elts == NULL) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
697 conf->limits = prev->limits;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
698 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
699
3185
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
700 ngx_conf_merge_uint_value(conf->limit_log_level, prev->limit_log_level,
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
701 NGX_LOG_ERR);
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
702
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
703 conf->delay_log_level = (conf->limit_log_level == NGX_LOG_INFO) ?
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
704 NGX_LOG_INFO : conf->limit_log_level + 1;
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
705
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
706 return NGX_CONF_OK;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
707 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
708
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
709
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
710 static char *
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
711 ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
712 {
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
713 u_char *p;
4417
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
714 size_t len;
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
715 ssize_t size;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
716 ngx_str_t *value, name, s;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
717 ngx_int_t rate, scale;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
718 ngx_uint_t i;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
719 ngx_shm_zone_t *shm_zone;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
720 ngx_http_limit_req_ctx_t *ctx;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
721
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
722 value = cf->args->elts;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
723
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
724 ctx = NULL;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
725 size = 0;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
726 rate = 1;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
727 scale = 1;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
728 name.len = 0;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
729
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
730 for (i = 1; i < cf->args->nelts; i++) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
731
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
732 if (ngx_strncmp(value[i].data, "zone=", 5) == 0) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
733
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
734 name.data = value[i].data + 5;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
735
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
736 p = (u_char *) ngx_strchr(name.data, ':');
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
737
4417
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
738 if (p == NULL) {
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
739 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
740 "invalid zone size \"%V\"", &value[i]);
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
741 return NGX_CONF_ERROR;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
742 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
743
4417
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
744 name.len = p - name.data;
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
745
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
746 s.data = p + 1;
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
747 s.len = value[i].data + value[i].len - s.data;
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
748
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
749 size = ngx_parse_size(&s);
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
750
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
751 if (size == NGX_ERROR) {
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
752 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
753 "invalid zone size \"%V\"", &value[i]);
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
754 return NGX_CONF_ERROR;
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
755 }
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
756
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
757 if (size < (ssize_t) (8 * ngx_pagesize)) {
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
758 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
759 "zone \"%V\" is too small", &value[i]);
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
760 return NGX_CONF_ERROR;
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
761 }
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
762
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
763 continue;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
764 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
765
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
766 if (ngx_strncmp(value[i].data, "rate=", 5) == 0) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
767
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
768 len = value[i].len;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
769 p = value[i].data + len - 3;
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
770
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
771 if (ngx_strncmp(p, "r/s", 3) == 0) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
772 scale = 1;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
773 len -= 3;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
774
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
775 } else if (ngx_strncmp(p, "r/m", 3) == 0) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
776 scale = 60;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
777 len -= 3;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
778 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
779
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
780 rate = ngx_atoi(value[i].data + 5, len - 5);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
781 if (rate <= NGX_ERROR) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
782 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
783 "invalid rate \"%V\"", &value[i]);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
784 return NGX_CONF_ERROR;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
785 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
786
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
787 continue;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
788 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
789
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
790 if (value[i].data[0] == '$') {
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
791
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
792 value[i].len--;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
793 value[i].data++;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
794
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
795 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_req_ctx_t));
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
796 if (ctx == NULL) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
797 return NGX_CONF_ERROR;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
798 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
799
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
800 ctx->index = ngx_http_get_variable_index(cf, &value[i]);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
801 if (ctx->index == NGX_ERROR) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
802 return NGX_CONF_ERROR;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
803 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
804
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
805 ctx->var = value[i];
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
806
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
807 continue;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
808 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
809
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
810 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
811 "invalid parameter \"%V\"", &value[i]);
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
812 return NGX_CONF_ERROR;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
813 }
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
814
4417
9e9d2e06f933 Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents: 4416
diff changeset
815 if (name.len == 0) {
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
816 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
817 "\"%V\" must have \"zone\" parameter",
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
818 &cmd->name);
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
819 return NGX_CONF_ERROR;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
820 }
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
821
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
822 if (ctx == NULL) {
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
823 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4416
8156a9bfc044 Limit req: error messages fixed.
Valentin Bartenev <vbart@nginx.com>
parents: 4412
diff changeset
824 "no variable is defined for %V \"%V\"",
8156a9bfc044 Limit req: error messages fixed.
Valentin Bartenev <vbart@nginx.com>
parents: 4412
diff changeset
825 &cmd->name, &name);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
826 return NGX_CONF_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
827 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
828
2313
b56a9ba4824d use integer instead of float
Igor Sysoev <igor@sysoev.ru>
parents: 2312
diff changeset
829 ctx->rate = rate * 1000 / scale;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
830
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
831 shm_zone = ngx_shared_memory_add(cf, &name, size,
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
832 &ngx_http_limit_req_module);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
833 if (shm_zone == NULL) {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
834 return NGX_CONF_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
835 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
836
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
837 if (shm_zone->data) {
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
838 ctx = shm_zone->data;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
839
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
840 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4416
8156a9bfc044 Limit req: error messages fixed.
Valentin Bartenev <vbart@nginx.com>
parents: 4412
diff changeset
841 "%V \"%V\" is already bound to variable \"%V\"",
8156a9bfc044 Limit req: error messages fixed.
Valentin Bartenev <vbart@nginx.com>
parents: 4412
diff changeset
842 &cmd->name, &name, &ctx->var);
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
843 return NGX_CONF_ERROR;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
844 }
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
845
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
846 shm_zone->init = ngx_http_limit_req_init_zone;
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
847 shm_zone->data = ctx;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
848
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
849 return NGX_CONF_OK;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
850 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
851
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
852
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
853 static char *
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
854 ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
855 {
2374
7b11f9a1bfe1 rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents: 2313
diff changeset
856 ngx_http_limit_req_conf_t *lrcf = conf;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
857
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
858 ngx_int_t burst;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
859 ngx_str_t *value, s;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
860 ngx_uint_t i, nodelay;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
861 ngx_shm_zone_t *shm_zone;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
862 ngx_http_limit_req_limit_t *limit, *limits;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
863
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
864 value = cf->args->elts;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
865
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
866 shm_zone = NULL;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
867 burst = 0;
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
868 nodelay = 0;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
869
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
870 for (i = 1; i < cf->args->nelts; i++) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
871
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
872 if (ngx_strncmp(value[i].data, "zone=", 5) == 0) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
873
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
874 s.len = value[i].len - 5;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
875 s.data = value[i].data + 5;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
876
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
877 shm_zone = ngx_shared_memory_add(cf, &s, 0,
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
878 &ngx_http_limit_req_module);
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
879 if (shm_zone == NULL) {
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
880 return NGX_CONF_ERROR;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
881 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
882
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
883 continue;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
884 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
885
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
886 if (ngx_strncmp(value[i].data, "burst=", 6) == 0) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
887
2300
159136c9808d *) correct leaky bucket implementation
Igor Sysoev <igor@sysoev.ru>
parents: 2294
diff changeset
888 burst = ngx_atoi(value[i].data + 6, value[i].len - 6);
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
889 if (burst <= 0) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
890 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
891 "invalid burst rate \"%V\"", &value[i]);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
892 return NGX_CONF_ERROR;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
893 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
894
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
895 continue;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
896 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
897
2300
159136c9808d *) correct leaky bucket implementation
Igor Sysoev <igor@sysoev.ru>
parents: 2294
diff changeset
898 if (ngx_strncmp(value[i].data, "nodelay", 7) == 0) {
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
899 nodelay = 1;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
900 continue;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
901 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
902
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
903 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
904 "invalid parameter \"%V\"", &value[i]);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
905 return NGX_CONF_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
906 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
907
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
908 if (shm_zone == NULL) {
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
909 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
910 "\"%V\" must have \"zone\" parameter",
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
911 &cmd->name);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
912 return NGX_CONF_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
913 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
914
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
915 if (shm_zone->data == NULL) {
1011
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
916 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
917 "unknown limit_req_zone \"%V\"",
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
918 &shm_zone->shm.name);
1011
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
919 return NGX_CONF_ERROR;
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
920 }
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
921
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
922 limits = lrcf->limits.elts;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
923
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
924 if (limits == NULL) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
925 if (ngx_array_init(&lrcf->limits, cf->pool, 1,
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
926 sizeof(ngx_http_limit_req_limit_t))
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
927 != NGX_OK)
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
928 {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
929 return NGX_CONF_ERROR;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
930 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
931 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
932
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
933 for (i = 0; i < lrcf->limits.nelts; i++) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
934 if (shm_zone == limits[i].shm_zone) {
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
935 return "is duplicate";
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
936 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
937 }
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
938
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
939 limit = ngx_array_push(&lrcf->limits);
4811
21d1e3bcb356 Added three missing checks for NULL after ngx_array_push() calls.
Valentin Bartenev <vbart@nginx.com>
parents: 4499
diff changeset
940 if (limit == NULL) {
21d1e3bcb356 Added three missing checks for NULL after ngx_array_push() calls.
Valentin Bartenev <vbart@nginx.com>
parents: 4499
diff changeset
941 return NGX_CONF_ERROR;
21d1e3bcb356 Added three missing checks for NULL after ngx_array_push() calls.
Valentin Bartenev <vbart@nginx.com>
parents: 4499
diff changeset
942 }
4420
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
943
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
944 limit->shm_zone = shm_zone;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
945 limit->burst = burst * 1000;
9ce48f9eb85b Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents: 4419
diff changeset
946 limit->nodelay = nodelay;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
947
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
948 return NGX_CONF_OK;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
949 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
950
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
951
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
952 static ngx_int_t
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
953 ngx_http_limit_req_init(ngx_conf_t *cf)
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
954 {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
955 ngx_http_handler_pt *h;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
956 ngx_http_core_main_conf_t *cmcf;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
957
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
958 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
959
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
960 h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
961 if (h == NULL) {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
962 return NGX_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
963 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
964
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
965 *h = ngx_http_limit_req_handler;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
966
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
967 return NGX_OK;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
968 }