Mercurial > hg > nginx
comparison src/http/modules/ngx_http_map_module.c @ 1617:cacb565c554e stable-0.5
r1254, r1416, r1493 merge:
the "www.example.*" wildcard hash support
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 07 Nov 2007 13:39:53 +0000 |
parents | bf7814d77484 |
children | 6b81bbc36eaf |
comparison
equal
deleted
inserted
replaced
1615:ca6845b19113 | 1617:cacb565c554e |
---|---|
24 ngx_uint_t hostnames; /* unsigned hostnames:1 */ | 24 ngx_uint_t hostnames; /* unsigned hostnames:1 */ |
25 } ngx_http_map_conf_ctx_t; | 25 } ngx_http_map_conf_ctx_t; |
26 | 26 |
27 | 27 |
28 typedef struct { | 28 typedef struct { |
29 ngx_hash_t hash; | 29 ngx_hash_combined_t hash; |
30 ngx_hash_wildcard_t *dns_wildcards; | |
31 ngx_int_t index; | 30 ngx_int_t index; |
32 ngx_http_variable_value_t *default_value; | 31 ngx_http_variable_value_t *default_value; |
33 ngx_uint_t hostnames; /* unsigned hostnames:1 */ | 32 ngx_uint_t hostnames; /* unsigned hostnames:1 */ |
34 } ngx_http_map_ctx_t; | 33 } ngx_http_map_ctx_t; |
35 | 34 |
140 for (i = 0; i < len; i++) { | 139 for (i = 0; i < len; i++) { |
141 name[i] = ngx_tolower(vv->data[i]); | 140 name[i] = ngx_tolower(vv->data[i]); |
142 key = ngx_hash(key, name[i]); | 141 key = ngx_hash(key, name[i]); |
143 } | 142 } |
144 | 143 |
145 value = NULL; | 144 value = ngx_hash_find_combined(&map->hash, key, name, len); |
146 | |
147 if (map->hash.buckets) { | |
148 value = ngx_hash_find(&map->hash, key, name, len); | |
149 } | |
150 | 145 |
151 if (value) { | 146 if (value) { |
152 *v = *value; | 147 *v = *value; |
153 | 148 |
154 } else { | 149 } else { |
155 if (map->dns_wildcards && map->dns_wildcards->hash.buckets) { | 150 *v = *map->default_value; |
156 value = ngx_hash_find_wildcard(map->dns_wildcards, name, len); | |
157 if (value) { | |
158 *v = *value; | |
159 | |
160 } else { | |
161 *v = *map->default_value; | |
162 } | |
163 | |
164 } else { | |
165 *v = *map->default_value; | |
166 } | |
167 } | 151 } |
168 | 152 |
169 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 153 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
170 "http map: \"%v\" \"%v\"", vv, v); | 154 "http map: \"%v\" \"%v\"", vv, v); |
171 | 155 |
280 if (rv != NGX_CONF_OK) { | 264 if (rv != NGX_CONF_OK) { |
281 ngx_destroy_pool(pool); | 265 ngx_destroy_pool(pool); |
282 return rv; | 266 return rv; |
283 } | 267 } |
284 | 268 |
269 map->default_value = ctx.default_value ? ctx.default_value: | |
270 &ngx_http_variable_null_value; | |
271 | |
285 hash.key = ngx_hash_key_lc; | 272 hash.key = ngx_hash_key_lc; |
286 hash.max_size = mcf->hash_max_size; | 273 hash.max_size = mcf->hash_max_size; |
287 hash.bucket_size = mcf->hash_bucket_size; | 274 hash.bucket_size = mcf->hash_bucket_size; |
288 hash.name = "map_hash"; | 275 hash.name = "map_hash"; |
289 hash.pool = cf->pool; | 276 hash.pool = cf->pool; |
290 | 277 |
291 if (ctx.keys.keys.nelts) { | 278 if (ctx.keys.keys.nelts) { |
292 hash.hash = &map->hash; | 279 hash.hash = &map->hash.hash; |
293 hash.temp_pool = NULL; | 280 hash.temp_pool = NULL; |
294 | 281 |
295 if (ngx_hash_init(&hash, ctx.keys.keys.elts, ctx.keys.keys.nelts) | 282 if (ngx_hash_init(&hash, ctx.keys.keys.elts, ctx.keys.keys.nelts) |
296 != NGX_OK) | 283 != NGX_OK) |
297 { | 284 { |
298 ngx_destroy_pool(pool); | 285 ngx_destroy_pool(pool); |
299 return NGX_CONF_ERROR; | 286 return NGX_CONF_ERROR; |
300 } | 287 } |
301 } | 288 } |
302 | 289 |
303 map->default_value = ctx.default_value ? ctx.default_value: | 290 if (ctx.keys.dns_wc_head.nelts) { |
304 &ngx_http_variable_null_value; | 291 |
305 | 292 ngx_qsort(ctx.keys.dns_wc_head.elts, |
306 if (ctx.keys.dns_wildcards.nelts) { | 293 (size_t) ctx.keys.dns_wc_head.nelts, |
307 | |
308 ngx_qsort(ctx.keys.dns_wildcards.elts, | |
309 (size_t) ctx.keys.dns_wildcards.nelts, | |
310 sizeof(ngx_hash_key_t), ngx_http_map_cmp_dns_wildcards); | 294 sizeof(ngx_hash_key_t), ngx_http_map_cmp_dns_wildcards); |
311 | 295 |
312 hash.hash = NULL; | 296 hash.hash = NULL; |
313 hash.temp_pool = pool; | 297 hash.temp_pool = pool; |
314 | 298 |
315 if (ngx_hash_wildcard_init(&hash, ctx.keys.dns_wildcards.elts, | 299 if (ngx_hash_wildcard_init(&hash, ctx.keys.dns_wc_head.elts, |
316 ctx.keys.dns_wildcards.nelts) | 300 ctx.keys.dns_wc_head.nelts) |
317 != NGX_OK) | 301 != NGX_OK) |
318 { | 302 { |
319 ngx_destroy_pool(pool); | 303 ngx_destroy_pool(pool); |
320 return NGX_CONF_ERROR; | 304 return NGX_CONF_ERROR; |
321 } | 305 } |
322 | 306 |
323 map->dns_wildcards = (ngx_hash_wildcard_t *) hash.hash; | 307 map->hash.wc_head = (ngx_hash_wildcard_t *) hash.hash; |
308 } | |
309 | |
310 if (ctx.keys.dns_wc_tail.nelts) { | |
311 | |
312 ngx_qsort(ctx.keys.dns_wc_tail.elts, | |
313 (size_t) ctx.keys.dns_wc_tail.nelts, | |
314 sizeof(ngx_hash_key_t), ngx_http_map_cmp_dns_wildcards); | |
315 | |
316 hash.hash = NULL; | |
317 hash.temp_pool = pool; | |
318 | |
319 if (ngx_hash_wildcard_init(&hash, ctx.keys.dns_wc_tail.elts, | |
320 ctx.keys.dns_wc_tail.nelts) | |
321 != NGX_OK) | |
322 { | |
323 ngx_destroy_pool(pool); | |
324 return NGX_CONF_ERROR; | |
325 } | |
326 | |
327 map->hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash; | |
324 } | 328 } |
325 | 329 |
326 ngx_destroy_pool(pool); | 330 ngx_destroy_pool(pool); |
327 | 331 |
328 return rv; | 332 return rv; |
342 | 346 |
343 | 347 |
344 static char * | 348 static char * |
345 ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) | 349 ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) |
346 { | 350 { |
347 u_char ch; | |
348 ngx_int_t rc; | 351 ngx_int_t rc; |
349 ngx_str_t *value, file; | 352 ngx_str_t *value, file; |
350 ngx_uint_t i, key, flags; | 353 ngx_uint_t i, key; |
351 ngx_http_map_conf_ctx_t *ctx; | 354 ngx_http_map_conf_ctx_t *ctx; |
352 ngx_http_variable_value_t *var, **vp; | 355 ngx_http_variable_value_t *var, **vp; |
353 | 356 |
354 ctx = cf->ctx; | 357 ctx = cf->ctx; |
355 | 358 |
437 | 440 |
438 *vp = var; | 441 *vp = var; |
439 | 442 |
440 found: | 443 found: |
441 | 444 |
442 ch = value[0].data[0]; | 445 if (ngx_strcmp(value[0].data, "default") == 0) { |
443 | 446 |
444 if ((ch != '*' && ch != '.') || ctx->hostnames == 0) { | 447 if (ctx->default_value) { |
445 | |
446 if (ngx_strcmp(value[0].data, "default") == 0) { | |
447 | |
448 if (ctx->default_value) { | |
449 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
450 "duplicate default map parameter"); | |
451 return NGX_CONF_ERROR; | |
452 } | |
453 | |
454 ctx->default_value = var; | |
455 | |
456 return NGX_CONF_OK; | |
457 } | |
458 | |
459 if (value[0].len && ch == '!') { | |
460 value[0].len--; | |
461 value[0].data++; | |
462 } | |
463 | |
464 flags = 0; | |
465 | |
466 } else { | |
467 | |
468 if ((ch == '*' && (value[0].len < 3 || value[0].data[1] != '.')) | |
469 || (ch == '.' && value[0].len < 2)) | |
470 { | |
471 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 448 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
472 "invalid DNS wildcard \"%V\"", &value[0]); | 449 "duplicate default map parameter"); |
473 | 450 return NGX_CONF_ERROR; |
474 return NGX_CONF_ERROR; | 451 } |
475 } | 452 |
476 | 453 ctx->default_value = var; |
477 flags = NGX_HASH_WILDCARD_KEY; | 454 |
478 } | 455 return NGX_CONF_OK; |
479 | 456 } |
480 rc = ngx_hash_add_key(&ctx->keys, &value[0], var, flags); | 457 |
458 if (value[0].len && value[0].data[0] == '!') { | |
459 value[0].len--; | |
460 value[0].data++; | |
461 } | |
462 | |
463 rc = ngx_hash_add_key(&ctx->keys, &value[0], var, | |
464 (ctx->hostnames) ? NGX_HASH_WILDCARD_KEY : 0); | |
481 | 465 |
482 if (rc == NGX_OK) { | 466 if (rc == NGX_OK) { |
483 return NGX_CONF_OK; | 467 return NGX_CONF_OK; |
468 } | |
469 | |
470 if (rc == NGX_DECLINED) { | |
471 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
472 "invalid hostname or wildcard \"%V\"", &value[0]); | |
484 } | 473 } |
485 | 474 |
486 if (rc == NGX_BUSY) { | 475 if (rc == NGX_BUSY) { |
487 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 476 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
488 "conflicting parameter \"%V\"", &value[0]); | 477 "conflicting parameter \"%V\"", &value[0]); |