Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_map_module.c @ 4915:e62219793beb
Upstream: better detection of connect() failures with kqueue.
Pending EOF might be reported on both read and write events, whichever
comes first, so check both of them.
Patch by Yichun Zhang (agentzh), slightly modified.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Fri, 16 Nov 2012 18:29:19 +0000 |
parents | 6e46016ea276 |
children | 8b635cf36ccc |
rev | line source |
---|---|
589 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
589 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
13 typedef struct { | |
14 ngx_uint_t hash_max_size; | |
15 ngx_uint_t hash_bucket_size; | |
16 } ngx_http_map_conf_t; | |
17 | |
18 | |
19 typedef struct { | |
593 | 20 ngx_hash_keys_arrays_t keys; |
589 | 21 |
22 ngx_array_t *values_hash; | |
3792
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
23 ngx_array_t var_values; |
3872
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
24 #if (NGX_PCRE) |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
25 ngx_array_t regexes; |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
26 #endif |
589 | 27 |
28 ngx_http_variable_value_t *default_value; | |
3792
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
29 ngx_conf_t *cf; |
589 | 30 ngx_uint_t hostnames; /* unsigned hostnames:1 */ |
31 } ngx_http_map_conf_ctx_t; | |
32 | |
33 | |
34 typedef struct { | |
3872
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
35 ngx_http_map_t map; |
3789
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
36 ngx_http_complex_value_t value; |
589 | 37 ngx_http_variable_value_t *default_value; |
38 ngx_uint_t hostnames; /* unsigned hostnames:1 */ | |
39 } ngx_http_map_ctx_t; | |
40 | |
41 | |
42 static int ngx_libc_cdecl ngx_http_map_cmp_dns_wildcards(const void *one, | |
43 const void *two); | |
44 static void *ngx_http_map_create_conf(ngx_conf_t *cf); | |
45 static char *ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | |
46 static char *ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); | |
47 | |
48 | |
49 static ngx_command_t ngx_http_map_commands[] = { | |
50 | |
51 { ngx_string("map"), | |
52 NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE2, | |
53 ngx_http_map_block, | |
54 NGX_HTTP_MAIN_CONF_OFFSET, | |
55 0, | |
56 NULL }, | |
57 | |
58 { ngx_string("map_hash_max_size"), | |
59 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, | |
60 ngx_conf_set_num_slot, | |
61 NGX_HTTP_MAIN_CONF_OFFSET, | |
62 offsetof(ngx_http_map_conf_t, hash_max_size), | |
63 NULL }, | |
64 | |
65 { ngx_string("map_hash_bucket_size"), | |
66 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, | |
67 ngx_conf_set_num_slot, | |
68 NGX_HTTP_MAIN_CONF_OFFSET, | |
69 offsetof(ngx_http_map_conf_t, hash_bucket_size), | |
70 NULL }, | |
71 | |
72 ngx_null_command | |
73 }; | |
74 | |
75 | |
76 static ngx_http_module_t ngx_http_map_module_ctx = { | |
77 NULL, /* preconfiguration */ | |
78 NULL, /* postconfiguration */ | |
79 | |
80 ngx_http_map_create_conf, /* create main configuration */ | |
81 NULL, /* init main configuration */ | |
82 | |
83 NULL, /* create server configuration */ | |
84 NULL, /* merge server configuration */ | |
85 | |
86 NULL, /* create location configuration */ | |
87 NULL /* merge location configuration */ | |
88 }; | |
89 | |
90 | |
91 ngx_module_t ngx_http_map_module = { | |
92 NGX_MODULE_V1, | |
93 &ngx_http_map_module_ctx, /* module context */ | |
94 ngx_http_map_commands, /* module directives */ | |
95 NGX_HTTP_MODULE, /* module type */ | |
96 NULL, /* init master */ | |
97 NULL, /* init module */ | |
98 NULL, /* init process */ | |
99 NULL, /* init thread */ | |
100 NULL, /* exit thread */ | |
101 NULL, /* exit process */ | |
102 NULL, /* exit master */ | |
103 NGX_MODULE_V1_PADDING | |
104 }; | |
105 | |
106 | |
107 static ngx_int_t | |
108 ngx_http_map_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, | |
109 uintptr_t data) | |
110 { | |
111 ngx_http_map_ctx_t *map = (ngx_http_map_ctx_t *) data; | |
112 | |
3789
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
113 ngx_str_t val; |
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
114 ngx_http_variable_value_t *value; |
589 | 115 |
116 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
117 "http map started"); | |
118 | |
3789
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
119 if (ngx_http_complex_value(r, &map->value, &val) != NGX_OK) { |
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
120 return NGX_ERROR; |
797
36f7b549f481
fix segfault if $server_addr failed
Igor Sysoev <igor@sysoev.ru>
parents:
637
diff
changeset
|
121 } |
36f7b549f481
fix segfault if $server_addr failed
Igor Sysoev <igor@sysoev.ru>
parents:
637
diff
changeset
|
122 |
4712
fd3eefefa5f9
map: strip final dot before looking up in a map of hostnames.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
123 if (map->hostnames && val.len > 0 && val.data[val.len - 1] == '.') { |
fd3eefefa5f9
map: strip final dot before looking up in a map of hostnames.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
124 val.len--; |
589 | 125 } |
126 | |
3929
fa4612bfb9fa
change ngx_http_map_find(): use case sensitive regexes
Igor Sysoev <igor@sysoev.ru>
parents:
3874
diff
changeset
|
127 value = ngx_http_map_find(r, &map->map, &val); |
589 | 128 |
3792
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
129 if (value == NULL) { |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
130 value = map->default_value; |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
131 } |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
132 |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
133 if (!value->valid) { |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
134 value = ngx_http_get_flushed_variable(r, (ngx_uint_t) value->data); |
589 | 135 |
3792
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
136 if (value == NULL || value->not_found) { |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
137 value = &ngx_http_variable_null_value; |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
138 } |
589 | 139 } |
140 | |
3792
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
141 *v = *value; |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
142 |
589 | 143 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
3789
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
144 "http map: \"%v\" \"%v\"", &val, v); |
589 | 145 |
146 return NGX_OK; | |
147 } | |
148 | |
149 | |
150 static void * | |
151 ngx_http_map_create_conf(ngx_conf_t *cf) | |
152 { | |
153 ngx_http_map_conf_t *mcf; | |
154 | |
155 mcf = ngx_palloc(cf->pool, sizeof(ngx_http_map_conf_t)); | |
156 if (mcf == NULL) { | |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
157 return NULL; |
589 | 158 } |
159 | |
160 mcf->hash_max_size = NGX_CONF_UNSET_UINT; | |
161 mcf->hash_bucket_size = NGX_CONF_UNSET_UINT; | |
162 | |
163 return mcf; | |
164 } | |
165 | |
166 | |
167 static char * | |
168 ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
169 { | |
170 ngx_http_map_conf_t *mcf = conf; | |
171 | |
3789
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
172 char *rv; |
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
173 ngx_str_t *value, name; |
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
174 ngx_conf_t save; |
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
175 ngx_pool_t *pool; |
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
176 ngx_hash_init_t hash; |
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
177 ngx_http_map_ctx_t *map; |
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
178 ngx_http_variable_t *var; |
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
179 ngx_http_map_conf_ctx_t ctx; |
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
180 ngx_http_compile_complex_value_t ccv; |
589 | 181 |
182 if (mcf->hash_max_size == NGX_CONF_UNSET_UINT) { | |
183 mcf->hash_max_size = 2048; | |
184 } | |
185 | |
186 if (mcf->hash_bucket_size == NGX_CONF_UNSET_UINT) { | |
187 mcf->hash_bucket_size = ngx_cacheline_size; | |
188 | |
189 } else { | |
190 mcf->hash_bucket_size = ngx_align(mcf->hash_bucket_size, | |
191 ngx_cacheline_size); | |
192 } | |
193 | |
194 map = ngx_pcalloc(cf->pool, sizeof(ngx_http_map_ctx_t)); | |
195 if (map == NULL) { | |
196 return NGX_CONF_ERROR; | |
197 } | |
198 | |
199 value = cf->args->elts; | |
200 | |
3789
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
201 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
589 | 202 |
3789
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
203 ccv.cf = cf; |
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
204 ccv.value = &value[1]; |
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
205 ccv.complex_value = &map->value; |
589 | 206 |
3789
19c931be8b98
allow expressions in the first "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
207 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
589 | 208 return NGX_CONF_ERROR; |
209 } | |
210 | |
211 name = value[2]; | |
212 name.len--; | |
213 name.data++; | |
214 | |
1565 | 215 var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE); |
589 | 216 if (var == NULL) { |
217 return NGX_CONF_ERROR; | |
218 } | |
219 | |
637 | 220 var->get_handler = ngx_http_map_variable; |
589 | 221 var->data = (uintptr_t) map; |
222 | |
223 pool = ngx_create_pool(16384, cf->log); | |
224 if (pool == NULL) { | |
225 return NGX_CONF_ERROR; | |
226 } | |
227 | |
593 | 228 ctx.keys.pool = cf->pool; |
229 ctx.keys.temp_pool = pool; | |
589 | 230 |
593 | 231 if (ngx_hash_keys_array_init(&ctx.keys, NGX_HASH_LARGE) != NGX_OK) { |
589 | 232 ngx_destroy_pool(pool); |
233 return NGX_CONF_ERROR; | |
234 } | |
235 | |
593 | 236 ctx.values_hash = ngx_pcalloc(pool, sizeof(ngx_array_t) * ctx.keys.hsize); |
589 | 237 if (ctx.values_hash == NULL) { |
238 ngx_destroy_pool(pool); | |
239 return NGX_CONF_ERROR; | |
240 } | |
241 | |
3792
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
242 if (ngx_array_init(&ctx.var_values, cf->pool, 2, |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
243 sizeof(ngx_http_variable_value_t)) |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
244 != NGX_OK) |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
245 { |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
246 ngx_destroy_pool(pool); |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
247 return NGX_CONF_ERROR; |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
248 } |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
249 |
3872
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
250 #if (NGX_PCRE) |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
251 if (ngx_array_init(&ctx.regexes, cf->pool, 2, sizeof(ngx_http_map_regex_t)) |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
252 != NGX_OK) |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
253 { |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
254 ngx_destroy_pool(pool); |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
255 return NGX_CONF_ERROR; |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
256 } |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
257 #endif |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
258 |
589 | 259 ctx.default_value = NULL; |
3792
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
260 ctx.cf = &save; |
589 | 261 ctx.hostnames = 0; |
262 | |
263 save = *cf; | |
264 cf->pool = pool; | |
265 cf->ctx = &ctx; | |
266 cf->handler = ngx_http_map; | |
267 cf->handler_conf = conf; | |
268 | |
269 rv = ngx_conf_parse(cf, NULL); | |
270 | |
271 *cf = save; | |
272 | |
273 if (rv != NGX_CONF_OK) { | |
274 ngx_destroy_pool(pool); | |
275 return rv; | |
276 } | |
277 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
278 map->default_value = ctx.default_value ? ctx.default_value: |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
279 &ngx_http_variable_null_value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
280 |
4712
fd3eefefa5f9
map: strip final dot before looking up in a map of hostnames.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
281 map->hostnames = ctx.hostnames; |
fd3eefefa5f9
map: strip final dot before looking up in a map of hostnames.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
282 |
589 | 283 hash.key = ngx_hash_key_lc; |
284 hash.max_size = mcf->hash_max_size; | |
285 hash.bucket_size = mcf->hash_bucket_size; | |
286 hash.name = "map_hash"; | |
287 hash.pool = cf->pool; | |
288 | |
593 | 289 if (ctx.keys.keys.nelts) { |
3872
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
290 hash.hash = &map->map.hash.hash; |
589 | 291 hash.temp_pool = NULL; |
292 | |
593 | 293 if (ngx_hash_init(&hash, ctx.keys.keys.elts, ctx.keys.keys.nelts) |
591 | 294 != NGX_OK) |
295 { | |
593 | 296 ngx_destroy_pool(pool); |
589 | 297 return NGX_CONF_ERROR; |
298 } | |
299 } | |
300 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
301 if (ctx.keys.dns_wc_head.nelts) { |
589 | 302 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
303 ngx_qsort(ctx.keys.dns_wc_head.elts, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
304 (size_t) ctx.keys.dns_wc_head.nelts, |
589 | 305 sizeof(ngx_hash_key_t), ngx_http_map_cmp_dns_wildcards); |
306 | |
307 hash.hash = NULL; | |
308 hash.temp_pool = pool; | |
309 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
310 if (ngx_hash_wildcard_init(&hash, ctx.keys.dns_wc_head.elts, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
311 ctx.keys.dns_wc_head.nelts) |
589 | 312 != NGX_OK) |
313 { | |
593 | 314 ngx_destroy_pool(pool); |
589 | 315 return NGX_CONF_ERROR; |
316 } | |
317 | |
3872
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
318 map->map.hash.wc_head = (ngx_hash_wildcard_t *) hash.hash; |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
319 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
320 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
321 if (ctx.keys.dns_wc_tail.nelts) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
322 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
323 ngx_qsort(ctx.keys.dns_wc_tail.elts, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
324 (size_t) ctx.keys.dns_wc_tail.nelts, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
325 sizeof(ngx_hash_key_t), ngx_http_map_cmp_dns_wildcards); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
326 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
327 hash.hash = NULL; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
328 hash.temp_pool = pool; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
329 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
330 if (ngx_hash_wildcard_init(&hash, ctx.keys.dns_wc_tail.elts, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
331 ctx.keys.dns_wc_tail.nelts) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
332 != NGX_OK) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
333 { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
334 ngx_destroy_pool(pool); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
335 return NGX_CONF_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
336 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
337 |
3872
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
338 map->map.hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash; |
589 | 339 } |
340 | |
3872
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
341 #if (NGX_PCRE) |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
342 |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
343 if (ctx.regexes.nelts) { |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
344 map->map.regex = ctx.regexes.elts; |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
345 map->map.nregex = ctx.regexes.nelts; |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
346 } |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
347 |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
348 #endif |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
349 |
589 | 350 ngx_destroy_pool(pool); |
351 | |
352 return rv; | |
353 } | |
354 | |
355 | |
356 static int ngx_libc_cdecl | |
357 ngx_http_map_cmp_dns_wildcards(const void *one, const void *two) | |
358 { | |
359 ngx_hash_key_t *first, *second; | |
360 | |
361 first = (ngx_hash_key_t *) one; | |
362 second = (ngx_hash_key_t *) two; | |
363 | |
3116
98e288c6dac3
If .domain.com, .sub.domain.com, and .domain-some.com were defined,
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
364 return ngx_dns_strcmp(first->key.data, second->key.data); |
589 | 365 } |
366 | |
367 | |
368 static char * | |
369 ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) | |
370 { | |
3792
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
371 ngx_int_t rc, index; |
4827
6e46016ea276
Fixed the "include" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4814
diff
changeset
|
372 ngx_str_t *value, name; |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
373 ngx_uint_t i, key; |
589 | 374 ngx_http_map_conf_ctx_t *ctx; |
591 | 375 ngx_http_variable_value_t *var, **vp; |
589 | 376 |
377 ctx = cf->ctx; | |
378 | |
379 value = cf->args->elts; | |
380 | |
381 if (cf->args->nelts == 1 | |
382 && ngx_strcmp(value[0].data, "hostnames") == 0) | |
383 { | |
384 ctx->hostnames = 1; | |
385 return NGX_CONF_OK; | |
386 | |
387 } else if (cf->args->nelts != 2) { | |
388 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
389 "invalid number of the map parameters"); | |
390 return NGX_CONF_ERROR; | |
391 } | |
392 | |
393 if (ngx_strcmp(value[0].data, "include") == 0) { | |
4827
6e46016ea276
Fixed the "include" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4814
diff
changeset
|
394 return ngx_conf_include(cf, dummy, conf); |
589 | 395 } |
396 | |
3792
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
397 if (value[1].data[0] == '$') { |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
398 name = value[1]; |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
399 name.len--; |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
400 name.data++; |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
401 |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
402 index = ngx_http_get_variable_index(ctx->cf, &name); |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
403 if (index == NGX_ERROR) { |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
404 return NGX_CONF_ERROR; |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
405 } |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
406 |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
407 var = ctx->var_values.elts; |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
408 |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
409 for (i = 0; i < ctx->var_values.nelts; i++) { |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
410 if (index == (ngx_int_t) var[i].data) { |
4814
0656cfe8f7cb
Map: fixed optimization of variables as values.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4712
diff
changeset
|
411 var = &var[i]; |
3792
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
412 goto found; |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
413 } |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
414 } |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
415 |
4814
0656cfe8f7cb
Map: fixed optimization of variables as values.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4712
diff
changeset
|
416 var = ngx_array_push(&ctx->var_values); |
3792
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
417 if (var == NULL) { |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
418 return NGX_CONF_ERROR; |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
419 } |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
420 |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
421 var->valid = 0; |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
422 var->no_cacheable = 0; |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
423 var->not_found = 0; |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
424 var->len = 0; |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
425 var->data = (u_char *) index; |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
426 |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
427 goto found; |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
428 } |
164a7f8df979
allow variable as "map" value
Igor Sysoev <igor@sysoev.ru>
parents:
3791
diff
changeset
|
429 |
589 | 430 key = 0; |
431 | |
432 for (i = 0; i < value[1].len; i++) { | |
433 key = ngx_hash(key, value[1].data[i]); | |
434 } | |
435 | |
593 | 436 key %= ctx->keys.hsize; |
589 | 437 |
438 vp = ctx->values_hash[key].elts; | |
439 | |
440 if (vp) { | |
441 for (i = 0; i < ctx->values_hash[key].nelts; i++) { | |
442 if (value[1].len != (size_t) vp[i]->len) { | |
443 continue; | |
444 } | |
445 | |
446 if (ngx_strncmp(value[1].data, vp[i]->data, value[1].len) == 0) { | |
447 var = vp[i]; | |
448 goto found; | |
449 } | |
450 } | |
451 | |
452 } else { | |
453 if (ngx_array_init(&ctx->values_hash[key], cf->pool, 4, | |
454 sizeof(ngx_http_variable_value_t *)) | |
455 != NGX_OK) | |
456 { | |
457 return NGX_CONF_ERROR; | |
458 } | |
459 } | |
460 | |
593 | 461 var = ngx_palloc(ctx->keys.pool, sizeof(ngx_http_variable_value_t)); |
589 | 462 if (var == NULL) { |
463 return NGX_CONF_ERROR; | |
464 } | |
465 | |
466 var->len = value[1].len; | |
593 | 467 var->data = ngx_pstrdup(ctx->keys.pool, &value[1]); |
589 | 468 if (var->data == NULL) { |
469 return NGX_CONF_ERROR; | |
470 } | |
471 | |
472 var->valid = 1; | |
1565 | 473 var->no_cacheable = 0; |
589 | 474 var->not_found = 0; |
475 | |
476 vp = ngx_array_push(&ctx->values_hash[key]); | |
477 if (vp == NULL) { | |
478 return NGX_CONF_ERROR; | |
479 } | |
480 | |
481 *vp = var; | |
482 | |
483 found: | |
484 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
485 if (ngx_strcmp(value[0].data, "default") == 0) { |
589 | 486 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
487 if (ctx->default_value) { |
589 | 488 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
489 "duplicate default map parameter"); |
589 | 490 return NGX_CONF_ERROR; |
491 } | |
492 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
493 ctx->default_value = var; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
494 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
495 return NGX_CONF_OK; |
589 | 496 } |
497 | |
3872
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
498 #if (NGX_PCRE) |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
499 |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
500 if (value[0].len && value[0].data[0] == '~') { |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
501 ngx_regex_compile_t rc; |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
502 ngx_http_map_regex_t *regex; |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
503 u_char errstr[NGX_MAX_CONF_ERRSTR]; |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
504 |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
505 regex = ngx_array_push(&ctx->regexes); |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
506 if (regex == NULL) { |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
507 return NGX_CONF_ERROR; |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
508 } |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
509 |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
510 value[0].len--; |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
511 value[0].data++; |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
512 |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
513 ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
514 |
3930
ace14fd91086
revert r3875 since now map uses case sensetive regexes by default
Igor Sysoev <igor@sysoev.ru>
parents:
3929
diff
changeset
|
515 if (value[0].data[0] == '*') { |
ace14fd91086
revert r3875 since now map uses case sensetive regexes by default
Igor Sysoev <igor@sysoev.ru>
parents:
3929
diff
changeset
|
516 value[0].len--; |
ace14fd91086
revert r3875 since now map uses case sensetive regexes by default
Igor Sysoev <igor@sysoev.ru>
parents:
3929
diff
changeset
|
517 value[0].data++; |
ace14fd91086
revert r3875 since now map uses case sensetive regexes by default
Igor Sysoev <igor@sysoev.ru>
parents:
3929
diff
changeset
|
518 rc.options = NGX_REGEX_CASELESS; |
ace14fd91086
revert r3875 since now map uses case sensetive regexes by default
Igor Sysoev <igor@sysoev.ru>
parents:
3929
diff
changeset
|
519 } |
ace14fd91086
revert r3875 since now map uses case sensetive regexes by default
Igor Sysoev <igor@sysoev.ru>
parents:
3929
diff
changeset
|
520 |
3872
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
521 rc.pattern = value[0]; |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
522 rc.err.len = NGX_MAX_CONF_ERRSTR; |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
523 rc.err.data = errstr; |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
524 |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
525 regex->regex = ngx_http_regex_compile(ctx->cf, &rc); |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
526 if (regex->regex == NULL) { |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
527 return NGX_CONF_ERROR; |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
528 } |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
529 |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
530 regex->value = var; |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
531 |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
532 return NGX_CONF_OK; |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
533 } |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
534 |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
535 #endif |
83cd1910329c
allow regex as "map" parameter
Igor Sysoev <igor@sysoev.ru>
parents:
3792
diff
changeset
|
536 |
3791
11701c4c0358
use "\" to escape "default", "include", and "hostnames" values instead of "!"
Igor Sysoev <igor@sysoev.ru>
parents:
3790
diff
changeset
|
537 if (value[0].len && value[0].data[0] == '\\') { |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
538 value[0].len--; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
539 value[0].data++; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
540 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
541 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
542 rc = ngx_hash_add_key(&ctx->keys, &value[0], var, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
543 (ctx->hostnames) ? NGX_HASH_WILDCARD_KEY : 0); |
589 | 544 |
591 | 545 if (rc == NGX_OK) { |
546 return NGX_CONF_OK; | |
547 } | |
589 | 548 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
549 if (rc == NGX_DECLINED) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
550 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
551 "invalid hostname or wildcard \"%V\"", &value[0]); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
552 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
797
diff
changeset
|
553 |
591 | 554 if (rc == NGX_BUSY) { |
555 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
556 "conflicting parameter \"%V\"", &value[0]); | |
557 } | |
589 | 558 |
591 | 559 return NGX_CONF_ERROR; |
589 | 560 } |