Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_limit_req_module.c @ 8546:d80365ca678d quic
HTTP/3: require mandatory uni streams before additional ones.
As per quic-http-34:
Endpoints SHOULD create the HTTP control stream as well as the
unidirectional streams required by mandatory extensions (such as the
QPACK encoder and decoder streams) first, and then create additional
streams as allowed by their peer.
Previously, client could create and destroy additional uni streams unlimited
number of times before creating mandatory streams.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Thu, 29 Jul 2021 10:03:36 +0300 |
parents | 1ebd78df4ce7 |
children |
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 |
8374
1ebd78df4ce7
Fixed handling of already closed connections.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8179
diff
changeset
|
313 if (r->connection->read->ready) { |
1ebd78df4ce7
Fixed handling of already closed connections.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8179
diff
changeset
|
314 ngx_post_event(r->connection->read, &ngx_posted_events); |
1ebd78df4ce7
Fixed handling of already closed connections.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8179
diff
changeset
|
315 |
1ebd78df4ce7
Fixed handling of already closed connections.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8179
diff
changeset
|
316 } else { |
1ebd78df4ce7
Fixed handling of already closed connections.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8179
diff
changeset
|
317 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { |
1ebd78df4ce7
Fixed handling of already closed connections.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8179
diff
changeset
|
318 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
1ebd78df4ce7
Fixed handling of already closed connections.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8179
diff
changeset
|
319 } |
2294 | 320 } |
321 | |
3780
d94d7104f598
change order of limit_req lookup result processing
Igor Sysoev <igor@sysoev.ru>
parents:
3779
diff
changeset
|
322 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
|
323 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
|
324 |
7fcf209d40c8
Limit req: fixed delaying subrequests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6653
diff
changeset
|
325 r->connection->write->delayed = 1; |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
326 ngx_add_timer(r->connection->write, delay); |
2294 | 327 |
3780
d94d7104f598
change order of limit_req lookup result processing
Igor Sysoev <igor@sysoev.ru>
parents:
3779
diff
changeset
|
328 return NGX_AGAIN; |
980 | 329 } |
330 | |
331 | |
332 static void | |
2294 | 333 ngx_http_limit_req_delay(ngx_http_request_t *r) |
334 { | |
2972
c5ad288f851d
fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
335 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
|
336 |
2294 | 337 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2973 | 338 "limit_req delay"); |
2294 | 339 |
2972
c5ad288f851d
fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
340 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
|
341 |
6961
903fb1ddc07f
Moved handling of wev->delayed to the connection event handler.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6959
diff
changeset
|
342 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
|
343 |
c5ad288f851d
fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
344 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
|
345 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
|
346 } |
c5ad288f851d
fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
347 |
c5ad288f851d
fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
348 return; |
c5ad288f851d
fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
349 } |
c5ad288f851d
fix client write event handling in ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
350 |
2294 | 351 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { |
352 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
353 return; | |
354 } | |
355 | |
356 r->read_event_handler = ngx_http_block_reading; | |
357 r->write_event_handler = ngx_http_core_run_phases; | |
358 | |
359 ngx_http_core_run_phases(r); | |
360 } | |
361 | |
362 | |
363 static void | |
364 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
|
365 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
|
366 { |
2294 | 367 ngx_rbtree_node_t **p; |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
368 ngx_http_limit_req_node_t *lrn, *lrnt; |
1026
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
369 |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
370 for ( ;; ) { |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
371 |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
372 if (node->key < temp->key) { |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
373 |
1743
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1406
diff
changeset
|
374 p = &temp->left; |
1026
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
375 |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
376 } else if (node->key > temp->key) { |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
377 |
1743
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1406
diff
changeset
|
378 p = &temp->right; |
1026
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
379 |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
380 } else { /* node->key == temp->key */ |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
381 |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
382 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
|
383 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
|
384 |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
385 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
|
386 ? &temp->left : &temp->right; |
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1406
diff
changeset
|
387 } |
1026
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
388 |
1743
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1406
diff
changeset
|
389 if (*p == sentinel) { |
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1406
diff
changeset
|
390 break; |
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1406
diff
changeset
|
391 } |
1026
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
392 |
1743
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1406
diff
changeset
|
393 temp = *p; |
1026
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
394 } |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
395 |
1743
4fc402c3ec73
optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents:
1406
diff
changeset
|
396 *p = node; |
1026
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
397 node->parent = temp; |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
398 node->left = sentinel; |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
399 node->right = sentinel; |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
400 ngx_rbt_red(node); |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
401 } |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
402 |
38be15c1379a
fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents:
1012
diff
changeset
|
403 |
2294 | 404 static ngx_int_t |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
405 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
|
406 ngx_str_t *key, ngx_uint_t *ep, ngx_uint_t account) |
980 | 407 { |
4418
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
408 size_t size; |
2313 | 409 ngx_int_t rc, excess; |
2294 | 410 ngx_msec_t now; |
411 ngx_msec_int_t ms; | |
412 ngx_rbtree_node_t *node, *sentinel; | |
413 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
|
414 ngx_http_limit_req_node_t *lr; |
2294 | 415 |
6653
7a6456398fc3
Simplified extraction of current time.
Ruslan Ermilov <ru@nginx.com>
parents:
6117
diff
changeset
|
416 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
|
417 |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
418 ctx = limit->shm_zone->data; |
2294 | 419 |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
420 node = ctx->sh->rbtree.root; |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
421 sentinel = ctx->sh->rbtree.sentinel; |
980 | 422 |
2294 | 423 while (node != sentinel) { |
424 | |
425 if (hash < node->key) { | |
426 node = node->left; | |
427 continue; | |
428 } | |
429 | |
430 if (hash > node->key) { | |
431 node = node->right; | |
432 continue; | |
433 } | |
434 | |
435 /* hash == node->key */ | |
436 | |
4497
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
437 lr = (ngx_http_limit_req_node_t *) &node->color; |
2294 | 438 |
5863
102f85699420
Limit req: reduced number of parameters in the lookup function.
Valentin Bartenev <vbart@nginx.com>
parents:
5862
diff
changeset
|
439 rc = ngx_memn2cmp(key->data, lr->data, key->len, (size_t) lr->len); |
3191 | 440 |
4497
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
441 if (rc == 0) { |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
442 ngx_queue_remove(&lr->queue); |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
443 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
|
444 |
4497
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
445 ms = (ngx_msec_int_t) (now - lr->last); |
980 | 446 |
7281
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
447 if (ms < -60000) { |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
448 ms = 1; |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
449 |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
450 } else if (ms < 0) { |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
451 ms = 0; |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
452 } |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
453 |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
454 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
|
455 |
4497
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
456 if (excess < 0) { |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
457 excess = 0; |
2294 | 458 } |
459 | |
4497
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
460 *ep = excess; |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
461 |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
462 if ((ngx_uint_t) excess > limit->burst) { |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
463 return NGX_BUSY; |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
464 } |
2294 | 465 |
4497
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
466 if (account) { |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
467 lr->excess = excess; |
7281
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
468 |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
469 if (ms) { |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
470 lr->last = now; |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
471 } |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
472 |
4497
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
473 return NGX_OK; |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
474 } |
2294 | 475 |
4497
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
476 lr->count++; |
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 ctx->node = lr; |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
479 |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
480 return NGX_AGAIN; |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
481 } |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
482 |
95ab6658654a
Fix of rbtree lookup on hash collisions.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4424
diff
changeset
|
483 node = (rc < 0) ? node->left : node->right; |
980 | 484 } |
485 | |
3779
57aecfdcac3d
an excess was logged as 0.000 if requests were limited without delay:
Igor Sysoev <igor@sysoev.ru>
parents:
3525
diff
changeset
|
486 *ep = 0; |
2294 | 487 |
4418
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
488 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
|
489 + 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
|
490 + 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
|
491 |
4419
7084faa7a4b4
Limit req: number of cleanup calls reduced.
Valentin Bartenev <vbart@nginx.com>
parents:
4418
diff
changeset
|
492 ngx_http_limit_req_expire(ctx, 1); |
7084faa7a4b4
Limit req: number of cleanup calls reduced.
Valentin Bartenev <vbart@nginx.com>
parents:
4418
diff
changeset
|
493 |
4418
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 |
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
496 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
|
497 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
|
498 |
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
499 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
|
500 if (node == NULL) { |
5634
5024d29354f1
Core: slab log_nomem flag.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5411
diff
changeset
|
501 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
|
502 "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
|
503 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
|
504 } |
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
505 } |
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
506 |
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
507 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
|
508 |
aac79fc948cc
Limit req: allocation and initialization of a new node moved to the lookup
Valentin Bartenev <vbart@nginx.com>
parents:
4417
diff
changeset
|
509 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
|
510 |
5863
102f85699420
Limit req: reduced number of parameters in the lookup function.
Valentin Bartenev <vbart@nginx.com>
parents:
5862
diff
changeset
|
511 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
|
512 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
|
513 |
5863
102f85699420
Limit req: reduced number of parameters in the lookup function.
Valentin Bartenev <vbart@nginx.com>
parents:
5862
diff
changeset
|
514 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
|
515 |
4832
949ea3d3cd1a
Limit req: fix of rbtree node insertion on hash collisions.
Valentin Bartenev <vbart@nginx.com>
parents:
4811
diff
changeset
|
516 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
|
517 |
949ea3d3cd1a
Limit req: fix of rbtree node insertion on hash collisions.
Valentin Bartenev <vbart@nginx.com>
parents:
4811
diff
changeset
|
518 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
|
519 |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
520 if (account) { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
521 lr->last = now; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
522 lr->count = 0; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
523 return NGX_OK; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
524 } |
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 lr->last = 0; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
527 lr->count = 1; |
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 ctx->node = lr; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
530 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
531 return NGX_AGAIN; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
532 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
533 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
534 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
535 static ngx_msec_t |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
536 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
|
537 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
|
538 { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
539 ngx_int_t excess; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
540 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
|
541 ngx_msec_int_t ms; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
542 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
|
543 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
|
544 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
545 excess = *ep; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
546 |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
547 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
|
548 max_delay = 0; |
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 } else { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
551 ctx = (*limit)->shm_zone->data; |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
552 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
|
553 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
554 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
555 while (n--) { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
556 ctx = limits[n].shm_zone->data; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
557 lr = ctx->node; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
558 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
559 if (lr == NULL) { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
560 continue; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
561 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
562 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
563 ngx_shmtx_lock(&ctx->shpool->mutex); |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
564 |
6653
7a6456398fc3
Simplified extraction of current time.
Ruslan Ermilov <ru@nginx.com>
parents:
6117
diff
changeset
|
565 now = ngx_current_msec; |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
566 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
|
567 |
7281
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
568 if (ms < -60000) { |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
569 ms = 1; |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
570 |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
571 } else if (ms < 0) { |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
572 ms = 0; |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
573 } |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
574 |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
575 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
|
576 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
577 if (excess < 0) { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
578 excess = 0; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
579 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
580 |
7281
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
581 if (ms) { |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
582 lr->last = now; |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
583 } |
bd6563e81cea
Limit req: improved handling of negative times.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6961
diff
changeset
|
584 |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
585 lr->excess = excess; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
586 lr->count--; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
587 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
588 ngx_shmtx_unlock(&ctx->shpool->mutex); |
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 ctx->node = NULL; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
591 |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
592 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
|
593 continue; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
594 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
595 |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
596 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
|
597 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
598 if (delay > max_delay) { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
599 max_delay = delay; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
600 *ep = excess; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
601 *limit = &limits[n]; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
602 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
603 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
604 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
605 return max_delay; |
2294 | 606 } |
607 | |
608 | |
609 static void | |
8179
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
610 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
|
611 { |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
612 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
|
613 |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
614 while (n--) { |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
615 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
|
616 |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
617 if (ctx->node == NULL) { |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
618 continue; |
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 |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
621 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
|
622 |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
623 ctx->node->count--; |
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 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
|
626 |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
627 ctx->node = NULL; |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
628 } |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
629 } |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
630 |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
631 |
559d19037984
Limit req: unlocking of nodes on complex value errors.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7592
diff
changeset
|
632 static void |
2294 | 633 ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, ngx_uint_t n) |
634 { | |
2313 | 635 ngx_int_t excess; |
2294 | 636 ngx_msec_t now; |
637 ngx_queue_t *q; | |
638 ngx_msec_int_t ms; | |
639 ngx_rbtree_node_t *node; | |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
640 ngx_http_limit_req_node_t *lr; |
2294 | 641 |
6653
7a6456398fc3
Simplified extraction of current time.
Ruslan Ermilov <ru@nginx.com>
parents:
6117
diff
changeset
|
642 now = ngx_current_msec; |
2294 | 643 |
644 /* | |
645 * n == 1 deletes one or two zero rate entries | |
646 * n == 0 deletes oldest entry by force | |
647 * and one or two zero rate entries | |
648 */ | |
649 | |
650 while (n < 3) { | |
651 | |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
652 if (ngx_queue_empty(&ctx->sh->queue)) { |
2294 | 653 return; |
654 } | |
655 | |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
656 q = ngx_queue_last(&ctx->sh->queue); |
2294 | 657 |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
658 lr = ngx_queue_data(q, ngx_http_limit_req_node_t, queue); |
2294 | 659 |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
660 if (lr->count) { |
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 /* |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
663 * 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
|
664 * 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
|
665 */ |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
666 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
667 return; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
668 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
669 |
2294 | 670 if (n++ != 0) { |
671 | |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
672 ms = (ngx_msec_int_t) (now - lr->last); |
2294 | 673 ms = ngx_abs(ms); |
674 | |
675 if (ms < 60000) { | |
676 return; | |
677 } | |
678 | |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
679 excess = lr->excess - ctx->rate * ms / 1000; |
2294 | 680 |
2313 | 681 if (excess > 0) { |
2294 | 682 return; |
683 } | |
684 } | |
685 | |
686 ngx_queue_remove(q); | |
687 | |
688 node = (ngx_rbtree_node_t *) | |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
689 ((u_char *) lr - offsetof(ngx_rbtree_node_t, color)); |
2294 | 690 |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
691 ngx_rbtree_delete(&ctx->sh->rbtree, node); |
2294 | 692 |
693 ngx_slab_free_locked(ctx->shpool, node); | |
694 } | |
980 | 695 } |
696 | |
697 | |
698 static ngx_int_t | |
2294 | 699 ngx_http_limit_req_init_zone(ngx_shm_zone_t *shm_zone, void *data) |
980 | 700 { |
2294 | 701 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
|
702 |
2611
2bce3f6416c6
improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents:
2376
diff
changeset
|
703 size_t len; |
2294 | 704 ngx_http_limit_req_ctx_t *ctx; |
980 | 705 |
993
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
706 ctx = shm_zone->data; |
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
707 |
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
708 if (octx) { |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
709 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
|
710 || 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
|
711 ctx->key.value.len) |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
712 != 0) |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
713 { |
993
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
714 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
|
715 "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
|
716 "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
|
717 &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
|
718 &octx->key.value); |
993
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
719 return NGX_ERROR; |
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
720 } |
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
721 |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
722 ctx->sh = octx->sh; |
2294 | 723 ctx->shpool = octx->shpool; |
993
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
724 |
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
725 return NGX_OK; |
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
726 } |
1b9a4d92173f
pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents:
987
diff
changeset
|
727 |
2294 | 728 ctx->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; |
980 | 729 |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
730 if (shm_zone->shm.exists) { |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
731 ctx->sh = ctx->shpool->data; |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
732 |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
733 return NGX_OK; |
980 | 734 } |
735 | |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
736 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
|
737 if (ctx->sh == NULL) { |
980 | 738 return NGX_ERROR; |
739 } | |
740 | |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
741 ctx->shpool->data = ctx->sh; |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
742 |
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
743 ngx_rbtree_init(&ctx->sh->rbtree, &ctx->sh->sentinel, |
2294 | 744 ngx_http_limit_req_rbtree_insert_value); |
745 | |
2720
b3b8c66bd520
support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents:
2716
diff
changeset
|
746 ngx_queue_init(&ctx->sh->queue); |
980 | 747 |
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
|
748 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
|
749 |
2bce3f6416c6
improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents:
2376
diff
changeset
|
750 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
|
751 if (ctx->shpool->log_ctx == NULL) { |
2bce3f6416c6
improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents:
2376
diff
changeset
|
752 return NGX_ERROR; |
2bce3f6416c6
improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents:
2376
diff
changeset
|
753 } |
2bce3f6416c6
improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents:
2376
diff
changeset
|
754 |
2bce3f6416c6
improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents:
2376
diff
changeset
|
755 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
|
756 &shm_zone->shm.name); |
2611
2bce3f6416c6
improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents:
2376
diff
changeset
|
757 |
5634
5024d29354f1
Core: slab log_nomem flag.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5411
diff
changeset
|
758 ctx->shpool->log_nomem = 0; |
5024d29354f1
Core: slab log_nomem flag.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5411
diff
changeset
|
759 |
980 | 760 return NGX_OK; |
761 } | |
762 | |
763 | |
7592
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
764 static ngx_int_t |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
765 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
|
766 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
|
767 { |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
768 if (r->main->limit_req_status == 0) { |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
769 v->not_found = 1; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
770 return NGX_OK; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
771 } |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
772 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
773 v->valid = 1; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
774 v->no_cacheable = 0; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
775 v->not_found = 0; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
776 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
|
777 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
|
778 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
779 return NGX_OK; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
780 } |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
781 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
782 |
980 | 783 static void * |
2294 | 784 ngx_http_limit_req_create_conf(ngx_conf_t *cf) |
980 | 785 { |
2294 | 786 ngx_http_limit_req_conf_t *conf; |
980 | 787 |
2294 | 788 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_req_conf_t)); |
980 | 789 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
|
790 return NULL; |
980 | 791 } |
792 | |
793 /* | |
794 * set by ngx_pcalloc(): | |
795 * | |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
796 * conf->limits.elts = NULL; |
980 | 797 */ |
798 | |
3185 | 799 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
|
800 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
|
801 conf->dry_run = NGX_CONF_UNSET; |
3185 | 802 |
980 | 803 return conf; |
804 } | |
805 | |
806 | |
807 static char * | |
2294 | 808 ngx_http_limit_req_merge_conf(ngx_conf_t *cf, void *parent, void *child) |
980 | 809 { |
2294 | 810 ngx_http_limit_req_conf_t *prev = parent; |
811 ngx_http_limit_req_conf_t *conf = child; | |
980 | 812 |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
813 if (conf->limits.elts == NULL) { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
814 conf->limits = prev->limits; |
980 | 815 } |
816 | |
3185 | 817 ngx_conf_merge_uint_value(conf->limit_log_level, prev->limit_log_level, |
818 NGX_LOG_ERR); | |
819 | |
820 conf->delay_log_level = (conf->limit_log_level == NGX_LOG_INFO) ? | |
821 NGX_LOG_INFO : conf->limit_log_level + 1; | |
822 | |
5117
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
823 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
|
824 NGX_HTTP_SERVICE_UNAVAILABLE); |
00e4459739ed
The limit_req_status and limit_conn_status directives.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4832
diff
changeset
|
825 |
7515
2db68852d6a0
Limit req: limit_req_dry_run directive.
Roman Arutyunyan <arut@nginx.com>
parents:
7399
diff
changeset
|
826 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
|
827 |
980 | 828 return NGX_CONF_OK; |
829 } | |
830 | |
831 | |
832 static char * | |
2294 | 833 ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
980 | 834 { |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
835 u_char *p; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
836 size_t len; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
837 ssize_t size; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
838 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
|
839 ngx_int_t rate, scale; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
840 ngx_uint_t i; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
841 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
|
842 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
|
843 ngx_http_compile_complex_value_t ccv; |
980 | 844 |
845 value = cf->args->elts; | |
846 | |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
847 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
|
848 if (ctx == NULL) { |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
849 return NGX_CONF_ERROR; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
850 } |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
851 |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
852 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
|
853 |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
854 ccv.cf = cf; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
855 ccv.value = &value[1]; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
856 ccv.complex_value = &ctx->key; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
857 |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
858 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
|
859 return NGX_CONF_ERROR; |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
860 } |
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
861 |
2294 | 862 size = 0; |
863 rate = 1; | |
864 scale = 1; | |
865 name.len = 0; | |
866 | |
5862
ecbb99aa0e12
Limit req: use complex value in limit_req_zone.
Valentin Bartenev <vbart@nginx.com>
parents:
5846
diff
changeset
|
867 for (i = 2; i < cf->args->nelts; i++) { |
2294 | 868 |
869 if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { | |
870 | |
871 name.data = value[i].data + 5; | |
872 | |
873 p = (u_char *) ngx_strchr(name.data, ':'); | |
874 | |
4417
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
875 if (p == NULL) { |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
876 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
|
877 "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
|
878 return NGX_CONF_ERROR; |
2294 | 879 } |
880 | |
4417
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
881 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
|
882 |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
883 s.data = p + 1; |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
884 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
|
885 |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
886 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
|
887 |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
888 if (size == NGX_ERROR) { |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
889 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
|
890 "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
|
891 return NGX_CONF_ERROR; |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
892 } |
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 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
|
895 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
|
896 "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
|
897 return NGX_CONF_ERROR; |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
898 } |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
899 |
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
900 continue; |
2294 | 901 } |
902 | |
903 if (ngx_strncmp(value[i].data, "rate=", 5) == 0) { | |
904 | |
905 len = value[i].len; | |
906 p = value[i].data + len - 3; | |
987 | 907 |
2294 | 908 if (ngx_strncmp(p, "r/s", 3) == 0) { |
909 scale = 1; | |
910 len -= 3; | |
911 | |
912 } else if (ngx_strncmp(p, "r/m", 3) == 0) { | |
913 scale = 60; | |
914 len -= 3; | |
915 } | |
916 | |
917 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
|
918 if (rate <= 0) { |
2294 | 919 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
920 "invalid rate \"%V\"", &value[i]); | |
921 return NGX_CONF_ERROR; | |
922 } | |
923 | |
924 continue; | |
925 } | |
926 | |
927 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
928 "invalid parameter \"%V\"", &value[i]); | |
987 | 929 return NGX_CONF_ERROR; |
930 } | |
931 | |
4417
9e9d2e06f933
Limit req: improved error handling when parsing "zone" parameter of
Valentin Bartenev <vbart@nginx.com>
parents:
4416
diff
changeset
|
932 if (name.len == 0) { |
2294 | 933 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
934 "\"%V\" must have \"zone\" parameter", | |
935 &cmd->name); | |
987 | 936 return NGX_CONF_ERROR; |
937 } | |
938 | |
2313 | 939 ctx->rate = rate * 1000 / scale; |
980 | 940 |
2294 | 941 shm_zone = ngx_shared_memory_add(cf, &name, size, |
942 &ngx_http_limit_req_module); | |
980 | 943 if (shm_zone == NULL) { |
944 return NGX_CONF_ERROR; | |
945 } | |
946 | |
987 | 947 if (shm_zone->data) { |
948 ctx = shm_zone->data; | |
949 | |
950 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
|
951 "%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
|
952 &cmd->name, &name, &ctx->key.value); |
987 | 953 return NGX_CONF_ERROR; |
954 } | |
955 | |
2294 | 956 shm_zone->init = ngx_http_limit_req_init_zone; |
987 | 957 shm_zone->data = ctx; |
980 | 958 |
959 return NGX_CONF_OK; | |
960 } | |
961 | |
962 | |
963 static char * | |
2294 | 964 ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
980 | 965 { |
2374
7b11f9a1bfe1
rename "lz" to "lr" in variable names
Igor Sysoev <igor@sysoev.ru>
parents:
2313
diff
changeset
|
966 ngx_http_limit_req_conf_t *lrcf = conf; |
980 | 967 |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
968 ngx_int_t burst, delay; |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
969 ngx_str_t *value, s; |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
970 ngx_uint_t i; |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
971 ngx_shm_zone_t *shm_zone; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
972 ngx_http_limit_req_limit_t *limit, *limits; |
980 | 973 |
974 value = cf->args->elts; | |
975 | |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
976 shm_zone = NULL; |
2294 | 977 burst = 0; |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
978 delay = 0; |
2294 | 979 |
980 for (i = 1; i < cf->args->nelts; i++) { | |
981 | |
982 if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { | |
983 | |
984 s.len = value[i].len - 5; | |
985 s.data = value[i].data + 5; | |
986 | |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
987 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
|
988 &ngx_http_limit_req_module); |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
989 if (shm_zone == NULL) { |
2294 | 990 return NGX_CONF_ERROR; |
991 } | |
992 | |
993 continue; | |
994 } | |
995 | |
996 if (ngx_strncmp(value[i].data, "burst=", 6) == 0) { | |
997 | |
2300
159136c9808d
*) correct leaky bucket implementation
Igor Sysoev <igor@sysoev.ru>
parents:
2294
diff
changeset
|
998 burst = ngx_atoi(value[i].data + 6, value[i].len - 6); |
2294 | 999 if (burst <= 0) { |
1000 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
|
1001 "invalid burst value \"%V\"", &value[i]); |
2294 | 1002 return NGX_CONF_ERROR; |
1003 } | |
1004 | |
1005 continue; | |
1006 } | |
1007 | |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1008 if (ngx_strncmp(value[i].data, "delay=", 6) == 0) { |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1009 |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1010 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
|
1011 if (delay <= 0) { |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1012 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1013 "invalid delay value \"%V\"", &value[i]); |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1014 return NGX_CONF_ERROR; |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1015 } |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1016 |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1017 continue; |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1018 } |
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1019 |
5411
5483d9e77b32
Limit req: fixed "nodelay" parsing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5166
diff
changeset
|
1020 if (ngx_strcmp(value[i].data, "nodelay") == 0) { |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1021 delay = NGX_MAX_INT_T_VALUE / 1000; |
2294 | 1022 continue; |
1023 } | |
1024 | |
1025 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1026 "invalid parameter \"%V\"", &value[i]); | |
980 | 1027 return NGX_CONF_ERROR; |
1028 } | |
1029 | |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1030 if (shm_zone == NULL) { |
980 | 1031 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
2294 | 1032 "\"%V\" must have \"zone\" parameter", |
1033 &cmd->name); | |
980 | 1034 return NGX_CONF_ERROR; |
1035 } | |
1036 | |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1037 limits = lrcf->limits.elts; |
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 if (limits == NULL) { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1040 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
|
1041 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
|
1042 != NGX_OK) |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1043 { |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1044 return NGX_CONF_ERROR; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1045 } |
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 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
|
1049 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
|
1050 return "is duplicate"; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1051 } |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1052 } |
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 = 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
|
1055 if (limit == NULL) { |
21d1e3bcb356
Added three missing checks for NULL after ngx_array_push() calls.
Valentin Bartenev <vbart@nginx.com>
parents:
4499
diff
changeset
|
1056 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
|
1057 } |
4420
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1058 |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1059 limit->shm_zone = shm_zone; |
9ce48f9eb85b
Limit req: support for multiple "limit_req" limits.
Valentin Bartenev <vbart@nginx.com>
parents:
4419
diff
changeset
|
1060 limit->burst = burst * 1000; |
7399
d6ca744c727e
Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7398
diff
changeset
|
1061 limit->delay = delay * 1000; |
980 | 1062 |
1063 return NGX_CONF_OK; | |
1064 } | |
1065 | |
1066 | |
1067 static ngx_int_t | |
7592
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1068 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
|
1069 { |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1070 ngx_http_variable_t *var, *v; |
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 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
|
1073 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
|
1074 if (var == NULL) { |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1075 return NGX_ERROR; |
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 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1078 var->get_handler = v->get_handler; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1079 var->data = v->data; |
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 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1082 return NGX_OK; |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1083 } |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1084 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1085 |
776d1bebdca2
Limit req: $limit_req_status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
7515
diff
changeset
|
1086 static ngx_int_t |
2294 | 1087 ngx_http_limit_req_init(ngx_conf_t *cf) |
980 | 1088 { |
1089 ngx_http_handler_pt *h; | |
1090 ngx_http_core_main_conf_t *cmcf; | |
1091 | |
1092 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | |
1093 | |
1094 h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers); | |
1095 if (h == NULL) { | |
1096 return NGX_ERROR; | |
1097 } | |
1098 | |
2294 | 1099 *h = ngx_http_limit_req_handler; |
980 | 1100 |
1101 return NGX_OK; | |
1102 } |