Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_limit_req_module.c @ 8311:f790816a0e87
HTTP/2: removed http2_idle_timeout and http2_max_requests.
Instead, keepalive_timeout and keepalive_requests are now used. This
is expected to simplify HTTP/2 code and usage. This also matches
directives used by upstream module for all protocols.
In case of default settings, this effectively changes maximum number
of requests per connection from 1000 to 100. This looks acceptable,
especially given that HTTP/2 code now properly supports lingering close.
Further, this changes default keepalive timeout in HTTP/2 from 300 seconds
to 75 seconds. This also looks acceptable, and larger than PING interval
used by Firefox (network.http.spdy.ping-threshold defaults to 58s),
the only browser to use PINGs.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 11 Feb 2021 21:52:23 +0300 |
parents | 559d19037984 |
children | 1ebd78df4ce7 |
rev | line source |
---|---|
980 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
980 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
7592
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
13 #define NGX_HTTP_LIMIT_REQ_PASSED 1 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
14 #define NGX_HTTP_LIMIT_REQ_DELAYED 2 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
15 #define NGX_HTTP_LIMIT_REQ_REJECTED 3 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
16 #define NGX_HTTP_LIMIT_REQ_DELAYED_DRY_RUN 4 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
17 #define NGX_HTTP_LIMIT_REQ_REJECTED_DRY_RUN 5 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
18 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
19 |
980 | 20 typedef struct { |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
21 u_char color; |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
22 u_char dummy; |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
23 u_short len; |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
24 ngx_queue_t queue; |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
25 ngx_msec_t last; |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
26 /* 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
|
27 ngx_uint_t excess; |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
28 ngx_uint_t count; |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
29 u_char data[1]; |
2294 | 30 } ngx_http_limit_req_node_t; |
980 | 31 |
32 | |
33 typedef struct { | |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
34 ngx_rbtree_t rbtree; |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
35 ngx_rbtree_node_t sentinel; |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
36 ngx_queue_t queue; |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
37 } ngx_http_limit_req_shctx_t; |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
38 |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
39 |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
40 typedef struct { |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
41 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
|
42 ngx_slab_pool_t *shpool; |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
43 /* 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
|
44 ngx_uint_t rate; |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
45 ngx_http_complex_value_t key; |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
46 ngx_http_limit_req_node_t *node; |
2294 | 47 } ngx_http_limit_req_ctx_t; |
987 | 48 |
49 | |
50 typedef struct { | |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
51 ngx_shm_zone_t *shm_zone; |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
52 /* 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
|
53 ngx_uint_t burst; |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
54 ngx_uint_t delay; |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
55 } ngx_http_limit_req_limit_t; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
56 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
57 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
58 typedef struct { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
59 ngx_array_t limits; |
3185 | 60 ngx_uint_t limit_log_level; |
61 ngx_uint_t delay_log_level; | |
5117
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
62 ngx_uint_t status_code; |
7515
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
63 ngx_flag_t dry_run; |
2294 | 64 } ngx_http_limit_req_conf_t; |
980 | 65 |
66 | |
2294 | 67 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
|
68 static ngx_int_t ngx_http_limit_req_lookup(ngx_http_limit_req_limit_t *limit, |
5863
102f85699420
Limit req: reduced number of parameters in the lookup function.
Valentin Bartenev <vbart@nginx.com>
parents:
5862
diff
changeset
|
69 ngx_uint_t hash, ngx_str_t *key, ngx_uint_t *ep, ngx_uint_t account); |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
70 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
|
71 ngx_uint_t n, ngx_uint_t *ep, ngx_http_limit_req_limit_t **limit); |
8179
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
72 static void ngx_http_limit_req_unlock(ngx_http_limit_req_limit_t *limits, |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
73 ngx_uint_t n); |
2294 | 74 static void ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, |
75 ngx_uint_t n); | |
980 | 76 |
7592
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
77 static ngx_int_t ngx_http_limit_req_status_variable(ngx_http_request_t *r, |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
78 ngx_http_variable_value_t *v, uintptr_t data); |
2294 | 79 static void *ngx_http_limit_req_create_conf(ngx_conf_t *cf); |
80 static char *ngx_http_limit_req_merge_conf(ngx_conf_t *cf, void *parent, | |
980 | 81 void *child); |
2294 | 82 static char *ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, |
980 | 83 void *conf); |
2294 | 84 static char *ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, |
980 | 85 void *conf); |
7592
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
86 static ngx_int_t ngx_http_limit_req_add_variables(ngx_conf_t *cf); |
2294 | 87 static ngx_int_t ngx_http_limit_req_init(ngx_conf_t *cf); |
980 | 88 |
89 | |
3185 | 90 static ngx_conf_enum_t ngx_http_limit_req_log_levels[] = { |
91 { ngx_string("info"), NGX_LOG_INFO }, | |
92 { ngx_string("notice"), NGX_LOG_NOTICE }, | |
93 { ngx_string("warn"), NGX_LOG_WARN }, | |
94 { ngx_string("error"), NGX_LOG_ERR }, | |
95 { ngx_null_string, 0 } | |
96 }; | |
97 | |
98 | |
5117
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
99 static ngx_conf_num_bounds_t ngx_http_limit_req_status_bounds = { |
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
100 ngx_conf_check_num_bounds, 400, 599 |
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
101 }; |
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
102 |
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
103 |
2294 | 104 static ngx_command_t ngx_http_limit_req_commands[] = { |
980 | 105 |
2294 | 106 { ngx_string("limit_req_zone"), |
987 | 107 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE3, |
2294 | 108 ngx_http_limit_req_zone, |
980 | 109 0, |
110 0, | |
111 NULL }, | |
112 | |
2294 | 113 { ngx_string("limit_req"), |
114 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123, | |
115 ngx_http_limit_req, | |
980 | 116 NGX_HTTP_LOC_CONF_OFFSET, |
117 0, | |
118 NULL }, | |
119 | |
3185 | 120 { ngx_string("limit_req_log_level"), |
121 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
122 ngx_conf_set_enum_slot, | |
123 NGX_HTTP_LOC_CONF_OFFSET, | |
124 offsetof(ngx_http_limit_req_conf_t, limit_log_level), | |
125 &ngx_http_limit_req_log_levels }, | |
126 | |
5117
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
127 { ngx_string("limit_req_status"), |
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
128 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
129 ngx_conf_set_num_slot, |
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
130 NGX_HTTP_LOC_CONF_OFFSET, |
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
131 offsetof(ngx_http_limit_req_conf_t, status_code), |
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
132 &ngx_http_limit_req_status_bounds }, |
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
133 |
7515
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
134 { ngx_string("limit_req_dry_run"), |
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
135 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
136 ngx_conf_set_flag_slot, |
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
137 NGX_HTTP_LOC_CONF_OFFSET, |
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
138 offsetof(ngx_http_limit_req_conf_t, dry_run), |
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
139 NULL }, |
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
140 |
980 | 141 ngx_null_command |
142 }; | |
143 | |
144 | |
2294 | 145 static ngx_http_module_t ngx_http_limit_req_module_ctx = { |
7592
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
146 ngx_http_limit_req_add_variables, /* preconfiguration */ |
2294 | 147 ngx_http_limit_req_init, /* postconfiguration */ |
980 | 148 |
149 NULL, /* create main configuration */ | |
150 NULL, /* init main configuration */ | |
151 | |
152 NULL, /* create server configuration */ | |
153 NULL, /* merge server configuration */ | |
154 | |
4499
778ef9c3fd2d
Fixed spelling in single-line comments.
Ruslan Ermilov <ru@nginx.com>
parents:
4497
diff
changeset
|
155 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
|
156 ngx_http_limit_req_merge_conf /* merge location configuration */ |
980 | 157 }; |
158 | |
159 | |
2294 | 160 ngx_module_t ngx_http_limit_req_module = { |
980 | 161 NGX_MODULE_V1, |
2294 | 162 &ngx_http_limit_req_module_ctx, /* module context */ |
163 ngx_http_limit_req_commands, /* module directives */ | |
980 | 164 NGX_HTTP_MODULE, /* module type */ |
165 NULL, /* init master */ | |
166 NULL, /* init module */ | |
167 NULL, /* init process */ | |
168 NULL, /* init thread */ | |
169 NULL, /* exit thread */ | |
170 NULL, /* exit process */ | |
171 NULL, /* exit master */ | |
172 NGX_MODULE_V1_PADDING | |
173 }; | |
174 | |
175 | |
7592
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
176 static ngx_http_variable_t ngx_http_limit_req_vars[] = { |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
177 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
178 { ngx_string("limit_req_status"), NULL, |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
179 ngx_http_limit_req_status_variable, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
180 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
181 ngx_http_null_variable |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
182 }; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
183 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
184 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
185 static ngx_str_t ngx_http_limit_req_status[] = { |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
186 ngx_string("PASSED"), |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
187 ngx_string("DELAYED"), |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
188 ngx_string("REJECTED"), |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
189 ngx_string("DELAYED_DRY_RUN"), |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
190 ngx_string("REJECTED_DRY_RUN") |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
191 }; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
192 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
193 |
980 | 194 static ngx_int_t |
2294 | 195 ngx_http_limit_req_handler(ngx_http_request_t *r) |
980 | 196 { |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
197 uint32_t hash; |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
198 ngx_str_t key; |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
199 ngx_int_t rc; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
200 ngx_uint_t n, excess; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
201 ngx_msec_t delay; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
202 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
|
203 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
|
204 ngx_http_limit_req_limit_t *limit, *limits; |
980 | 205 |
7592
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
206 if (r->main->limit_req_status) { |
984
dd128232e6ba
count connection once per request
Igor Sysoev <igor@sysoev.ru>
parents:
981
diff
changeset
|
207 return NGX_DECLINED; |
dd128232e6ba
count connection once per request
Igor Sysoev <igor@sysoev.ru>
parents:
981
diff
changeset
|
208 } |
dd128232e6ba
count connection once per request
Igor Sysoev <igor@sysoev.ru>
parents:
981
diff
changeset
|
209 |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
210 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
|
211 limits = lrcf->limits.elts; |
980 | 212 |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
213 excess = 0; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
214 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
215 rc = NGX_DECLINED; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
216 |
4424
aacd7356c197
Limit req: unbreak compilation with MSVC.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4420
diff
changeset
|
217 #if (NGX_SUPPRESS_WARN) |
aacd7356c197
Limit req: unbreak compilation with MSVC.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4420
diff
changeset
|
218 limit = NULL; |
aacd7356c197
Limit req: unbreak compilation with MSVC.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4420
diff
changeset
|
219 #endif |
aacd7356c197
Limit req: unbreak compilation with MSVC.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4420
diff
changeset
|
220 |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
221 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
|
222 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
223 limit = &limits[n]; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
224 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
225 ctx = limit->shm_zone->data; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
226 |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
227 if (ngx_http_complex_value(r, &ctx->key, &key) != NGX_OK) { |
8179
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
228 ngx_http_limit_req_unlock(limits, n); |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
229 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
4420
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 |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
232 if (key.len == 0) { |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
233 continue; |
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 |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
236 if (key.len > 65535) { |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
237 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
238 "the value of the \"%V\" key " |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
239 "is more than 65535 bytes: \"%V\"", |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
240 &ctx->key.value, &key); |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
241 continue; |
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 |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
244 hash = ngx_crc32_short(key.data, key.len); |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
245 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
246 ngx_shmtx_lock(&ctx->shpool->mutex); |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
247 |
5863
102f85699420
Limit req: reduced number of parameters in the lookup function.
Valentin Bartenev <vbart@nginx.com>
parents:
5862
diff
changeset
|
248 rc = ngx_http_limit_req_lookup(limit, hash, &key, &excess, |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
249 (n == lrcf->limits.nelts - 1)); |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
250 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
251 ngx_shmtx_unlock(&ctx->shpool->mutex); |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
252 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
253 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
|
254 "limit_req[%ui]: %i %ui.%03ui", |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
255 n, rc, excess / 1000, excess % 1000); |
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 if (rc != NGX_AGAIN) { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
258 break; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
259 } |
980 | 260 } |
261 | |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
262 if (rc == NGX_DECLINED) { |
1011
19118c44303f
test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents:
1002
diff
changeset
|
263 return NGX_DECLINED; |
19118c44303f
test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents:
1002
diff
changeset
|
264 } |
19118c44303f
test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents:
1002
diff
changeset
|
265 |
4418
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
266 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
|
267 |
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
268 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
|
269 ngx_log_error(lrcf->limit_log_level, r->connection->log, 0, |
7515
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
270 "limiting requests%s, excess: %ui.%03ui by zone \"%V\"", |
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
271 lrcf->dry_run ? ", dry run" : "", |
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
272 excess / 1000, excess % 1000, |
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
273 &limit->shm_zone->shm.name); |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
274 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
275 |
8179
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
276 ngx_http_limit_req_unlock(limits, n); |
980 | 277 |
7515
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
278 if (lrcf->dry_run) { |
7592
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
279 r->main->limit_req_status = NGX_HTTP_LIMIT_REQ_REJECTED_DRY_RUN; |
7515
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
280 return NGX_DECLINED; |
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
281 } |
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
282 |
7592
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
283 r->main->limit_req_status = NGX_HTTP_LIMIT_REQ_REJECTED; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
284 |
5117
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
285 return lrcf->status_code; |
980 | 286 } |
287 | |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
288 /* rc == NGX_AGAIN || rc == NGX_OK */ |
2300
159136c9808d
*) correct leaky bucket implementation
Igor Sysoev <igor@sysoev.ru>
parents:
2294
diff
changeset
|
289 |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
290 if (rc == NGX_AGAIN) { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
291 excess = 0; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
292 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
293 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
294 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
|
295 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
296 if (!delay) { |
7592
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
297 r->main->limit_req_status = NGX_HTTP_LIMIT_REQ_PASSED; |
3780
d94d7104f598
change order of limit_req lookup result processing
Igor Sysoev <igor@sysoev.ru>
parents:
3779
diff
changeset
|
298 return NGX_DECLINED; |
2294 | 299 } |
300 | |
3780
d94d7104f598
change order of limit_req lookup result processing
Igor Sysoev <igor@sysoev.ru>
parents:
3779
diff
changeset
|
301 ngx_log_error(lrcf->delay_log_level, r->connection->log, 0, |
7515
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
302 "delaying request%s, excess: %ui.%03ui, by zone \"%V\"", |
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
303 lrcf->dry_run ? ", dry run" : "", |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
304 excess / 1000, excess % 1000, &limit->shm_zone->shm.name); |
2294 | 305 |
7515
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
306 if (lrcf->dry_run) { |
7592
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
307 r->main->limit_req_status = NGX_HTTP_LIMIT_REQ_DELAYED_DRY_RUN; |
7515
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
308 return NGX_DECLINED; |
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
309 } |
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
310 |
7592
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
311 r->main->limit_req_status = NGX_HTTP_LIMIT_REQ_DELAYED; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
312 |
3780
d94d7104f598
change order of limit_req lookup result processing
Igor Sysoev <igor@sysoev.ru>
parents:
3779
diff
changeset
|
313 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
|
314 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
2294 | 315 } |
316 | |
3780
d94d7104f598
change order of limit_req lookup result processing
Igor Sysoev <igor@sysoev.ru>
parents:
3779
diff
changeset
|
317 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
|
318 r->write_event_handler = ngx_http_limit_req_delay; |
6959
7fcf209d40c8
Limit req: fixed delaying subrequests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6653
diff
changeset
|
319 |
7fcf209d40c8
Limit req: fixed delaying subrequests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6653
diff
changeset
|
320 r->connection->write->delayed = 1; |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
321 ngx_add_timer(r->connection->write, delay); |
2294 | 322 |
3780
d94d7104f598
change order of limit_req lookup result processing
Igor Sysoev <igor@sysoev.ru>
parents:
3779
diff
changeset
|
323 return NGX_AGAIN; |
980 | 324 } |
325 | |
326 | |
327 static void | |
2294 | 328 ngx_http_limit_req_delay(ngx_http_request_t *r) |
329 { | |
2972
c5ad288f851d
fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
330 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
|
331 |
2294 | 332 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2973 | 333 "limit_req delay"); |
2294 | 334 |
2972
c5ad288f851d
fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
335 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
|
336 |
6961
903fb1ddc07f
Moved handling of wev->delayed to the connection event handler.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6959
diff
changeset
|
337 if (wev->delayed) { |
2972
c5ad288f851d
fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
338 |
c5ad288f851d
fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
339 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
|
340 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
|
341 } |
c5ad288f851d
fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
342 |
c5ad288f851d
fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
343 return; |
c5ad288f851d
fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
344 } |
c5ad288f851d
fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
345 |
2294 | 346 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { |
347 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
348 return; | |
349 } | |
350 | |
351 r->read_event_handler = ngx_http_block_reading; | |
352 r->write_event_handler = ngx_http_core_run_phases; | |
353 | |
354 ngx_http_core_run_phases(r); | |
355 } | |
356 | |
357 | |
358 static void | |
359 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
|
360 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
|
361 { |
2294 | 362 ngx_rbtree_node_t **p; |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
363 ngx_http_limit_req_node_t *lrn, *lrnt; |
1026
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
364 |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
365 for ( ;; ) { |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
366 |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
367 if (node->key < temp->key) { |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
368 |
1743
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1406
diff
changeset
|
369 p = &temp->left; |
1026
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
370 |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
371 } else if (node->key > temp->key) { |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
372 |
1743
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1406
diff
changeset
|
373 p = &temp->right; |
1026
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
374 |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
375 } else { /* node->key == temp->key */ |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
376 |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
377 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
|
378 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
|
379 |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
380 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
|
381 ? &temp->left : &temp->right; |
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1406
diff
changeset
|
382 } |
1026
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
383 |
1743
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1406
diff
changeset
|
384 if (*p == sentinel) { |
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1406
diff
changeset
|
385 break; |
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1406
diff
changeset
|
386 } |
1026
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
387 |
1743
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1406
diff
changeset
|
388 temp = *p; |
1026
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
389 } |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
390 |
1743
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1406
diff
changeset
|
391 *p = node; |
1026
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
392 node->parent = temp; |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
393 node->left = sentinel; |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
394 node->right = sentinel; |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
395 ngx_rbt_red(node); |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
396 } |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
397 |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
398 |
2294 | 399 static ngx_int_t |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
400 ngx_http_limit_req_lookup(ngx_http_limit_req_limit_t *limit, ngx_uint_t hash, |
5863
102f85699420
Limit req: reduced number of parameters in the lookup function.
Valentin Bartenev <vbart@nginx.com>
parents:
5862
diff
changeset
|
401 ngx_str_t *key, ngx_uint_t *ep, ngx_uint_t account) |
980 | 402 { |
4418
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
403 size_t size; |
2313 | 404 ngx_int_t rc, excess; |
2294 | 405 ngx_msec_t now; |
406 ngx_msec_int_t ms; | |
407 ngx_rbtree_node_t *node, *sentinel; | |
408 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
|
409 ngx_http_limit_req_node_t *lr; |
2294 | 410 |
6653
7a6456398fc3
Simplified extraction of current time.
Ruslan Ermilov <ru@nginx.com>
parents:
6117
diff
changeset
|
411 now = ngx_current_msec; |
4418
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
412 |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
413 ctx = limit->shm_zone->data; |
2294 | 414 |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
415 node = ctx->sh->rbtree.root; |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
416 sentinel = ctx->sh->rbtree.sentinel; |
980 | 417 |
2294 | 418 while (node != sentinel) { |
419 | |
420 if (hash < node->key) { | |
421 node = node->left; | |
422 continue; | |
423 } | |
424 | |
425 if (hash > node->key) { | |
426 node = node->right; | |
427 continue; | |
428 } | |
429 | |
430 /* hash == node->key */ | |
431 | |
4497
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
432 lr = (ngx_http_limit_req_node_t *) &node->color; |
2294 | 433 |
5863
102f85699420
Limit req: reduced number of parameters in the lookup function.
Valentin Bartenev <vbart@nginx.com>
parents:
5862
diff
changeset
|
434 rc = ngx_memn2cmp(key->data, lr->data, key->len, (size_t) lr->len); |
3191 | 435 |
4497
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
436 if (rc == 0) { |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
437 ngx_queue_remove(&lr->queue); |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
438 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
|
439 |
4497
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
440 ms = (ngx_msec_int_t) (now - lr->last); |
980 | 441 |
7281
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
442 if (ms < -60000) { |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
443 ms = 1; |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
444 |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
445 } else if (ms < 0) { |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
446 ms = 0; |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
447 } |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
448 |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
449 excess = lr->excess - ctx->rate * ms / 1000 + 1000; |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
450 |
4497
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
451 if (excess < 0) { |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
452 excess = 0; |
2294 | 453 } |
454 | |
4497
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
455 *ep = excess; |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
456 |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
457 if ((ngx_uint_t) excess > limit->burst) { |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
458 return NGX_BUSY; |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
459 } |
2294 | 460 |
4497
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
461 if (account) { |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
462 lr->excess = excess; |
7281
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
463 |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
464 if (ms) { |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
465 lr->last = now; |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
466 } |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
467 |
4497
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
468 return NGX_OK; |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
469 } |
2294 | 470 |
4497
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
471 lr->count++; |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
472 |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
473 ctx->node = lr; |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
474 |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
475 return NGX_AGAIN; |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
476 } |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
477 |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
478 node = (rc < 0) ? node->left : node->right; |
980 | 479 } |
480 | |
3779
57aecfdcac3d
an excess was logged as 0.000 if requests were limited without delay:
Igor Sysoev <igor@sysoev.ru>
parents:
3525
diff
changeset
|
481 *ep = 0; |
2294 | 482 |
4418
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
483 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
|
484 + offsetof(ngx_http_limit_req_node_t, data) |
5863
102f85699420
Limit req: reduced number of parameters in the lookup function.
Valentin Bartenev <vbart@nginx.com>
parents:
5862
diff
changeset
|
485 + key->len; |
4418
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
486 |
4419
7084faa7a4b4
Limit req: number of cleanup calls reduced.
Valentin Bartenev <vbart@nginx.com>
parents:
4418
diff
changeset
|
487 ngx_http_limit_req_expire(ctx, 1); |
7084faa7a4b4
Limit req: number of cleanup calls reduced.
Valentin Bartenev <vbart@nginx.com>
parents:
4418
diff
changeset
|
488 |
4418
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
489 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
|
490 |
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
491 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
|
492 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
|
493 |
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
494 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
|
495 if (node == NULL) { |
5634
5024d29354f1
Core: slab log_nomem flag.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5411
diff
changeset
|
496 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, |
5024d29354f1
Core: slab log_nomem flag.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5411
diff
changeset
|
497 "could not allocate node%s", ctx->shpool->log_ctx); |
4418
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
498 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
|
499 } |
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
500 } |
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
501 |
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
502 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
|
503 |
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
504 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
|
505 |
5863
102f85699420
Limit req: reduced number of parameters in the lookup function.
Valentin Bartenev <vbart@nginx.com>
parents:
5862
diff
changeset
|
506 lr->len = (u_short) key->len; |
4418
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
507 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
|
508 |
5863
102f85699420
Limit req: reduced number of parameters in the lookup function.
Valentin Bartenev <vbart@nginx.com>
parents:
5862
diff
changeset
|
509 ngx_memcpy(lr->data, key->data, key->len); |
4418
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
510 |
4832
949ea3d3cd1a
Limit req: fix of rbtree node insertion on hash collisions.
Valentin Bartenev <vbart@nginx.com>
parents:
4811
diff
changeset
|
511 ngx_rbtree_insert(&ctx->sh->rbtree, node); |
949ea3d3cd1a
Limit req: fix of rbtree node insertion on hash collisions.
Valentin Bartenev <vbart@nginx.com>
parents:
4811
diff
changeset
|
512 |
949ea3d3cd1a
Limit req: fix of rbtree node insertion on hash collisions.
Valentin Bartenev <vbart@nginx.com>
parents:
4811
diff
changeset
|
513 ngx_queue_insert_head(&ctx->sh->queue, &lr->queue); |
949ea3d3cd1a
Limit req: fix of rbtree node insertion on hash collisions.
Valentin Bartenev <vbart@nginx.com>
parents:
4811
diff
changeset
|
514 |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
515 if (account) { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
516 lr->last = now; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
517 lr->count = 0; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
518 return NGX_OK; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
519 } |
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 lr->last = 0; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
522 lr->count = 1; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
523 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
524 ctx->node = lr; |
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 return NGX_AGAIN; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
527 } |
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 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
530 static ngx_msec_t |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
531 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
|
532 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
|
533 { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
534 ngx_int_t excess; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
535 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
|
536 ngx_msec_int_t ms; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
537 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
|
538 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
|
539 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
540 excess = *ep; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
541 |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
542 if ((ngx_uint_t) excess <= (*limit)->delay) { |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
543 max_delay = 0; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
544 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
545 } else { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
546 ctx = (*limit)->shm_zone->data; |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
547 max_delay = (excess - (*limit)->delay) * 1000 / ctx->rate; |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
548 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
549 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
550 while (n--) { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
551 ctx = limits[n].shm_zone->data; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
552 lr = ctx->node; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
553 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
554 if (lr == NULL) { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
555 continue; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
556 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
557 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
558 ngx_shmtx_lock(&ctx->shpool->mutex); |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
559 |
6653
7a6456398fc3
Simplified extraction of current time.
Ruslan Ermilov <ru@nginx.com>
parents:
6117
diff
changeset
|
560 now = ngx_current_msec; |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
561 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
|
562 |
7281
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
563 if (ms < -60000) { |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
564 ms = 1; |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
565 |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
566 } else if (ms < 0) { |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
567 ms = 0; |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
568 } |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
569 |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
570 excess = lr->excess - ctx->rate * ms / 1000 + 1000; |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
571 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
572 if (excess < 0) { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
573 excess = 0; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
574 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
575 |
7281
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
576 if (ms) { |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
577 lr->last = now; |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
578 } |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
579 |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
580 lr->excess = excess; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
581 lr->count--; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
582 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
583 ngx_shmtx_unlock(&ctx->shpool->mutex); |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
584 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
585 ctx->node = NULL; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
586 |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
587 if ((ngx_uint_t) excess <= limits[n].delay) { |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
588 continue; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
589 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
590 |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
591 delay = (excess - limits[n].delay) * 1000 / ctx->rate; |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
592 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
593 if (delay > max_delay) { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
594 max_delay = delay; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
595 *ep = excess; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
596 *limit = &limits[n]; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
597 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
598 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
599 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
600 return max_delay; |
2294 | 601 } |
602 | |
603 | |
604 static void | |
8179
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
605 ngx_http_limit_req_unlock(ngx_http_limit_req_limit_t *limits, ngx_uint_t n) |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
606 { |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
607 ngx_http_limit_req_ctx_t *ctx; |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
608 |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
609 while (n--) { |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
610 ctx = limits[n].shm_zone->data; |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
611 |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
612 if (ctx->node == NULL) { |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
613 continue; |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
614 } |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
615 |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
616 ngx_shmtx_lock(&ctx->shpool->mutex); |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
617 |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
618 ctx->node->count--; |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
619 |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
620 ngx_shmtx_unlock(&ctx->shpool->mutex); |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
621 |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
622 ctx->node = NULL; |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
623 } |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
624 } |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
625 |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
626 |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
627 static void |
2294 | 628 ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, ngx_uint_t n) |
629 { | |
2313 | 630 ngx_int_t excess; |
2294 | 631 ngx_msec_t now; |
632 ngx_queue_t *q; | |
633 ngx_msec_int_t ms; | |
634 ngx_rbtree_node_t *node; | |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
635 ngx_http_limit_req_node_t *lr; |
2294 | 636 |
6653
7a6456398fc3
Simplified extraction of current time.
Ruslan Ermilov <ru@nginx.com>
parents:
6117
diff
changeset
|
637 now = ngx_current_msec; |
2294 | 638 |
639 /* | |
640 * n == 1 deletes one or two zero rate entries | |
641 * n == 0 deletes oldest entry by force | |
642 * and one or two zero rate entries | |
643 */ | |
644 | |
645 while (n < 3) { | |
646 | |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
647 if (ngx_queue_empty(&ctx->sh->queue)) { |
2294 | 648 return; |
649 } | |
650 | |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
651 q = ngx_queue_last(&ctx->sh->queue); |
2294 | 652 |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
653 lr = ngx_queue_data(q, ngx_http_limit_req_node_t, queue); |
2294 | 654 |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
655 if (lr->count) { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
656 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
657 /* |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
658 * 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
|
659 * 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
|
660 */ |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
661 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
662 return; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
663 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
664 |
2294 | 665 if (n++ != 0) { |
666 | |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
667 ms = (ngx_msec_int_t) (now - lr->last); |
2294 | 668 ms = ngx_abs(ms); |
669 | |
670 if (ms < 60000) { | |
671 return; | |
672 } | |
673 | |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
674 excess = lr->excess - ctx->rate * ms / 1000; |
2294 | 675 |
2313 | 676 if (excess > 0) { |
2294 | 677 return; |
678 } | |
679 } | |
680 | |
681 ngx_queue_remove(q); | |
682 | |
683 node = (ngx_rbtree_node_t *) | |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
684 ((u_char *) lr - offsetof(ngx_rbtree_node_t, color)); |
2294 | 685 |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
686 ngx_rbtree_delete(&ctx->sh->rbtree, node); |
2294 | 687 |
688 ngx_slab_free_locked(ctx->shpool, node); | |
689 } | |
980 | 690 } |
691 | |
692 | |
693 static ngx_int_t | |
2294 | 694 ngx_http_limit_req_init_zone(ngx_shm_zone_t *shm_zone, void *data) |
980 | 695 { |
2294 | 696 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
|
697 |
2611
2bce3f6416c6
improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents:
2376
diff
changeset
|
698 size_t len; |
2294 | 699 ngx_http_limit_req_ctx_t *ctx; |
980 | 700 |
993
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
701 ctx = shm_zone->data; |
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
702 |
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
703 if (octx) { |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
704 if (ctx->key.value.len != octx->key.value.len |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
705 || ngx_strncmp(ctx->key.value.data, octx->key.value.data, |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
706 ctx->key.value.len) |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
707 != 0) |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
708 { |
993
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
709 ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0, |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
710 "limit_req \"%V\" uses the \"%V\" key " |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
711 "while previously it used the \"%V\" key", |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
712 &shm_zone->shm.name, &ctx->key.value, |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
713 &octx->key.value); |
993
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
714 return NGX_ERROR; |
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
715 } |
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
716 |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
717 ctx->sh = octx->sh; |
2294 | 718 ctx->shpool = octx->shpool; |
993
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
719 |
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
720 return NGX_OK; |
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
721 } |
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
722 |
2294 | 723 ctx->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; |
980 | 724 |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
725 if (shm_zone->shm.exists) { |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
726 ctx->sh = ctx->shpool->data; |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
727 |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
728 return NGX_OK; |
980 | 729 } |
730 | |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
731 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
|
732 if (ctx->sh == NULL) { |
980 | 733 return NGX_ERROR; |
734 } | |
735 | |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
736 ctx->shpool->data = ctx->sh; |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
737 |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
738 ngx_rbtree_init(&ctx->sh->rbtree, &ctx->sh->sentinel, |
2294 | 739 ngx_http_limit_req_rbtree_insert_value); |
740 | |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
741 ngx_queue_init(&ctx->sh->queue); |
980 | 742 |
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
|
743 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
|
744 |
2bce3f6416c6
improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents:
2376
diff
changeset
|
745 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
|
746 if (ctx->shpool->log_ctx == NULL) { |
2bce3f6416c6
improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents:
2376
diff
changeset
|
747 return NGX_ERROR; |
2bce3f6416c6
improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents:
2376
diff
changeset
|
748 } |
2bce3f6416c6
improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents:
2376
diff
changeset
|
749 |
2bce3f6416c6
improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents:
2376
diff
changeset
|
750 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
|
751 &shm_zone->shm.name); |
2611
2bce3f6416c6
improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents:
2376
diff
changeset
|
752 |
5634
5024d29354f1
Core: slab log_nomem flag.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5411
diff
changeset
|
753 ctx->shpool->log_nomem = 0; |
5024d29354f1
Core: slab log_nomem flag.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5411
diff
changeset
|
754 |
980 | 755 return NGX_OK; |
756 } | |
757 | |
758 | |
7592
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
759 static ngx_int_t |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
760 ngx_http_limit_req_status_variable(ngx_http_request_t *r, |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
761 ngx_http_variable_value_t *v, uintptr_t data) |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
762 { |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
763 if (r->main->limit_req_status == 0) { |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
764 v->not_found = 1; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
765 return NGX_OK; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
766 } |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
767 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
768 v->valid = 1; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
769 v->no_cacheable = 0; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
770 v->not_found = 0; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
771 v->len = ngx_http_limit_req_status[r->main->limit_req_status - 1].len; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
772 v->data = ngx_http_limit_req_status[r->main->limit_req_status - 1].data; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
773 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
774 return NGX_OK; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
775 } |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
776 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
777 |
980 | 778 static void * |
2294 | 779 ngx_http_limit_req_create_conf(ngx_conf_t *cf) |
980 | 780 { |
2294 | 781 ngx_http_limit_req_conf_t *conf; |
980 | 782 |
2294 | 783 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_req_conf_t)); |
980 | 784 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
|
785 return NULL; |
980 | 786 } |
787 | |
788 /* | |
789 * set by ngx_pcalloc(): | |
790 * | |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
791 * conf->limits.elts = NULL; |
980 | 792 */ |
793 | |
3185 | 794 conf->limit_log_level = NGX_CONF_UNSET_UINT; |
5117
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
795 conf->status_code = NGX_CONF_UNSET_UINT; |
7515
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
796 conf->dry_run = NGX_CONF_UNSET; |
3185 | 797 |
980 | 798 return conf; |
799 } | |
800 | |
801 | |
802 static char * | |
2294 | 803 ngx_http_limit_req_merge_conf(ngx_conf_t *cf, void *parent, void *child) |
980 | 804 { |
2294 | 805 ngx_http_limit_req_conf_t *prev = parent; |
806 ngx_http_limit_req_conf_t *conf = child; | |
980 | 807 |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
808 if (conf->limits.elts == NULL) { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
809 conf->limits = prev->limits; |
980 | 810 } |
811 | |
3185 | 812 ngx_conf_merge_uint_value(conf->limit_log_level, prev->limit_log_level, |
813 NGX_LOG_ERR); | |
814 | |
815 conf->delay_log_level = (conf->limit_log_level == NGX_LOG_INFO) ? | |
816 NGX_LOG_INFO : conf->limit_log_level + 1; | |
817 | |
5117
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
818 ngx_conf_merge_uint_value(conf->status_code, prev->status_code, |
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
819 NGX_HTTP_SERVICE_UNAVAILABLE); |
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
820 |
7515
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
821 ngx_conf_merge_value(conf->dry_run, prev->dry_run, 0); |
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
822 |
980 | 823 return NGX_CONF_OK; |
824 } | |
825 | |
826 | |
827 static char * | |
2294 | 828 ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
980 | 829 { |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
830 u_char *p; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
831 size_t len; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
832 ssize_t size; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
833 ngx_str_t *value, name, s; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
834 ngx_int_t rate, scale; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
835 ngx_uint_t i; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
836 ngx_shm_zone_t *shm_zone; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
837 ngx_http_limit_req_ctx_t *ctx; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
838 ngx_http_compile_complex_value_t ccv; |
980 | 839 |
840 value = cf->args->elts; | |
841 | |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
842 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_req_ctx_t)); |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
843 if (ctx == NULL) { |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
844 return NGX_CONF_ERROR; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
845 } |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
846 |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
847 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
848 |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
849 ccv.cf = cf; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
850 ccv.value = &value[1]; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
851 ccv.complex_value = &ctx->key; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
852 |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
853 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
854 return NGX_CONF_ERROR; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
855 } |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
856 |
2294 | 857 size = 0; |
858 rate = 1; | |
859 scale = 1; | |
860 name.len = 0; | |
861 | |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
862 for (i = 2; i < cf->args->nelts; i++) { |
2294 | 863 |
864 if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { | |
865 | |
866 name.data = value[i].data + 5; | |
867 | |
868 p = (u_char *) ngx_strchr(name.data, ':'); | |
869 | |
4417
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
870 if (p == NULL) { |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
871 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
|
872 "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
|
873 return NGX_CONF_ERROR; |
2294 | 874 } |
875 | |
4417
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
876 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
|
877 |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
878 s.data = p + 1; |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
879 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
|
880 |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
881 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
|
882 |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
883 if (size == NGX_ERROR) { |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
884 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
|
885 "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
|
886 return NGX_CONF_ERROR; |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
887 } |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
888 |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
889 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
|
890 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
|
891 "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
|
892 return NGX_CONF_ERROR; |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
893 } |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
894 |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
895 continue; |
2294 | 896 } |
897 | |
898 if (ngx_strncmp(value[i].data, "rate=", 5) == 0) { | |
899 | |
900 len = value[i].len; | |
901 p = value[i].data + len - 3; | |
987 | 902 |
2294 | 903 if (ngx_strncmp(p, "r/s", 3) == 0) { |
904 scale = 1; | |
905 len -= 3; | |
906 | |
907 } else if (ngx_strncmp(p, "r/m", 3) == 0) { | |
908 scale = 60; | |
909 len -= 3; | |
910 } | |
911 | |
912 rate = ngx_atoi(value[i].data + 5, len - 5); | |
5166
fc595eeb6c54
Limit req: rate should be non-zero.
Valentin Bartenev <vbart@nginx.com>
parents:
5117
diff
changeset
|
913 if (rate <= 0) { |
2294 | 914 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
915 "invalid rate \"%V\"", &value[i]); | |
916 return NGX_CONF_ERROR; | |
917 } | |
918 | |
919 continue; | |
920 } | |
921 | |
922 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
923 "invalid parameter \"%V\"", &value[i]); | |
987 | 924 return NGX_CONF_ERROR; |
925 } | |
926 | |
4417
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
927 if (name.len == 0) { |
2294 | 928 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
929 "\"%V\" must have \"zone\" parameter", | |
930 &cmd->name); | |
987 | 931 return NGX_CONF_ERROR; |
932 } | |
933 | |
2313 | 934 ctx->rate = rate * 1000 / scale; |
980 | 935 |
2294 | 936 shm_zone = ngx_shared_memory_add(cf, &name, size, |
937 &ngx_http_limit_req_module); | |
980 | 938 if (shm_zone == NULL) { |
939 return NGX_CONF_ERROR; | |
940 } | |
941 | |
987 | 942 if (shm_zone->data) { |
943 ctx = shm_zone->data; | |
944 | |
945 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
946 "%V \"%V\" is already bound to key \"%V\"", |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
947 &cmd->name, &name, &ctx->key.value); |
987 | 948 return NGX_CONF_ERROR; |
949 } | |
950 | |
2294 | 951 shm_zone->init = ngx_http_limit_req_init_zone; |
987 | 952 shm_zone->data = ctx; |
980 | 953 |
954 return NGX_CONF_OK; | |
955 } | |
956 | |
957 | |
958 static char * | |
2294 | 959 ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
980 | 960 { |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
961 ngx_http_limit_req_conf_t *lrcf = conf; |
980 | 962 |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
963 ngx_int_t burst, delay; |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
964 ngx_str_t *value, s; |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
965 ngx_uint_t i; |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
966 ngx_shm_zone_t *shm_zone; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
967 ngx_http_limit_req_limit_t *limit, *limits; |
980 | 968 |
969 value = cf->args->elts; | |
970 | |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
971 shm_zone = NULL; |
2294 | 972 burst = 0; |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
973 delay = 0; |
2294 | 974 |
975 for (i = 1; i < cf->args->nelts; i++) { | |
976 | |
977 if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { | |
978 | |
979 s.len = value[i].len - 5; | |
980 s.data = value[i].data + 5; | |
981 | |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
982 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
|
983 &ngx_http_limit_req_module); |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
984 if (shm_zone == NULL) { |
2294 | 985 return NGX_CONF_ERROR; |
986 } | |
987 | |
988 continue; | |
989 } | |
990 | |
991 if (ngx_strncmp(value[i].data, "burst=", 6) == 0) { | |
992 | |
2300
159136c9808d
*) correct leaky bucket implementation
Igor Sysoev <igor@sysoev.ru>
parents:
2294
diff
changeset
|
993 burst = ngx_atoi(value[i].data + 6, value[i].len - 6); |
2294 | 994 if (burst <= 0) { |
995 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
7398
bca4dad0d3cb
Limit req: fixed error message wording.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7281
diff
changeset
|
996 "invalid burst value \"%V\"", &value[i]); |
2294 | 997 return NGX_CONF_ERROR; |
998 } | |
999 | |
1000 continue; | |
1001 } | |
1002 | |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1003 if (ngx_strncmp(value[i].data, "delay=", 6) == 0) { |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1004 |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1005 delay = ngx_atoi(value[i].data + 6, value[i].len - 6); |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1006 if (delay <= 0) { |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1007 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1008 "invalid delay value \"%V\"", &value[i]); |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1009 return NGX_CONF_ERROR; |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1010 } |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1011 |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1012 continue; |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1013 } |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1014 |
5411
5483d9e77b32
Limit req: fixed "nodelay" parsing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5166
diff
changeset
|
1015 if (ngx_strcmp(value[i].data, "nodelay") == 0) { |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1016 delay = NGX_MAX_INT_T_VALUE / 1000; |
2294 | 1017 continue; |
1018 } | |
1019 | |
1020 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1021 "invalid parameter \"%V\"", &value[i]); | |
980 | 1022 return NGX_CONF_ERROR; |
1023 } | |
1024 | |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1025 if (shm_zone == NULL) { |
980 | 1026 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
2294 | 1027 "\"%V\" must have \"zone\" parameter", |
1028 &cmd->name); | |
980 | 1029 return NGX_CONF_ERROR; |
1030 } | |
1031 | |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1032 limits = lrcf->limits.elts; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1033 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1034 if (limits == NULL) { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1035 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
|
1036 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
|
1037 != NGX_OK) |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1038 { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1039 return NGX_CONF_ERROR; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1040 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1041 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1042 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1043 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
|
1044 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
|
1045 return "is duplicate"; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1046 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1047 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1048 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1049 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
|
1050 if (limit == NULL) { |
21d1e3bcb356
Added three missing checks for NULL after ngx_array_push() calls.
Valentin Bartenev <vbart@nginx.com>
parents:
4499
diff
changeset
|
1051 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
|
1052 } |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1053 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1054 limit->shm_zone = shm_zone; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1055 limit->burst = burst * 1000; |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1056 limit->delay = delay * 1000; |
980 | 1057 |
1058 return NGX_CONF_OK; | |
1059 } | |
1060 | |
1061 | |
1062 static ngx_int_t | |
7592
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1063 ngx_http_limit_req_add_variables(ngx_conf_t *cf) |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1064 { |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1065 ngx_http_variable_t *var, *v; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1066 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1067 for (v = ngx_http_limit_req_vars; v->name.len; v++) { |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1068 var = ngx_http_add_variable(cf, &v->name, v->flags); |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1069 if (var == NULL) { |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1070 return NGX_ERROR; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1071 } |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1072 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1073 var->get_handler = v->get_handler; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1074 var->data = v->data; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1075 } |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1076 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1077 return NGX_OK; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1078 } |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1079 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1080 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1081 static ngx_int_t |
2294 | 1082 ngx_http_limit_req_init(ngx_conf_t *cf) |
980 | 1083 { |
1084 ngx_http_handler_pt *h; | |
1085 ngx_http_core_main_conf_t *cmcf; | |
1086 | |
1087 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | |
1088 | |
1089 h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers); | |
1090 if (h == NULL) { | |
1091 return NGX_ERROR; | |
1092 } | |
1093 | |
2294 | 1094 *h = ngx_http_limit_req_handler; |
980 | 1095 |
1096 return NGX_OK; | |
1097 } |