12
12
#define NGX_HTTP_REFERER_NO_URI_PART ((void *) 4)
16
ngx_hash_wildcard_t *dns_wildcards;
19
} ngx_http_referer_regex_t;
23
#define ngx_regex_t void
29
ngx_hash_combined_t hash;
18
35
ngx_flag_t no_referer;
19
36
ngx_flag_t blocked_referer;
30
47
static char *ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
31
48
ngx_str_t *value, ngx_str_t *uri);
49
static char *ngx_http_add_regex_referer(ngx_conf_t *cf,
50
ngx_http_referer_conf_t *rlcf, ngx_str_t *name, ngx_regex_t *regex);
32
51
static int ngx_libc_cdecl ngx_http_cmp_referer_wildcards(const void *one,
81
100
ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
84
u_char *p, *ref, *last;
88
ngx_http_referer_conf_t *rlcf;
103
u_char *p, *ref, *last;
107
ngx_http_referer_conf_t *rlcf;
112
ngx_http_referer_regex_t *regex;
91
115
rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module);
93
if (rlcf->hash.buckets == NULL && rlcf->dns_wildcards == NULL) {
117
if (rlcf->hash.hash.buckets == NULL
118
&& rlcf->hash.wc_head == NULL
119
&& rlcf->hash.wc_tail == NULL
121
&& rlcf->regex == NULL
138
if (rlcf->hash.buckets) {
139
uri = ngx_hash_find(&rlcf->hash, key, buf, len);
145
if (rlcf->dns_wildcards) {
146
uri = ngx_hash_find_wildcard(rlcf->dns_wildcards, buf, len);
167
uri = ngx_hash_find_combined(&rlcf->hash, key, buf, p - ref);
177
referer.len = len - 7;
180
regex = rlcf->regex->elts;
182
for (i = 0; i < rlcf->regex->nelts; i++) {
183
n = ngx_regex_exec(regex[i].regex, &referer, NULL, 0);
185
if (n == NGX_REGEX_NO_MATCHED) {
190
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
192
" failed: %d on \"%V\" using \"%V\"",
193
n, &referer, ®ex[i].name);
209
262
if (conf->keys == NULL) {
210
263
conf->hash = prev->hash;
211
conf->dns_wildcards = prev->dns_wildcards;
213
265
ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0);
214
266
ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0);
219
271
if ((conf->no_referer == 1 || conf->blocked_referer == 1)
220
&& conf->keys->keys.nelts == 0 && conf->keys->dns_wildcards.nelts == 0)
272
&& conf->keys->keys.nelts == 0
273
&& conf->keys->dns_wc_head.nelts == 0
274
&& conf->keys->dns_wc_tail.nelts == 0)
222
276
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
223
277
"the \"none\" or \"blocked\" referers are specified "
246
if (conf->keys->dns_wildcards.nelts) {
248
ngx_qsort(conf->keys->dns_wildcards.elts,
249
(size_t) conf->keys->dns_wildcards.nelts,
250
sizeof(ngx_hash_key_t),
251
ngx_http_cmp_referer_wildcards);
254
hash.temp_pool = cf->temp_pool;
256
if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wildcards.elts,
257
conf->keys->dns_wildcards.nelts)
260
return NGX_CONF_ERROR;
263
conf->dns_wildcards = (ngx_hash_wildcard_t *) hash.hash;
300
if (conf->keys->dns_wc_head.nelts) {
302
ngx_qsort(conf->keys->dns_wc_head.elts,
303
(size_t) conf->keys->dns_wc_head.nelts,
304
sizeof(ngx_hash_key_t),
305
ngx_http_cmp_referer_wildcards);
308
hash.temp_pool = cf->temp_pool;
310
if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wc_head.elts,
311
conf->keys->dns_wc_head.nelts)
314
return NGX_CONF_ERROR;
317
conf->hash.wc_head = (ngx_hash_wildcard_t *) hash.hash;
320
if (conf->keys->dns_wc_tail.nelts) {
322
ngx_qsort(conf->keys->dns_wc_tail.elts,
323
(size_t) conf->keys->dns_wc_tail.nelts,
324
sizeof(ngx_hash_key_t),
325
ngx_http_cmp_referer_wildcards);
328
hash.temp_pool = cf->temp_pool;
330
if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wc_tail.elts,
331
conf->keys->dns_wc_tail.nelts)
334
return NGX_CONF_ERROR;
337
conf->hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash;
266
340
if (conf->no_referer == NGX_CONF_UNSET) {
343
417
sn = cscf->server_names.elts;
344
418
for (n = 0; n < cscf->server_names.nelts; n++) {
423
if (ngx_http_add_regex_referer(cf, rlcf, &sn[n].name,
427
return NGX_CONF_ERROR;
345
434
if (ngx_http_add_referer(cf, rlcf->keys, &sn[n].name, &uri)
444
if (value[i].data[0] == '~') {
445
if (ngx_http_add_regex_referer(cf, rlcf, &value[i], NULL) != NGX_OK)
447
return NGX_CONF_ERROR;
355
453
p = (u_char *) ngx_strchr(value[i].data, '/');
373
471
ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
374
472
ngx_str_t *value, ngx_str_t *uri)
383
if ((ch == '*' && (value->len < 3 || value->data[1] != '.'))
384
|| (ch == '.' && value->len < 2))
386
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
387
"invalid DNS wildcard \"%V\"", value);
389
return NGX_CONF_ERROR;
392
flags = (ch == '*' || ch == '.') ? NGX_HASH_WILDCARD_KEY : 0;
394
477
if (uri->len == 0) {
395
478
u = NGX_HTTP_REFERER_NO_URI_PART;
406
rc = ngx_hash_add_key(keys, value, u, flags);
489
rc = ngx_hash_add_key(keys, value, u, NGX_HASH_WILDCARD_KEY);
408
491
if (rc == NGX_OK) {
409
492
return NGX_CONF_OK;
495
if (rc == NGX_DECLINED) {
496
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
497
"invalid hostname or wildcard \"%V\"", value);
412
500
if (rc == NGX_BUSY) {
413
501
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
414
502
"conflicting parameter \"%V\"", value);
510
ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
511
ngx_str_t *name, ngx_regex_t *regex)
515
ngx_http_referer_regex_t *rr;
516
u_char errstr[NGX_MAX_CONF_ERRSTR];
518
if (rlcf->regex == NULL) {
519
rlcf->regex = ngx_array_create(cf->pool, 2,
520
sizeof(ngx_http_referer_regex_t));
521
if (rlcf->regex == NULL) {
522
return NGX_CONF_ERROR;
526
rr = ngx_array_push(rlcf->regex);
528
return NGX_CONF_ERROR;
538
err.len = NGX_MAX_CONF_ERRSTR;
544
rr->regex = ngx_regex_compile(name, NGX_REGEX_CASELESS, cf->pool, &err);
546
if (rr->regex == NULL) {
547
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
548
return NGX_CONF_ERROR;
557
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
558
"the using of the regex \"%V\" requires PCRE library",
561
return NGX_CONF_ERROR;
421
567
static int ngx_libc_cdecl
422
568
ngx_http_cmp_referer_wildcards(const void *one, const void *two)