comparison src/http/modules/ngx_http_referer_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 95d92ec39071
children 9fc4ab6673f9
comparison
equal deleted inserted replaced
311:fcb663e92663 312:429900ca25ee
10 10
11 11
12 #define NGX_HTTP_REFERER_NO_URI_PART ((void *) 4) 12 #define NGX_HTTP_REFERER_NO_URI_PART ((void *) 4)
13 13
14 typedef struct { 14 typedef struct {
15 ngx_hash_t hash; 15 ngx_hash_combined_t hash;
16 ngx_hash_wildcard_t *dns_wildcards;
17 16
18 ngx_flag_t no_referer; 17 ngx_flag_t no_referer;
19 ngx_flag_t blocked_referer; 18 ngx_flag_t blocked_referer;
20 19
21 ngx_hash_keys_arrays_t *keys; 20 ngx_hash_keys_arrays_t *keys;
88 ngx_http_referer_conf_t *rlcf; 87 ngx_http_referer_conf_t *rlcf;
89 u_char buf[256]; 88 u_char buf[256];
90 89
91 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module); 90 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module);
92 91
93 if (rlcf->hash.buckets == NULL && rlcf->dns_wildcards == NULL) { 92 if (rlcf->hash.hash.buckets == NULL
93 && rlcf->hash.wc_head == NULL
94 && rlcf->hash.wc_tail == NULL)
95 {
94 goto valid; 96 goto valid;
95 } 97 }
96 98
97 if (r->headers_in.referer == NULL) { 99 if (r->headers_in.referer == NULL) {
98 if (rlcf->no_referer) { 100 if (rlcf->no_referer) {
133 } 135 }
134 } 136 }
135 137
136 len = p - ref; 138 len = p - ref;
137 139
138 if (rlcf->hash.buckets) { 140 uri = ngx_hash_find_combined(&rlcf->hash, key, buf, len);
139 uri = ngx_hash_find(&rlcf->hash, key, buf, len); 141
140 if (uri) { 142 if (uri) {
141 goto uri; 143 goto uri;
142 }
143 }
144
145 if (rlcf->dns_wildcards) {
146 uri = ngx_hash_find_wildcard(rlcf->dns_wildcards, buf, len);
147 if (uri) {
148 goto uri;
149 }
150 } 144 }
151 145
152 invalid: 146 invalid:
153 147
154 *v = ngx_http_variable_true_value; 148 *v = ngx_http_variable_true_value;
206 200
207 ngx_hash_init_t hash; 201 ngx_hash_init_t hash;
208 202
209 if (conf->keys == NULL) { 203 if (conf->keys == NULL) {
210 conf->hash = prev->hash; 204 conf->hash = prev->hash;
211 conf->dns_wildcards = prev->dns_wildcards;
212 205
213 ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0); 206 ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0);
214 ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0); 207 ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0);
215 208
216 return NGX_CONF_OK; 209 return NGX_CONF_OK;
217 } 210 }
218 211
219 if ((conf->no_referer == 1 || conf->blocked_referer == 1) 212 if ((conf->no_referer == 1 || conf->blocked_referer == 1)
220 && conf->keys->keys.nelts == 0 && conf->keys->dns_wildcards.nelts == 0) 213 && conf->keys->keys.nelts == 0
214 && conf->keys->dns_wc_head.nelts == 0
215 && conf->keys->dns_wc_tail.nelts == 0)
221 { 216 {
222 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, 217 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
223 "the \"none\" or \"blocked\" referers are specified " 218 "the \"none\" or \"blocked\" referers are specified "
224 "in the \"valid_referers\" directive " 219 "in the \"valid_referers\" directive "
225 "without any valid referer"); 220 "without any valid referer");
231 hash.bucket_size = 64; /* TODO: referer_hash_bucket_size; */ 226 hash.bucket_size = 64; /* TODO: referer_hash_bucket_size; */
232 hash.name = "referers_hash"; 227 hash.name = "referers_hash";
233 hash.pool = cf->pool; 228 hash.pool = cf->pool;
234 229
235 if (conf->keys->keys.nelts) { 230 if (conf->keys->keys.nelts) {
236 hash.hash = &conf->hash; 231 hash.hash = &conf->hash.hash;
237 hash.temp_pool = NULL; 232 hash.temp_pool = NULL;
238 233
239 if (ngx_hash_init(&hash, conf->keys->keys.elts, conf->keys->keys.nelts) 234 if (ngx_hash_init(&hash, conf->keys->keys.elts, conf->keys->keys.nelts)
240 != NGX_OK) 235 != NGX_OK)
241 { 236 {
242 return NGX_CONF_ERROR; 237 return NGX_CONF_ERROR;
243 } 238 }
244 } 239 }
245 240
246 if (conf->keys->dns_wildcards.nelts) { 241 if (conf->keys->dns_wc_head.nelts) {
247 242
248 ngx_qsort(conf->keys->dns_wildcards.elts, 243 ngx_qsort(conf->keys->dns_wc_head.elts,
249 (size_t) conf->keys->dns_wildcards.nelts, 244 (size_t) conf->keys->dns_wc_head.nelts,
250 sizeof(ngx_hash_key_t), 245 sizeof(ngx_hash_key_t),
251 ngx_http_cmp_referer_wildcards); 246 ngx_http_cmp_referer_wildcards);
252 247
253 hash.hash = NULL; 248 hash.hash = NULL;
254 hash.temp_pool = cf->temp_pool; 249 hash.temp_pool = cf->temp_pool;
255 250
256 if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wildcards.elts, 251 if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wc_head.elts,
257 conf->keys->dns_wildcards.nelts) 252 conf->keys->dns_wc_head.nelts)
258 != NGX_OK) 253 != NGX_OK)
259 { 254 {
260 return NGX_CONF_ERROR; 255 return NGX_CONF_ERROR;
261 } 256 }
262 257
263 conf->dns_wildcards = (ngx_hash_wildcard_t *) hash.hash; 258 conf->hash.wc_head = (ngx_hash_wildcard_t *) hash.hash;
259 }
260
261 if (conf->keys->dns_wc_tail.nelts) {
262
263 ngx_qsort(conf->keys->dns_wc_tail.elts,
264 (size_t) conf->keys->dns_wc_tail.nelts,
265 sizeof(ngx_hash_key_t),
266 ngx_http_cmp_referer_wildcards);
267
268 hash.hash = NULL;
269 hash.temp_pool = cf->temp_pool;
270
271 if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wc_tail.elts,
272 conf->keys->dns_wc_tail.nelts)
273 != NGX_OK)
274 {
275 return NGX_CONF_ERROR;
276 }
277
278 conf->hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash;
264 } 279 }
265 280
266 if (conf->no_referer == NGX_CONF_UNSET) { 281 if (conf->no_referer == NGX_CONF_UNSET) {
267 conf->no_referer = 0; 282 conf->no_referer = 0;
268 } 283 }
371 386
372 static char * 387 static char *
373 ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys, 388 ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
374 ngx_str_t *value, ngx_str_t *uri) 389 ngx_str_t *value, ngx_str_t *uri)
375 { 390 {
376 u_char ch; 391 ngx_int_t rc;
377 ngx_int_t rc; 392 ngx_str_t *u;
378 ngx_str_t *u;
379 ngx_uint_t flags;
380
381 ch = value->data[0];
382
383 if ((ch == '*' && (value->len < 3 || value->data[1] != '.'))
384 || (ch == '.' && value->len < 2))
385 {
386 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
387 "invalid DNS wildcard \"%V\"", value);
388
389 return NGX_CONF_ERROR;
390 }
391
392 flags = (ch == '*' || ch == '.') ? NGX_HASH_WILDCARD_KEY : 0;
393 393
394 if (uri->len == 0) { 394 if (uri->len == 0) {
395 u = NGX_HTTP_REFERER_NO_URI_PART; 395 u = NGX_HTTP_REFERER_NO_URI_PART;
396 396
397 } else { 397 } else {
401 } 401 }
402 402
403 *u = *uri; 403 *u = *uri;
404 } 404 }
405 405
406 rc = ngx_hash_add_key(keys, value, u, flags); 406 rc = ngx_hash_add_key(keys, value, u, NGX_HASH_WILDCARD_KEY);
407 407
408 if (rc == NGX_OK) { 408 if (rc == NGX_OK) {
409 return NGX_CONF_OK; 409 return NGX_CONF_OK;
410 }
411
412 if (rc == NGX_DECLINED) {
413 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
414 "invalid hostname or wildcard \"%V\"", value);
410 } 415 }
411 416
412 if (rc == NGX_BUSY) { 417 if (rc == NGX_BUSY) {
413 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 418 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
414 "conflicting parameter \"%V\"", value); 419 "conflicting parameter \"%V\"", value);