annotate src/http/modules/ngx_http_limit_req_module.c @ 9274:46ecad404a29 default tip

Mail: reset imap tag to empty after authentication attempt. We need to reset the imap tag to empty after an authentication attempt completes, otherwise if the next line parsed is incomplete with no tag (e.g. empty line) then we use the "tag" from the previous buffer which is now definitely wrong and has been partially overwritten with the most recently read data (e.g. CRLF). An example before this patch: S: * OK IMAP4 ready C: foobar login a b S: foobar NO Incorrect username or password. C: S: S: obar BAD invalid command Then with this patch: S: * OK IMAP4 ready C: foobar login a b S: foobar NO Incorrect username or password. C: S: * BAD invalid command
author Rob Mueller <robm@fastmailteam.com>
date Wed, 15 May 2024 10:06:00 +0300
parents 1ebd78df4ce7
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
2 /*
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
3 * Copyright (C) Igor Sysoev
4412
d620f497c50f Copyright updated.
Maxim Konovalov <maxim@nginx.com>
parents: 4399
diff changeset
4 * Copyright (C) Nginx, Inc.
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
5 */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
6
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
7
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
8 #include <ngx_config.h>
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
9 #include <ngx_core.h>
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
10 #include <ngx_http.h>
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
11
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
12
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
30 } ngx_http_limit_req_node_t;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
31
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
32
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
47 } ngx_http_limit_req_ctx_t;
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
48
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
49
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
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
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
60 ngx_uint_t limit_log_level;
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
64 } ngx_http_limit_req_conf_t;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
65
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
66
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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);
7726
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
74 static void ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx,
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
75 ngx_uint_t n);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
79 static void *ngx_http_limit_req_create_conf(ngx_conf_t *cf);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
80 static char *ngx_http_limit_req_merge_conf(ngx_conf_t *cf, void *parent,
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
81 void *child);
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
82 static char *ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd,
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
83 void *conf);
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
84 static char *ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd,
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
87 static ngx_int_t ngx_http_limit_req_init(ngx_conf_t *cf);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
88
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
89
3185
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
90 static ngx_conf_enum_t ngx_http_limit_req_log_levels[] = {
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
91 { ngx_string("info"), NGX_LOG_INFO },
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
92 { ngx_string("notice"), NGX_LOG_NOTICE },
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
93 { ngx_string("warn"), NGX_LOG_WARN },
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
94 { ngx_string("error"), NGX_LOG_ERR },
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
95 { ngx_null_string, 0 }
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
96 };
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
97
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
104 static ngx_command_t ngx_http_limit_req_commands[] = {
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
105
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
106 { ngx_string("limit_req_zone"),
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
107 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE3,
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
108 ngx_http_limit_req_zone,
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
109 0,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
110 0,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
111 NULL },
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
112
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
113 { ngx_string("limit_req"),
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
114 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
115 ngx_http_limit_req,
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
116 NGX_HTTP_LOC_CONF_OFFSET,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
117 0,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
118 NULL },
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
119
3185
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
120 { ngx_string("limit_req_log_level"),
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
121 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
122 ngx_conf_set_enum_slot,
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
123 NGX_HTTP_LOC_CONF_OFFSET,
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
124 offsetof(ngx_http_limit_req_conf_t, limit_log_level),
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
125 &ngx_http_limit_req_log_levels },
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
141 ngx_null_command
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
142 };
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
143
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
144
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
147 ngx_http_limit_req_init, /* postconfiguration */
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
148
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
149 NULL, /* create main configuration */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
150 NULL, /* init main configuration */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
151
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
152 NULL, /* create server configuration */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
153 NULL, /* merge server configuration */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
157 };
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
158
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
159
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
160 ngx_module_t ngx_http_limit_req_module = {
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
161 NGX_MODULE_V1,
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
162 &ngx_http_limit_req_module_ctx, /* module context */
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
163 ngx_http_limit_req_commands, /* module directives */
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
164 NGX_HTTP_MODULE, /* module type */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
165 NULL, /* init master */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
166 NULL, /* init module */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
167 NULL, /* init process */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
168 NULL, /* init thread */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
169 NULL, /* exit thread */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
170 NULL, /* exit process */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
171 NULL, /* exit master */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
172 NGX_MODULE_V1_PADDING
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
173 };
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
174
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
194 static ngx_int_t
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
195 ngx_http_limit_req_handler(ngx_http_request_t *r)
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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) {
7726
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
260 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7726
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
286 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
299 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
7811
1ebd78df4ce7 Fixed handling of already closed connections.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7726
diff changeset
313 if (r->connection->read->ready) {
1ebd78df4ce7 Fixed handling of already closed connections.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7726
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: 7726
diff changeset
315
1ebd78df4ce7 Fixed handling of already closed connections.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7726
diff changeset
316 } else {
1ebd78df4ce7 Fixed handling of already closed connections.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7726
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: 7726
diff changeset
318 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1ebd78df4ce7 Fixed handling of already closed connections.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7726
diff changeset
319 }
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
320 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
329 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
330
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
331
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
332 static void
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
333 ngx_http_limit_req_delay(ngx_http_request_t *r)
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
337 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2973
70c8b2d28d1d style fix
Igor Sysoev <igor@sysoev.ru>
parents: 2972
diff changeset
338 "limit_req delay");
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
351 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
352 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
353 return;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
354 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
355
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
356 r->read_event_handler = ngx_http_block_reading;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
357 r->write_event_handler = ngx_http_core_run_phases;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
358
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
359 ngx_http_core_run_phases(r);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
360 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
361
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
362
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
363 static void
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
b56a9ba4824d use integer instead of float
Igor Sysoev <igor@sysoev.ru>
parents: 2312
diff changeset
409 ngx_int_t rc, excess;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
410 ngx_msec_t now;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
411 ngx_msec_int_t ms;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
412 ngx_rbtree_node_t *node, *sentinel;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
422
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
423 while (node != sentinel) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
424
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
425 if (hash < node->key) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
426 node = node->left;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
427 continue;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
428 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
429
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
430 if (hash > node->key) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
431 node = node->right;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
432 continue;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
433 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
434
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
435 /* hash == node->key */
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
30f841e2536d fix r3184
Igor Sysoev <igor@sysoev.ru>
parents: 3185
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
458 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
484 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
606 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
607
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
608
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
609 static void
7726
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
633 ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, ngx_uint_t n)
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
634 {
2313
b56a9ba4824d use integer instead of float
Igor Sysoev <igor@sysoev.ru>
parents: 2312
diff changeset
635 ngx_int_t excess;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
636 ngx_msec_t now;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
637 ngx_queue_t *q;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
638 ngx_msec_int_t ms;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
641
6653
7a6456398fc3 Simplified extraction of current time.
Ruslan Ermilov <ru@nginx.com>
parents: 6117
diff changeset
642 now = ngx_current_msec;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
643
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
644 /*
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
645 * n == 1 deletes one or two zero rate entries
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
646 * n == 0 deletes oldest entry by force
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
647 * and one or two zero rate entries
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
648 */
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
649
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
650 while (n < 3) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
651
2720
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
652 if (ngx_queue_empty(&ctx->sh->queue)) {
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
653 return;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
654 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
670 if (n++ != 0) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
673 ms = ngx_abs(ms);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
674
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
675 if (ms < 60000) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
676 return;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
677 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
680
2313
b56a9ba4824d use integer instead of float
Igor Sysoev <igor@sysoev.ru>
parents: 2312
diff changeset
681 if (excess > 0) {
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
682 return;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
683 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
684 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
685
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
686 ngx_queue_remove(q);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
687
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
692
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
693 ngx_slab_free_locked(ctx->shpool, node);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
694 }
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
695 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
696
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
697
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
698 static ngx_int_t
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
699 ngx_http_limit_req_init_zone(ngx_shm_zone_t *shm_zone, void *data)
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
700 {
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
704 ngx_http_limit_req_ctx_t *ctx;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
728 ctx->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
734 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
738 return NGX_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
739 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
744 ngx_http_limit_req_rbtree_insert_value);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
760 return NGX_OK;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
761 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
762
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
783 static void *
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
784 ngx_http_limit_req_create_conf(ngx_conf_t *cf)
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
785 {
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
786 ngx_http_limit_req_conf_t *conf;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
787
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
788 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_req_conf_t));
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
791 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
792
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
793 /*
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
794 * set by ngx_pcalloc():
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
797 */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
798
3185
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
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
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
802
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
803 return conf;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
804 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
805
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
806
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
807 static char *
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
808 ngx_http_limit_req_merge_conf(ngx_conf_t *cf, void *parent, void *child)
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
809 {
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
810 ngx_http_limit_req_conf_t *prev = parent;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
811 ngx_http_limit_req_conf_t *conf = child;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
815 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
816
3185
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
817 ngx_conf_merge_uint_value(conf->limit_log_level, prev->limit_log_level,
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
818 NGX_LOG_ERR);
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
819
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
820 conf->delay_log_level = (conf->limit_log_level == NGX_LOG_INFO) ?
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
821 NGX_LOG_INFO : conf->limit_log_level + 1;
30570a5b9bb0 limit_req_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 3183
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
828 return NGX_CONF_OK;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
829 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
830
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
831
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
832 static char *
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
833 ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
844
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
845 value = cf->args->elts;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
862 size = 0;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
863 rate = 1;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
864 scale = 1;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
865 name.len = 0;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
868
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
869 if (ngx_strncmp(value[i].data, "zone=", 5) == 0) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
870
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
871 name.data = value[i].data + 5;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
872
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
873 p = (u_char *) ngx_strchr(name.data, ':');
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
879 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
901 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
902
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
903 if (ngx_strncmp(value[i].data, "rate=", 5) == 0) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
904
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
905 len = value[i].len;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
906 p = value[i].data + len - 3;
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
907
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
908 if (ngx_strncmp(p, "r/s", 3) == 0) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
909 scale = 1;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
910 len -= 3;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
911
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
912 } else if (ngx_strncmp(p, "r/m", 3) == 0) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
913 scale = 60;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
914 len -= 3;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
915 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
916
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
919 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
920 "invalid rate \"%V\"", &value[i]);
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
921 return NGX_CONF_ERROR;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
922 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
923
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
924 continue;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
925 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
926
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
927 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
928 "invalid parameter \"%V\"", &value[i]);
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
929 return NGX_CONF_ERROR;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
930 }
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
933 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
934 "\"%V\" must have \"zone\" parameter",
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
935 &cmd->name);
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
936 return NGX_CONF_ERROR;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
937 }
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
938
2313
b56a9ba4824d use integer instead of float
Igor Sysoev <igor@sysoev.ru>
parents: 2312
diff changeset
939 ctx->rate = rate * 1000 / scale;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
940
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
941 shm_zone = ngx_shared_memory_add(cf, &name, size,
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
942 &ngx_http_limit_req_module);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
943 if (shm_zone == NULL) {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
944 return NGX_CONF_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
945 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
946
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
947 if (shm_zone->data) {
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
948 ctx = shm_zone->data;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
949
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
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
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
953 return NGX_CONF_ERROR;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
954 }
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
955
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
956 shm_zone->init = ngx_http_limit_req_init_zone;
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
957 shm_zone->data = ctx;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
958
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
959 return NGX_CONF_OK;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
960 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
961
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
962
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
963 static char *
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
964 ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
973
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
974 value = cf->args->elts;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
977 burst = 0;
7399
d6ca744c727e Limit req: "delay=" parameter.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7398
diff changeset
978 delay = 0;
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
979
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
980 for (i = 1; i < cf->args->nelts; i++) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
981
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
982 if (ngx_strncmp(value[i].data, "zone=", 5) == 0) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
983
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
984 s.len = value[i].len - 5;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
985 s.data = value[i].data + 5;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
990 return NGX_CONF_ERROR;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
991 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
992
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
993 continue;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
994 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
995
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
996 if (ngx_strncmp(value[i].data, "burst=", 6) == 0) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
999 if (burst <= 0) {
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
1002 return NGX_CONF_ERROR;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
1003 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
1004
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
1005 continue;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
1006 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
1022 continue;
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
1023 }
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
1024
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
1025 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
1026 "invalid parameter \"%V\"", &value[i]);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1027 return NGX_CONF_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1028 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1031 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
1032 "\"%V\" must have \"zone\" parameter",
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
1033 &cmd->name);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1034 return NGX_CONF_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1035 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1062
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1063 return NGX_CONF_OK;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1064 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1065
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1066
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
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
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
1087 ngx_http_limit_req_init(ngx_conf_t *cf)
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1088 {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1089 ngx_http_handler_pt *h;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1090 ngx_http_core_main_conf_t *cmcf;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1091
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1092 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1093
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1094 h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1095 if (h == NULL) {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1096 return NGX_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1097 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1098
2294
ce574b0ffeec ngx_http_limit_req_module
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
1099 *h = ngx_http_limit_req_handler;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1100
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1101 return NGX_OK;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1102 }