comparison src/http/modules/ngx_http_referer_module.c @ 5351:a2c772963b04

Referer: "server_names" parsing deferred to merge phase. This allows to approach "server_name" values specified below the "valid_referers" directive when used within the "server_names" parameter, e.g.: server_name example.org; valid_referers server_names; server_name example.com; As a bonus, this fixes bogus error with "server_names" specified several times.
author Sergey Kandaurov <pluknet@nginx.com>
date Thu, 29 Aug 2013 22:35:27 +0400
parents 8220e393c241
children ec0be12c8e29
comparison
equal deleted inserted replaced
5350:8220e393c241 5351:a2c772963b04
21 ngx_array_t *server_name_regex; 21 ngx_array_t *server_name_regex;
22 #endif 22 #endif
23 23
24 ngx_flag_t no_referer; 24 ngx_flag_t no_referer;
25 ngx_flag_t blocked_referer; 25 ngx_flag_t blocked_referer;
26 ngx_flag_t server_names;
26 27
27 ngx_hash_keys_arrays_t *keys; 28 ngx_hash_keys_arrays_t *keys;
28 29
29 ngx_uint_t referer_hash_max_size; 30 ngx_uint_t referer_hash_max_size;
30 ngx_uint_t referer_hash_bucket_size; 31 ngx_uint_t referer_hash_bucket_size;
270 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_referer_conf_t)); 271 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_referer_conf_t));
271 if (conf == NULL) { 272 if (conf == NULL) {
272 return NULL; 273 return NULL;
273 } 274 }
274 275
276 /*
277 * set by ngx_pcalloc():
278 *
279 * conf->hash = { NULL };
280 * conf->server_names = 0;
281 * conf->keys = NULL;
282 */
283
275 #if (NGX_PCRE) 284 #if (NGX_PCRE)
276 conf->regex = NGX_CONF_UNSET_PTR; 285 conf->regex = NGX_CONF_UNSET_PTR;
277 conf->server_name_regex = NGX_CONF_UNSET_PTR; 286 conf->server_name_regex = NGX_CONF_UNSET_PTR;
278 #endif 287 #endif
279 288
290 ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child) 299 ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
291 { 300 {
292 ngx_http_referer_conf_t *prev = parent; 301 ngx_http_referer_conf_t *prev = parent;
293 ngx_http_referer_conf_t *conf = child; 302 ngx_http_referer_conf_t *conf = child;
294 303
295 ngx_hash_init_t hash; 304 ngx_uint_t n;
305 ngx_hash_init_t hash;
306 ngx_http_server_name_t *sn;
307 ngx_http_core_srv_conf_t *cscf;
296 308
297 if (conf->keys == NULL) { 309 if (conf->keys == NULL) {
298 conf->hash = prev->hash; 310 conf->hash = prev->hash;
299 311
300 #if (NGX_PCRE) 312 #if (NGX_PCRE)
308 prev->referer_hash_max_size, 2048); 320 prev->referer_hash_max_size, 2048);
309 ngx_conf_merge_uint_value(conf->referer_hash_bucket_size, 321 ngx_conf_merge_uint_value(conf->referer_hash_bucket_size,
310 prev->referer_hash_bucket_size, 64); 322 prev->referer_hash_bucket_size, 64);
311 323
312 return NGX_CONF_OK; 324 return NGX_CONF_OK;
325 }
326
327 if (conf->server_names == 1) {
328 cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module);
329
330 sn = cscf->server_names.elts;
331 for (n = 0; n < cscf->server_names.nelts; n++) {
332
333 #if (NGX_PCRE)
334 if (sn[n].regex) {
335
336 if (ngx_http_add_regex_server_name(cf, conf, sn[n].regex)
337 != NGX_OK)
338 {
339 return NGX_CONF_ERROR;
340 }
341
342 continue;
343 }
344 #endif
345
346 if (ngx_http_add_referer(cf, conf->keys, &sn[n].name, NULL)
347 != NGX_OK)
348 {
349 return NGX_CONF_ERROR;
350 }
351 }
313 } 352 }
314 353
315 if ((conf->no_referer == 1 || conf->blocked_referer == 1) 354 if ((conf->no_referer == 1 || conf->blocked_referer == 1)
316 && conf->keys->keys.nelts == 0 355 && conf->keys->keys.nelts == 0
317 && conf->keys->dns_wc_head.nelts == 0 356 && conf->keys->dns_wc_head.nelts == 0
413 { 452 {
414 ngx_http_referer_conf_t *rlcf = conf; 453 ngx_http_referer_conf_t *rlcf = conf;
415 454
416 u_char *p; 455 u_char *p;
417 ngx_str_t *value, uri, name; 456 ngx_str_t *value, uri, name;
418 ngx_uint_t i, n; 457 ngx_uint_t i;
419 ngx_http_variable_t *var; 458 ngx_http_variable_t *var;
420 ngx_http_server_name_t *sn;
421 ngx_http_core_srv_conf_t *cscf;
422 459
423 ngx_str_set(&name, "invalid_referer"); 460 ngx_str_set(&name, "invalid_referer");
424 461
425 var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE); 462 var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
426 if (var == NULL) { 463 if (var == NULL) {
460 if (ngx_strcmp(value[i].data, "blocked") == 0) { 497 if (ngx_strcmp(value[i].data, "blocked") == 0) {
461 rlcf->blocked_referer = 1; 498 rlcf->blocked_referer = 1;
462 continue; 499 continue;
463 } 500 }
464 501
465 ngx_str_null(&uri);
466
467 if (ngx_strcmp(value[i].data, "server_names") == 0) { 502 if (ngx_strcmp(value[i].data, "server_names") == 0) {
468 503 rlcf->server_names = 1;
469 cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module);
470
471 sn = cscf->server_names.elts;
472 for (n = 0; n < cscf->server_names.nelts; n++) {
473
474 #if (NGX_PCRE)
475 if (sn[n].regex) {
476
477 if (ngx_http_add_regex_server_name(cf, rlcf, sn[n].regex)
478 != NGX_OK)
479 {
480 return NGX_CONF_ERROR;
481 }
482
483 continue;
484 }
485 #endif
486
487 if (ngx_http_add_referer(cf, rlcf->keys, &sn[n].name, &uri)
488 != NGX_OK)
489 {
490 return NGX_CONF_ERROR;
491 }
492 }
493
494 continue; 504 continue;
495 } 505 }
496 506
497 if (value[i].data[0] == '~') { 507 if (value[i].data[0] == '~') {
498 if (ngx_http_add_regex_referer(cf, rlcf, &value[i]) != NGX_OK) { 508 if (ngx_http_add_regex_referer(cf, rlcf, &value[i]) != NGX_OK) {
500 } 510 }
501 511
502 continue; 512 continue;
503 } 513 }
504 514
515 ngx_str_null(&uri);
516
505 p = (u_char *) ngx_strchr(value[i].data, '/'); 517 p = (u_char *) ngx_strchr(value[i].data, '/');
506 518
507 if (p) { 519 if (p) {
508 uri.len = (value[i].data + value[i].len) - p; 520 uri.len = (value[i].data + value[i].len) - p;
509 uri.data = p; 521 uri.data = p;
524 ngx_str_t *value, ngx_str_t *uri) 536 ngx_str_t *value, ngx_str_t *uri)
525 { 537 {
526 ngx_int_t rc; 538 ngx_int_t rc;
527 ngx_str_t *u; 539 ngx_str_t *u;
528 540
529 if (uri->len == 0) { 541 if (uri == NULL || uri->len == 0) {
530 u = NGX_HTTP_REFERER_NO_URI_PART; 542 u = NGX_HTTP_REFERER_NO_URI_PART;
531 543
532 } else { 544 } else {
533 u = ngx_palloc(cf->pool, sizeof(ngx_str_t)); 545 u = ngx_palloc(cf->pool, sizeof(ngx_str_t));
534 if (u == NULL) { 546 if (u == NULL) {