Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_limit_req_module.c @ 8618:6a383020d61e quic
HTTP/3: make ngx_http_log_error() static again.
This function was only referenced from ngx_http_v3_create_push_request() to
initialize push connection log. Now the log handler is copied from the parent
request connection.
The change reduces diff to the default branch.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Fri, 17 Sep 2021 16:32:23 +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 } |