Mercurial > hg > nginx
annotate src/http/modules/ngx_http_referer_module.c @ 3440:88741ec7731a stable-0.7
merge r3294, r3305:
Fix a bug introduced in r2032: After a child process has read a terminate
message from a channel, the process tries to read the channel again.
The kernel (at least FreeBSD) may preempt the process and sends a SIGIO
signal to a master process. The master process sends a new terminate message,
the kernel switches again to the the child process, and the child process
reads the messages instead of an EAGAIN error. And this may repeat over
and over. Being that the child process can not exit the cycle and test
the termination flag set by the message handler.
The fix disallow the master process to send a new terminate message on
SIGIO signal reception. It may send the message only on SIGALARM signal.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 01 Feb 2010 15:49:36 +0000 |
parents | 616ff375a68f |
children | 3031b5931864 |
rev | line source |
---|---|
577 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_http.h> | |
10 | |
11 | |
595 | 12 #define NGX_HTTP_REFERER_NO_URI_PART ((void *) 4) |
13 | |
1785 | 14 #if !(NGX_PCRE) |
1388 | 15 |
16 #define ngx_regex_t void | |
17 | |
18 #endif | |
19 | |
20 | |
577 | 21 typedef struct { |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
22 ngx_hash_combined_t hash; |
577 | 23 |
1388 | 24 #if (NGX_PCRE) |
25 ngx_array_t *regex; | |
26 #endif | |
27 | |
593 | 28 ngx_flag_t no_referer; |
29 ngx_flag_t blocked_referer; | |
577 | 30 |
593 | 31 ngx_hash_keys_arrays_t *keys; |
577 | 32 } ngx_http_referer_conf_t; |
33 | |
34 | |
35 static void * ngx_http_referer_create_conf(ngx_conf_t *cf); | |
36 static char * ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, | |
37 void *child); | |
38 static char *ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, | |
39 void *conf); | |
593 | 40 static char *ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys, |
595 | 41 ngx_str_t *value, ngx_str_t *uri); |
1388 | 42 static char *ngx_http_add_regex_referer(ngx_conf_t *cf, |
43 ngx_http_referer_conf_t *rlcf, ngx_str_t *name, ngx_regex_t *regex); | |
593 | 44 static int ngx_libc_cdecl ngx_http_cmp_referer_wildcards(const void *one, |
45 const void *two); | |
577 | 46 |
47 | |
48 static ngx_command_t ngx_http_referer_commands[] = { | |
49 | |
50 { ngx_string("valid_referers"), | |
51 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
52 ngx_http_valid_referers, | |
53 NGX_HTTP_LOC_CONF_OFFSET, | |
54 0, | |
55 NULL }, | |
56 | |
57 ngx_null_command | |
58 }; | |
59 | |
60 | |
61 static ngx_http_module_t ngx_http_referer_module_ctx = { | |
62 NULL, /* preconfiguration */ | |
63 NULL, /* postconfiguration */ | |
64 | |
65 NULL, /* create main configuration */ | |
66 NULL, /* init main configuration */ | |
67 | |
68 NULL, /* create server configuration */ | |
69 NULL, /* merge server configuration */ | |
70 | |
71 ngx_http_referer_create_conf, /* create location configuration */ | |
72 ngx_http_referer_merge_conf /* merge location configuration */ | |
73 }; | |
74 | |
75 | |
76 ngx_module_t ngx_http_referer_module = { | |
77 NGX_MODULE_V1, | |
78 &ngx_http_referer_module_ctx, /* module context */ | |
79 ngx_http_referer_commands, /* module directives */ | |
80 NGX_HTTP_MODULE, /* module type */ | |
81 NULL, /* init master */ | |
82 NULL, /* init module */ | |
83 NULL, /* init process */ | |
84 NULL, /* init thread */ | |
85 NULL, /* exit thread */ | |
86 NULL, /* exit process */ | |
87 NULL, /* exit master */ | |
88 NGX_MODULE_V1_PADDING | |
89 }; | |
90 | |
91 | |
92 static ngx_int_t | |
93 ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, | |
94 uintptr_t data) | |
95 { | |
1388 | 96 u_char *p, *ref, *last; |
97 size_t len; | |
98 ngx_str_t *uri; | |
99 ngx_uint_t i, key; | |
100 ngx_http_referer_conf_t *rlcf; | |
101 u_char buf[256]; | |
577 | 102 |
593 | 103 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module); |
577 | 104 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
105 if (rlcf->hash.hash.buckets == NULL |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
106 && rlcf->hash.wc_head == NULL |
1388 | 107 && rlcf->hash.wc_tail == NULL |
108 #if (NGX_PCRE) | |
109 && rlcf->regex == NULL | |
110 #endif | |
111 ) | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
112 { |
595 | 113 goto valid; |
577 | 114 } |
115 | |
116 if (r->headers_in.referer == NULL) { | |
593 | 117 if (rlcf->no_referer) { |
595 | 118 goto valid; |
119 } | |
577 | 120 |
595 | 121 goto invalid; |
577 | 122 } |
123 | |
124 len = r->headers_in.referer->value.len; | |
125 ref = r->headers_in.referer->value.data; | |
126 | |
127 if (len < sizeof("http://i.ru") - 1 | |
1107
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
637
diff
changeset
|
128 || (ngx_strncasecmp(ref, (u_char *) "http://", 7) != 0)) |
577 | 129 { |
593 | 130 if (rlcf->blocked_referer) { |
595 | 131 goto valid; |
132 } | |
577 | 133 |
595 | 134 goto invalid; |
577 | 135 } |
136 | |
595 | 137 last = ref + len; |
577 | 138 ref += 7; |
595 | 139 i = 0; |
140 key = 0; | |
577 | 141 |
595 | 142 for (p = ref; p < last; p++) { |
593 | 143 if (*p == '/' || *p == ':') { |
144 break; | |
577 | 145 } |
595 | 146 |
147 buf[i] = ngx_tolower(*p); | |
148 key = ngx_hash(key, buf[i++]); | |
149 | |
150 if (i == 256) { | |
151 goto invalid; | |
152 } | |
593 | 153 } |
577 | 154 |
1388 | 155 uri = ngx_hash_find_combined(&rlcf->hash, key, buf, p - ref); |
577 | 156 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
157 if (uri) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
158 goto uri; |
577 | 159 } |
160 | |
1388 | 161 #if (NGX_PCRE) |
162 | |
163 if (rlcf->regex) { | |
1785 | 164 ngx_int_t rc; |
165 ngx_str_t referer; | |
1388 | 166 |
167 referer.len = len - 7; | |
168 referer.data = ref; | |
169 | |
1785 | 170 rc = ngx_regex_exec_array(rlcf->regex, &referer, r->connection->log); |
1388 | 171 |
1785 | 172 if (rc == NGX_OK) { |
1388 | 173 goto valid; |
174 } | |
1785 | 175 |
176 if (rc == NGX_ERROR) { | |
177 return rc; | |
178 } | |
179 | |
180 /* NGX_DECLINED */ | |
1388 | 181 } |
182 | |
183 #endif | |
184 | |
595 | 185 invalid: |
186 | |
577 | 187 *v = ngx_http_variable_true_value; |
188 | |
189 return NGX_OK; | |
595 | 190 |
191 uri: | |
192 | |
193 for ( /* void */ ; p < last; p++) { | |
194 if (*p == '/') { | |
195 break; | |
196 } | |
197 } | |
198 | |
199 len = last - p; | |
200 | |
201 if (uri == NGX_HTTP_REFERER_NO_URI_PART) { | |
202 goto valid; | |
203 } | |
204 | |
205 if (len < uri->len || ngx_strncmp(uri->data, p, uri->len) != 0) { | |
206 goto invalid; | |
207 } | |
208 | |
209 valid: | |
210 | |
211 *v = ngx_http_variable_null_value; | |
212 | |
213 return NGX_OK; | |
577 | 214 } |
215 | |
216 | |
217 static void * | |
218 ngx_http_referer_create_conf(ngx_conf_t *cf) | |
219 { | |
220 ngx_http_referer_conf_t *conf; | |
221 | |
593 | 222 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_referer_conf_t)); |
577 | 223 if (conf == NULL) { |
3237
2efa8d2fcde1
merge r2903, r2911, r2912, r3002:
Igor Sysoev <igor@sysoev.ru>
parents:
1800
diff
changeset
|
224 return NULL; |
577 | 225 } |
226 | |
1782
db07cb9d1cbc
regex valid_referers were not inherited
Igor Sysoev <igor@sysoev.ru>
parents:
1704
diff
changeset
|
227 #if (NGX_PCRE) |
db07cb9d1cbc
regex valid_referers were not inherited
Igor Sysoev <igor@sysoev.ru>
parents:
1704
diff
changeset
|
228 conf->regex = NGX_CONF_UNSET_PTR; |
db07cb9d1cbc
regex valid_referers were not inherited
Igor Sysoev <igor@sysoev.ru>
parents:
1704
diff
changeset
|
229 #endif |
db07cb9d1cbc
regex valid_referers were not inherited
Igor Sysoev <igor@sysoev.ru>
parents:
1704
diff
changeset
|
230 |
577 | 231 conf->no_referer = NGX_CONF_UNSET; |
232 conf->blocked_referer = NGX_CONF_UNSET; | |
233 | |
234 return conf; | |
235 } | |
236 | |
237 | |
238 static char * | |
239 ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child) | |
240 { | |
241 ngx_http_referer_conf_t *prev = parent; | |
242 ngx_http_referer_conf_t *conf = child; | |
243 | |
593 | 244 ngx_hash_init_t hash; |
245 | |
246 if (conf->keys == NULL) { | |
247 conf->hash = prev->hash; | |
248 | |
1800 | 249 #if (NGX_PCRE) |
1782
db07cb9d1cbc
regex valid_referers were not inherited
Igor Sysoev <igor@sysoev.ru>
parents:
1704
diff
changeset
|
250 ngx_conf_merge_ptr_value(conf->regex, prev->regex, NULL); |
1800 | 251 #endif |
577 | 252 ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0); |
253 ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0); | |
593 | 254 |
255 return NGX_CONF_OK; | |
256 } | |
257 | |
603 | 258 if ((conf->no_referer == 1 || conf->blocked_referer == 1) |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
259 && conf->keys->keys.nelts == 0 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
260 && conf->keys->dns_wc_head.nelts == 0 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
261 && conf->keys->dns_wc_tail.nelts == 0) |
603 | 262 { |
263 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
264 "the \"none\" or \"blocked\" referers are specified " | |
265 "in the \"valid_referers\" directive " | |
266 "without any valid referer"); | |
267 return NGX_CONF_ERROR; | |
268 } | |
269 | |
593 | 270 hash.key = ngx_hash_key_lc; |
271 hash.max_size = 2048; /* TODO: referer_hash_max_size; */ | |
272 hash.bucket_size = 64; /* TODO: referer_hash_bucket_size; */ | |
273 hash.name = "referers_hash"; | |
274 hash.pool = cf->pool; | |
275 | |
276 if (conf->keys->keys.nelts) { | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
277 hash.hash = &conf->hash.hash; |
593 | 278 hash.temp_pool = NULL; |
279 | |
280 if (ngx_hash_init(&hash, conf->keys->keys.elts, conf->keys->keys.nelts) | |
281 != NGX_OK) | |
282 { | |
283 return NGX_CONF_ERROR; | |
284 } | |
285 } | |
286 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
287 if (conf->keys->dns_wc_head.nelts) { |
593 | 288 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
289 ngx_qsort(conf->keys->dns_wc_head.elts, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
290 (size_t) conf->keys->dns_wc_head.nelts, |
593 | 291 sizeof(ngx_hash_key_t), |
292 ngx_http_cmp_referer_wildcards); | |
293 | |
294 hash.hash = NULL; | |
295 hash.temp_pool = cf->temp_pool; | |
296 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
297 if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wc_head.elts, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
298 conf->keys->dns_wc_head.nelts) |
593 | 299 != NGX_OK) |
300 { | |
301 return NGX_CONF_ERROR; | |
302 } | |
303 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
304 conf->hash.wc_head = (ngx_hash_wildcard_t *) hash.hash; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
305 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
306 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
307 if (conf->keys->dns_wc_tail.nelts) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
308 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
309 ngx_qsort(conf->keys->dns_wc_tail.elts, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
310 (size_t) conf->keys->dns_wc_tail.nelts, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
311 sizeof(ngx_hash_key_t), |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
312 ngx_http_cmp_referer_wildcards); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
313 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
314 hash.hash = NULL; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
315 hash.temp_pool = cf->temp_pool; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
316 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
317 if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wc_tail.elts, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
318 conf->keys->dns_wc_tail.nelts) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
319 != NGX_OK) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
320 { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
321 return NGX_CONF_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
322 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
323 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
324 conf->hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash; |
577 | 325 } |
326 | |
1800 | 327 #if (NGX_PCRE) |
1782
db07cb9d1cbc
regex valid_referers were not inherited
Igor Sysoev <igor@sysoev.ru>
parents:
1704
diff
changeset
|
328 ngx_conf_merge_ptr_value(conf->regex, prev->regex, NULL); |
1800 | 329 #endif |
1782
db07cb9d1cbc
regex valid_referers were not inherited
Igor Sysoev <igor@sysoev.ru>
parents:
1704
diff
changeset
|
330 |
577 | 331 if (conf->no_referer == NGX_CONF_UNSET) { |
332 conf->no_referer = 0; | |
333 } | |
334 | |
335 if (conf->blocked_referer == NGX_CONF_UNSET) { | |
336 conf->blocked_referer = 0; | |
337 } | |
338 | |
611 | 339 conf->keys = NULL; |
340 | |
577 | 341 return NGX_CONF_OK; |
342 } | |
343 | |
344 | |
345 static char * | |
346 ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
347 { | |
593 | 348 ngx_http_referer_conf_t *rlcf = conf; |
577 | 349 |
593 | 350 u_char *p; |
595 | 351 ngx_str_t *value, uri, name; |
593 | 352 ngx_uint_t i, n; |
577 | 353 ngx_http_variable_t *var; |
354 ngx_http_server_name_t *sn; | |
355 ngx_http_core_srv_conf_t *cscf; | |
356 | |
357 name.len = sizeof("invalid_referer") - 1; | |
358 name.data = (u_char *) "invalid_referer"; | |
359 | |
583 | 360 var = ngx_http_add_variable(cf, &name, |
1565 | 361 NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOHASH); |
577 | 362 if (var == NULL) { |
363 return NGX_CONF_ERROR; | |
364 } | |
365 | |
637 | 366 var->get_handler = ngx_http_referer_variable; |
577 | 367 |
593 | 368 if (rlcf->keys == NULL) { |
369 rlcf->keys = ngx_pcalloc(cf->temp_pool, sizeof(ngx_hash_keys_arrays_t)); | |
370 if (rlcf->keys == NULL) { | |
371 return NGX_CONF_ERROR; | |
372 } | |
577 | 373 |
593 | 374 rlcf->keys->pool = cf->pool; |
375 rlcf->keys->temp_pool = cf->pool; | |
376 | |
377 if (ngx_hash_keys_array_init(rlcf->keys, NGX_HASH_SMALL) != NGX_OK) { | |
577 | 378 return NGX_CONF_ERROR; |
379 } | |
380 } | |
381 | |
382 value = cf->args->elts; | |
383 | |
384 for (i = 1; i < cf->args->nelts; i++) { | |
385 if (value[i].len == 0) { | |
386 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
387 "invalid referer \"%V\"", &value[i]); | |
388 return NGX_CONF_ERROR; | |
389 } | |
390 | |
391 if (ngx_strcmp(value[i].data, "none") == 0) { | |
593 | 392 rlcf->no_referer = 1; |
577 | 393 continue; |
394 } | |
395 | |
396 if (ngx_strcmp(value[i].data, "blocked") == 0) { | |
593 | 397 rlcf->blocked_referer = 1; |
577 | 398 continue; |
399 } | |
400 | |
595 | 401 uri.len = 0; |
613 | 402 uri.data = NULL; |
595 | 403 |
577 | 404 if (ngx_strcmp(value[i].data, "server_names") == 0) { |
593 | 405 |
406 cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module); | |
577 | 407 |
593 | 408 sn = cscf->server_names.elts; |
409 for (n = 0; n < cscf->server_names.nelts; n++) { | |
1388 | 410 |
411 #if (NGX_PCRE) | |
412 if (sn[n].regex) { | |
413 | |
414 if (ngx_http_add_regex_referer(cf, rlcf, &sn[n].name, | |
415 sn[n].regex) | |
416 != NGX_OK) | |
417 { | |
418 return NGX_CONF_ERROR; | |
419 } | |
420 | |
421 continue; | |
422 } | |
423 #endif | |
424 | |
595 | 425 if (ngx_http_add_referer(cf, rlcf->keys, &sn[n].name, &uri) |
426 != NGX_OK) | |
427 { | |
593 | 428 return NGX_CONF_ERROR; |
429 } | |
430 } | |
577 | 431 |
432 continue; | |
433 } | |
434 | |
1388 | 435 if (value[i].data[0] == '~') { |
436 if (ngx_http_add_regex_referer(cf, rlcf, &value[i], NULL) != NGX_OK) | |
437 { | |
438 return NGX_CONF_ERROR; | |
439 } | |
440 | |
441 continue; | |
442 } | |
443 | |
1242 | 444 p = (u_char *) ngx_strchr(value[i].data, '/'); |
577 | 445 |
593 | 446 if (p) { |
595 | 447 uri.len = (value[i].data + value[i].len) - p; |
448 uri.data = p; | |
593 | 449 value[i].len = p - value[i].data; |
577 | 450 } |
451 | |
595 | 452 if (ngx_http_add_referer(cf, rlcf->keys, &value[i], &uri) != NGX_OK) { |
577 | 453 return NGX_CONF_ERROR; |
454 } | |
455 } | |
456 | |
457 return NGX_CONF_OK; | |
458 } | |
593 | 459 |
460 | |
461 static char * | |
462 ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys, | |
595 | 463 ngx_str_t *value, ngx_str_t *uri) |
593 | 464 { |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
465 ngx_int_t rc; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
466 ngx_str_t *u; |
593 | 467 |
595 | 468 if (uri->len == 0) { |
469 u = NGX_HTTP_REFERER_NO_URI_PART; | |
470 | |
471 } else { | |
472 u = ngx_palloc(cf->pool, sizeof(ngx_str_t)); | |
473 if (u == NULL) { | |
474 return NGX_CONF_ERROR; | |
475 } | |
476 | |
477 *u = *uri; | |
478 } | |
479 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
480 rc = ngx_hash_add_key(keys, value, u, NGX_HASH_WILDCARD_KEY); |
593 | 481 |
482 if (rc == NGX_OK) { | |
483 return NGX_CONF_OK; | |
484 } | |
485 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
486 if (rc == NGX_DECLINED) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
487 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
488 "invalid hostname or wildcard \"%V\"", value); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
489 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
490 |
593 | 491 if (rc == NGX_BUSY) { |
492 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
493 "conflicting parameter \"%V\"", value); | |
494 } | |
495 | |
496 return NGX_CONF_ERROR; | |
497 } | |
498 | |
499 | |
1388 | 500 static char * |
501 ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf, | |
502 ngx_str_t *name, ngx_regex_t *regex) | |
503 { | |
504 #if (NGX_PCRE) | |
1785 | 505 ngx_str_t err; |
506 ngx_regex_elt_t *re; | |
507 u_char errstr[NGX_MAX_CONF_ERRSTR]; | |
1388 | 508 |
3335 | 509 if (name->len == 1) { |
510 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "empty regex in \"%V\"", name); | |
511 return NGX_CONF_ERROR; | |
512 } | |
513 | |
1782
db07cb9d1cbc
regex valid_referers were not inherited
Igor Sysoev <igor@sysoev.ru>
parents:
1704
diff
changeset
|
514 if (rlcf->regex == NGX_CONF_UNSET_PTR) { |
1785 | 515 rlcf->regex = ngx_array_create(cf->pool, 2, sizeof(ngx_regex_elt_t)); |
1388 | 516 if (rlcf->regex == NULL) { |
517 return NGX_CONF_ERROR; | |
518 } | |
519 } | |
520 | |
1785 | 521 re = ngx_array_push(rlcf->regex); |
522 if (re == NULL) { | |
1388 | 523 return NGX_CONF_ERROR; |
524 } | |
525 | |
526 if (regex) { | |
1785 | 527 re->regex = regex; |
528 re->name = name->data; | |
1388 | 529 |
530 return NGX_CONF_OK; | |
531 } | |
532 | |
533 err.len = NGX_MAX_CONF_ERRSTR; | |
534 err.data = errstr; | |
535 | |
536 name->len--; | |
537 name->data++; | |
538 | |
1785 | 539 re->regex = ngx_regex_compile(name, NGX_REGEX_CASELESS, cf->pool, &err); |
1388 | 540 |
1785 | 541 if (re->regex == NULL) { |
1388 | 542 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); |
543 return NGX_CONF_ERROR; | |
544 } | |
545 | |
1785 | 546 re->name = name->data; |
1388 | 547 |
548 return NGX_CONF_OK; | |
549 | |
550 #else | |
551 | |
552 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
553 "the using of the regex \"%V\" requires PCRE library", | |
554 name); | |
555 | |
556 return NGX_CONF_ERROR; | |
557 | |
558 #endif | |
559 } | |
560 | |
561 | |
593 | 562 static int ngx_libc_cdecl |
563 ngx_http_cmp_referer_wildcards(const void *one, const void *two) | |
564 { | |
565 ngx_hash_key_t *first, *second; | |
566 | |
567 first = (ngx_hash_key_t *) one; | |
568 second = (ngx_hash_key_t *) two; | |
569 | |
3335 | 570 return ngx_dns_strcmp(first->key.data, second->key.data); |
593 | 571 } |