comparison src/http/modules/ngx_http_map_module.c @ 312:429900ca25ee NGINX_0_6_0

nginx 0.6.0 *) Feature: the "server_name", "map", and "valid_referers" directives support the "www.example.*" wildcards.
author Igor Sysoev <http://sysoev.ru>
date Thu, 14 Jun 2007 00:00:00 +0400
parents fbf2b2f66c9f
children f7cd062ee035
comparison
equal deleted inserted replaced
311:fcb663e92663 312:429900ca25ee
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]);