annotate src/http/modules/ngx_http_limit_req_module.c @ 7676:d225b70d38b6

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