Mercurial > hg > nginx
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) { |