annotate src/http/modules/ngx_http_limit_zone_module.c @ 4515:8bb695c05870 stable-1.0

Merge of r4498: Fix of rbtree lookup on hash collisions. Previous code incorrectly assumed that nodes with identical keys are linked together. This might not be true after tree rebalance. Patch by Lanshun Zhou.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 05 Mar 2012 13:17:56 +0000
parents 4919fb357a5d
children 50143b8fb95f
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
4450
4919fb357a5d Merge of r4406, r4413: copyrights updated.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4440
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
13 typedef struct {
981
6fe76f377a62 fix key length and alignment
Igor Sysoev <igor@sysoev.ru>
parents: 980
diff changeset
14 u_char color;
6fe76f377a62 fix key length and alignment
Igor Sysoev <igor@sysoev.ru>
parents: 980
diff changeset
15 u_char len;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
16 u_short conn;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
17 u_char data[1];
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
18 } ngx_http_limit_zone_node_t;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
19
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
20
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
21 typedef struct {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
22 ngx_shm_zone_t *shm_zone;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
23 ngx_rbtree_node_t *node;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
24 } ngx_http_limit_zone_cleanup_t;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
25
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
26
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
27 typedef struct {
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
28 ngx_rbtree_t *rbtree;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
29 ngx_int_t index;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
30 ngx_str_t var;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
31 } ngx_http_limit_zone_ctx_t;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
32
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
33
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
34 typedef struct {
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
35 ngx_shm_zone_t *shm_zone;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
36 ngx_uint_t conn;
3186
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
37 ngx_uint_t log_level;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
38 } ngx_http_limit_zone_conf_t;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
39
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
40
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
41 static void ngx_http_limit_zone_cleanup(void *data);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
42
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
43 static void *ngx_http_limit_zone_create_conf(ngx_conf_t *cf);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
44 static char *ngx_http_limit_zone_merge_conf(ngx_conf_t *cf, void *parent,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
45 void *child);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
46 static char *ngx_http_limit_zone(ngx_conf_t *cf, ngx_command_t *cmd,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
47 void *conf);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
48 static char *ngx_http_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
49 void *conf);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
50 static ngx_int_t ngx_http_limit_zone_init(ngx_conf_t *cf);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
51
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
52
3186
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
53 static ngx_conf_enum_t ngx_http_limit_conn_log_levels[] = {
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
54 { ngx_string("info"), NGX_LOG_INFO },
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
55 { ngx_string("notice"), NGX_LOG_NOTICE },
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
56 { ngx_string("warn"), NGX_LOG_WARN },
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
57 { ngx_string("error"), NGX_LOG_ERR },
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
58 { ngx_null_string, 0 }
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
59 };
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
60
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
61
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
62 static ngx_command_t ngx_http_limit_zone_commands[] = {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
63
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
64 { ngx_string("limit_zone"),
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
65 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE3,
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
66 ngx_http_limit_zone,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
67 0,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
68 0,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
69 NULL },
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
70
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
71 { ngx_string("limit_conn"),
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
72 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
73 ngx_http_limit_conn,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
74 NGX_HTTP_LOC_CONF_OFFSET,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
75 0,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
76 NULL },
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
77
3186
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
78 { ngx_string("limit_conn_log_level"),
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
79 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
80 ngx_conf_set_enum_slot,
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
81 NGX_HTTP_LOC_CONF_OFFSET,
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
82 offsetof(ngx_http_limit_zone_conf_t, log_level),
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
83 &ngx_http_limit_conn_log_levels },
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
84
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
85 ngx_null_command
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
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
88
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
89 static ngx_http_module_t ngx_http_limit_zone_module_ctx = {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
90 NULL, /* preconfiguration */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
91 ngx_http_limit_zone_init, /* postconfiguration */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
92
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
93 NULL, /* create main configuration */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
94 NULL, /* init main configuration */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
95
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
96 NULL, /* create server configuration */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
97 NULL, /* merge server configuration */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
98
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
99 ngx_http_limit_zone_create_conf, /* create location configration */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
100 ngx_http_limit_zone_merge_conf /* merge location configration */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
101 };
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
102
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
103
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
104 ngx_module_t ngx_http_limit_zone_module = {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
105 NGX_MODULE_V1,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
106 &ngx_http_limit_zone_module_ctx, /* module context */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
107 ngx_http_limit_zone_commands, /* module directives */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
108 NGX_HTTP_MODULE, /* module type */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
109 NULL, /* init master */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
110 NULL, /* init module */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
111 NULL, /* init process */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
112 NULL, /* init thread */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
113 NULL, /* exit thread */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
114 NULL, /* exit process */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
115 NULL, /* exit master */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
116 NGX_MODULE_V1_PADDING
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
117 };
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
118
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
119
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
120 static ngx_int_t
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
121 ngx_http_limit_zone_handler(ngx_http_request_t *r)
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
122 {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
123 size_t len, n;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
124 uint32_t hash;
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
125 ngx_int_t rc;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
126 ngx_slab_pool_t *shpool;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
127 ngx_rbtree_node_t *node, *sentinel;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
128 ngx_pool_cleanup_t *cln;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
129 ngx_http_variable_value_t *vv;
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
130 ngx_http_limit_zone_ctx_t *ctx;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
131 ngx_http_limit_zone_node_t *lz;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
132 ngx_http_limit_zone_conf_t *lzcf;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
133 ngx_http_limit_zone_cleanup_t *lzcln;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
134
997
5900ec20604a do not count connection for subrequest
Igor Sysoev <igor@sysoev.ru>
parents: 993
diff changeset
135 if (r->main->limit_zone_set) {
984
dd128232e6ba count connection once per request
Igor Sysoev <igor@sysoev.ru>
parents: 981
diff changeset
136 return NGX_DECLINED;
dd128232e6ba count connection once per request
Igor Sysoev <igor@sysoev.ru>
parents: 981
diff changeset
137 }
dd128232e6ba count connection once per request
Igor Sysoev <igor@sysoev.ru>
parents: 981
diff changeset
138
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
139 lzcf = ngx_http_get_module_loc_conf(r, ngx_http_limit_zone_module);
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 if (lzcf->shm_zone == NULL) {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
142 return NGX_DECLINED;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
143 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
144
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
145 ctx = lzcf->shm_zone->data;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
146
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
147 vv = ngx_http_get_indexed_variable(r, ctx->index);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
148
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
149 if (vv == NULL || vv->not_found) {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
150 return NGX_DECLINED;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
151 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
152
1011
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
153 len = vv->len;
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
154
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
155 if (len == 0) {
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
156 return NGX_DECLINED;
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
157 }
984
dd128232e6ba count connection once per request
Igor Sysoev <igor@sysoev.ru>
parents: 981
diff changeset
158
1011
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
159 if (len > 255) {
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
160 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
161 "the value of the \"%V\" variable "
1406
03341711f9a2 use %v for ngx_variable_value_t in ngx_sprintf(),
Igor Sysoev <igor@sysoev.ru>
parents: 1036
diff changeset
162 "is more than 255 bytes: \"%v\"",
1011
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
163 &ctx->var, vv);
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
164 return NGX_DECLINED;
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
165 }
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
166
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
167 r->main->limit_zone_set = 1;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
168
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
169 hash = ngx_crc32_short(vv->data, len);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
170
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
171 cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_http_limit_zone_cleanup_t));
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
172 if (cln == NULL) {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
173 return NGX_HTTP_INTERNAL_SERVER_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
174 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
175
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
176 shpool = (ngx_slab_pool_t *) lzcf->shm_zone->shm.addr;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
177
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
178 ngx_shmtx_lock(&shpool->mutex);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
179
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
180 node = ctx->rbtree->root;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
181 sentinel = ctx->rbtree->sentinel;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
182
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
183 while (node != sentinel) {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
184
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
185 if (hash < node->key) {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
186 node = node->left;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
187 continue;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
188 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
189
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
190 if (hash > node->key) {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
191 node = node->right;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
192 continue;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
193 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
194
1012
11ffb8e4753f stop rbtree search early if equal hash was found
Igor Sysoev <igor@sysoev.ru>
parents: 1011
diff changeset
195 /* hash == node->key */
11ffb8e4753f stop rbtree search early if equal hash was found
Igor Sysoev <igor@sysoev.ru>
parents: 1011
diff changeset
196
4515
8bb695c05870 Merge of r4498:
Maxim Dounin <mdounin@mdounin.ru>
parents: 4450
diff changeset
197 lz = (ngx_http_limit_zone_node_t *) &node->color;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
198
4515
8bb695c05870 Merge of r4498:
Maxim Dounin <mdounin@mdounin.ru>
parents: 4450
diff changeset
199 rc = ngx_memn2cmp(vv->data, lz->data, len, (size_t) lz->len);
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
200
4515
8bb695c05870 Merge of r4498:
Maxim Dounin <mdounin@mdounin.ru>
parents: 4450
diff changeset
201 if (rc == 0) {
8bb695c05870 Merge of r4498:
Maxim Dounin <mdounin@mdounin.ru>
parents: 4450
diff changeset
202 if ((ngx_uint_t) lz->conn < lzcf->conn) {
8bb695c05870 Merge of r4498:
Maxim Dounin <mdounin@mdounin.ru>
parents: 4450
diff changeset
203 lz->conn++;
8bb695c05870 Merge of r4498:
Maxim Dounin <mdounin@mdounin.ru>
parents: 4450
diff changeset
204 goto done;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
205 }
1012
11ffb8e4753f stop rbtree search early if equal hash was found
Igor Sysoev <igor@sysoev.ru>
parents: 1011
diff changeset
206
4515
8bb695c05870 Merge of r4498:
Maxim Dounin <mdounin@mdounin.ru>
parents: 4450
diff changeset
207 ngx_shmtx_unlock(&shpool->mutex);
1012
11ffb8e4753f stop rbtree search early if equal hash was found
Igor Sysoev <igor@sysoev.ru>
parents: 1011
diff changeset
208
4515
8bb695c05870 Merge of r4498:
Maxim Dounin <mdounin@mdounin.ru>
parents: 4450
diff changeset
209 ngx_log_error(lzcf->log_level, r->connection->log, 0,
8bb695c05870 Merge of r4498:
Maxim Dounin <mdounin@mdounin.ru>
parents: 4450
diff changeset
210 "limiting connections by zone \"%V\"",
8bb695c05870 Merge of r4498:
Maxim Dounin <mdounin@mdounin.ru>
parents: 4450
diff changeset
211 &lzcf->shm_zone->shm.name);
1012
11ffb8e4753f stop rbtree search early if equal hash was found
Igor Sysoev <igor@sysoev.ru>
parents: 1011
diff changeset
212
4515
8bb695c05870 Merge of r4498:
Maxim Dounin <mdounin@mdounin.ru>
parents: 4450
diff changeset
213 return NGX_HTTP_SERVICE_UNAVAILABLE;
8bb695c05870 Merge of r4498:
Maxim Dounin <mdounin@mdounin.ru>
parents: 4450
diff changeset
214 }
8bb695c05870 Merge of r4498:
Maxim Dounin <mdounin@mdounin.ru>
parents: 4450
diff changeset
215
8bb695c05870 Merge of r4498:
Maxim Dounin <mdounin@mdounin.ru>
parents: 4450
diff changeset
216 node = (rc < 0) ? node->left : node->right;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
217 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
218
981
6fe76f377a62 fix key length and alignment
Igor Sysoev <igor@sysoev.ru>
parents: 980
diff changeset
219 n = offsetof(ngx_rbtree_node_t, color)
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
220 + offsetof(ngx_http_limit_zone_node_t, data)
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
221 + len;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
222
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
223 node = ngx_slab_alloc_locked(shpool, n);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
224 if (node == NULL) {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
225 ngx_shmtx_unlock(&shpool->mutex);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
226 return NGX_HTTP_SERVICE_UNAVAILABLE;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
227 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
228
981
6fe76f377a62 fix key length and alignment
Igor Sysoev <igor@sysoev.ru>
parents: 980
diff changeset
229 lz = (ngx_http_limit_zone_node_t *) &node->color;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
230
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
231 node->key = hash;
981
6fe76f377a62 fix key length and alignment
Igor Sysoev <igor@sysoev.ru>
parents: 980
diff changeset
232 lz->len = (u_char) len;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
233 lz->conn = 1;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
234 ngx_memcpy(lz->data, vv->data, len);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
235
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
236 ngx_rbtree_insert(ctx->rbtree, node);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
237
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
238 done:
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
239
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
240 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
241 "limit zone: %08XD %d", node->key, lz->conn);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
242
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
243 ngx_shmtx_unlock(&shpool->mutex);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
244
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
245 cln->handler = ngx_http_limit_zone_cleanup;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
246 lzcln = cln->data;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
247
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
248 lzcln->shm_zone = lzcf->shm_zone;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
249 lzcln->node = node;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
250
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
251 return NGX_DECLINED;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
252 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
253
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
254
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
255 static void
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
256 ngx_http_limit_zone_rbtree_insert_value(ngx_rbtree_node_t *temp,
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
257 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
258 {
1743
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
259 ngx_rbtree_node_t **p;
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
260 ngx_http_limit_zone_node_t *lzn, *lznt;
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
261
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
262 for ( ;; ) {
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
263
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
264 if (node->key < temp->key) {
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
265
1743
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
266 p = &temp->left;
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
267
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
268 } else if (node->key > temp->key) {
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
269
1743
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
270 p = &temp->right;
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
271
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
272 } else { /* node->key == temp->key */
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
273
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
274 lzn = (ngx_http_limit_zone_node_t *) &node->color;
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
275 lznt = (ngx_http_limit_zone_node_t *) &temp->color;
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
276
1743
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
277 p = (ngx_memn2cmp(lzn->data, lznt->data, lzn->len, lznt->len) < 0)
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
278 ? &temp->left : &temp->right;
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
279 }
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
280
1743
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
281 if (*p == sentinel) {
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
282 break;
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
283 }
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
284
1743
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
285 temp = *p;
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
286 }
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
287
1743
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
288 *p = node;
1026
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
289 node->parent = temp;
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
290 node->left = sentinel;
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
291 node->right = sentinel;
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
292 ngx_rbt_red(node);
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
293 }
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
294
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
295
38be15c1379a fix duplicate rbtree keys case
Igor Sysoev <igor@sysoev.ru>
parents: 1012
diff changeset
296 static void
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
297 ngx_http_limit_zone_cleanup(void *data)
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
298 {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
299 ngx_http_limit_zone_cleanup_t *lzcln = data;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
300
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
301 ngx_slab_pool_t *shpool;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
302 ngx_rbtree_node_t *node;
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
303 ngx_http_limit_zone_ctx_t *ctx;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
304 ngx_http_limit_zone_node_t *lz;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
305
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
306 ctx = lzcln->shm_zone->data;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
307 shpool = (ngx_slab_pool_t *) lzcln->shm_zone->shm.addr;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
308 node = lzcln->node;
981
6fe76f377a62 fix key length and alignment
Igor Sysoev <igor@sysoev.ru>
parents: 980
diff changeset
309 lz = (ngx_http_limit_zone_node_t *) &node->color;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
310
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
311 ngx_shmtx_lock(&shpool->mutex);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
312
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
313 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, lzcln->shm_zone->shm.log, 0,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
314 "limit zone cleanup: %08XD %d", node->key, lz->conn);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
315
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
316 lz->conn--;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
317
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
318 if (lz->conn == 0) {
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
319 ngx_rbtree_delete(ctx->rbtree, node);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
320 ngx_slab_free_locked(shpool, node);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
321 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
322
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
323 ngx_shmtx_unlock(&shpool->mutex);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
324 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
325
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
326
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
327 static ngx_int_t
993
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
328 ngx_http_limit_zone_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
329 {
993
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
330 ngx_http_limit_zone_ctx_t *octx = data;
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
331
2611
2bce3f6416c6 improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents: 2373
diff changeset
332 size_t len;
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
333 ngx_slab_pool_t *shpool;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
334 ngx_rbtree_node_t *sentinel;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
335 ngx_http_limit_zone_ctx_t *ctx;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
336
993
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
337 ctx = shm_zone->data;
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
338
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
339 if (octx) {
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
340 if (ngx_strcmp(ctx->var.data, octx->var.data) != 0) {
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
341 ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0,
1001
778e7d9a92d6 fix typo
Igor Sysoev <igor@sysoev.ru>
parents: 997
diff changeset
342 "limit_zone \"%V\" uses the \"%V\" variable "
993
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
343 "while previously it used the \"%V\" variable",
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
344 &shm_zone->shm.name, &ctx->var, &octx->var);
993
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
345 return NGX_ERROR;
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
346 }
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
347
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
348 ctx->rbtree = octx->rbtree;
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
349
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
350 return NGX_OK;
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
351 }
1b9a4d92173f pass the inherited shm_zone data
Igor Sysoev <igor@sysoev.ru>
parents: 987
diff changeset
352
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
353 shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
354
2720
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
355 if (shm_zone->shm.exists) {
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
356 ctx->rbtree = shpool->data;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
357
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
358 return NGX_OK;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
359 }
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
360
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
361 ctx->rbtree = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_t));
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
362 if (ctx->rbtree == NULL) {
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
363 return NGX_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
364 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
365
2720
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
366 shpool->data = ctx->rbtree;
b3b8c66bd520 support attaching to an existent Win32 shared memory
Igor Sysoev <igor@sysoev.ru>
parents: 2716
diff changeset
367
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
368 sentinel = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_node_t));
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
369 if (sentinel == NULL) {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
370 return NGX_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
371 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
372
1743
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
373 ngx_rbtree_init(ctx->rbtree, sentinel,
4fc402c3ec73 optimize rbtree initialization and insert
Igor Sysoev <igor@sysoev.ru>
parents: 1406
diff changeset
374 ngx_http_limit_zone_rbtree_insert_value);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
375
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
376 len = sizeof(" in limit_zone \"\"") + shm_zone->shm.name.len;
2611
2bce3f6416c6 improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents: 2373
diff changeset
377
2bce3f6416c6 improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents: 2373
diff changeset
378 shpool->log_ctx = ngx_slab_alloc(shpool, len);
2bce3f6416c6 improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents: 2373
diff changeset
379 if (shpool->log_ctx == NULL) {
2bce3f6416c6 improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents: 2373
diff changeset
380 return NGX_ERROR;
2bce3f6416c6 improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents: 2373
diff changeset
381 }
2bce3f6416c6 improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents: 2373
diff changeset
382
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
383 ngx_sprintf(shpool->log_ctx, " in limit_zone \"%V\"%Z",
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
384 &shm_zone->shm.name);
2611
2bce3f6416c6 improve ngx_slab_alloc() error logging
Igor Sysoev <igor@sysoev.ru>
parents: 2373
diff changeset
385
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
386 return NGX_OK;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
387 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
388
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
389
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
390 static void *
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
391 ngx_http_limit_zone_create_conf(ngx_conf_t *cf)
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
392 {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
393 ngx_http_limit_zone_conf_t *conf;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
394
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
395 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_zone_conf_t));
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
396 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
397 return NULL;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
398 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
399
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
400 /*
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
401 * set by ngx_pcalloc():
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
402 *
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
403 * conf->shm_zone = NULL;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
404 * conf->conn = 0;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
405 */
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
406
3186
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
407 conf->log_level = NGX_CONF_UNSET_UINT;
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
408
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
409 return conf;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
410 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
411
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
412
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
413 static char *
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
414 ngx_http_limit_zone_merge_conf(ngx_conf_t *cf, void *parent, void *child)
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
415 {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
416 ngx_http_limit_zone_conf_t *prev = parent;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
417 ngx_http_limit_zone_conf_t *conf = child;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
418
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
419 if (conf->shm_zone == NULL) {
4440
97995d63aa36 Merge of r4381, r4400:
Maxim Dounin <mdounin@mdounin.ru>
parents: 3186
diff changeset
420 conf->shm_zone = prev->shm_zone;
97995d63aa36 Merge of r4381, r4400:
Maxim Dounin <mdounin@mdounin.ru>
parents: 3186
diff changeset
421 conf->conn = prev->conn;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
422 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
423
3186
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
424 ngx_conf_merge_uint_value(conf->log_level, prev->log_level, NGX_LOG_ERR);
23d567eabc5d limit_conn_log_level
Igor Sysoev <igor@sysoev.ru>
parents: 2912
diff changeset
425
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
426 return NGX_CONF_OK;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
427 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
428
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
429
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
430 static char *
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
431 ngx_http_limit_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
432 {
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
433 ssize_t n;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
434 ngx_str_t *value;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
435 ngx_shm_zone_t *shm_zone;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
436 ngx_http_limit_zone_ctx_t *ctx;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
437
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
438 value = cf->args->elts;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
439
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
440 if (value[2].data[0] != '$') {
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
441 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
442 "invalid variable name \"%V\"", &value[2]);
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
443 return NGX_CONF_ERROR;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
444 }
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
445
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
446 value[2].len--;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
447 value[2].data++;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
448
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
449 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_zone_ctx_t));
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
450 if (ctx == NULL) {
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
451 return NGX_CONF_ERROR;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
452 }
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
453
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
454 ctx->index = ngx_http_get_variable_index(cf, &value[2]);
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
455 if (ctx->index == NGX_ERROR) {
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
456 return NGX_CONF_ERROR;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
457 }
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
458
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
459 ctx->var = value[2];
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
460
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
461 n = ngx_parse_size(&value[3]);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
462
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
463 if (n == NGX_ERROR) {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
464 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
465 "invalid size of limit_zone \"%V\"", &value[3]);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
466 return NGX_CONF_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
467 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
468
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
469 if (n < (ngx_int_t) (8 * ngx_pagesize)) {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
470 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
471 "limit_zone \"%V\" is too small", &value[1]);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
472 return NGX_CONF_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
473 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
474
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
475
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
476 shm_zone = ngx_shared_memory_add(cf, &value[1], n,
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
477 &ngx_http_limit_zone_module);
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
478 if (shm_zone == NULL) {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
479 return NGX_CONF_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
480 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
481
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
482 if (shm_zone->data) {
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
483 ctx = shm_zone->data;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
484
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
485 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
486 "limit_zone \"%V\" is already bound to variable \"%V\"",
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
487 &value[1], &ctx->var);
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
488 return NGX_CONF_ERROR;
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
489 }
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
490
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
491 shm_zone->init = ngx_http_limit_zone_init_zone;
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
492 shm_zone->data = ctx;
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
493
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
494 return NGX_CONF_OK;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
495 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
496
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
497
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
498 static char *
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
499 ngx_http_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
500 {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
501 ngx_http_limit_zone_conf_t *lzcf = conf;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
502
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
503 ngx_int_t n;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
504 ngx_str_t *value;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
505
2372
7148efbdd798 test duplicate limit_conn
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
506 if (lzcf->shm_zone) {
7148efbdd798 test duplicate limit_conn
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
507 return "is duplicate";
7148efbdd798 test duplicate limit_conn
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
508 }
7148efbdd798 test duplicate limit_conn
Igor Sysoev <igor@sysoev.ru>
parents: 1743
diff changeset
509
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
510 value = cf->args->elts;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
511
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
512 lzcf->shm_zone = ngx_shared_memory_add(cf, &value[1], 0,
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
513 &ngx_http_limit_zone_module);
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
514 if (lzcf->shm_zone == NULL) {
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
515 return NGX_CONF_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
516 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
517
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
518 n = ngx_atoi(value[2].data, value[2].len);
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
519 if (n <= 0) {
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
520 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
987
14e68f471d02 new syntax
Igor Sysoev <igor@sysoev.ru>
parents: 984
diff changeset
521 "invalid number of connections \"%V\"", &value[2]);
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
522 return NGX_CONF_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
523 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
524
1011
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
525 if (n > 65535) {
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
526 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
527 "connection limit must be less 65536");
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
528 return NGX_CONF_ERROR;
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
529 }
19118c44303f test length of variable and number of connections
Igor Sysoev <igor@sysoev.ru>
parents: 1002
diff changeset
530
980
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
531 lzcf->conn = n;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
532
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
533 return NGX_CONF_OK;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
534 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
535
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
536
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
537 static ngx_int_t
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
538 ngx_http_limit_zone_init(ngx_conf_t *cf)
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
539 {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
540 ngx_http_handler_pt *h;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
541 ngx_http_core_main_conf_t *cmcf;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
542
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
543 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
544
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
545 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
546 if (h == NULL) {
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
547 return NGX_ERROR;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
548 }
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
549
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
550 *h = ngx_http_limit_zone_handler;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
551
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
552 return NGX_OK;
7cb910b4a58a ngx_http_limit_zone_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
553 }