comparison src/http/modules/ngx_http_referer_module.c @ 326:9fc4ab6673f9 NGINX_0_6_7

nginx 0.6.7 *) Change: now the paths specified in the "include", "auth_basic_user_file", "perl_modules", "ssl_certificate", "ssl_certificate_key", and "ssl_client_certificate" directives are relative to directory of nginx configuration file nginx.conf, but not to nginx prefix directory. *) Change: the --sysconfdir=PATH option in configure was canceled. *) Change: the special make target "upgrade1" was defined for online upgrade of 0.1.x versions. *) Feature: the "server_name" and "valid_referers" directives support regular expressions. *) Feature: the "server" directive in the "upstream" context supports the "backup" parameter. *) Feature: the ngx_http_perl_module supports the $r->discard_request_body. *) Feature: the "add_header Last-Modified ..." directive changes the "Last-Modified" response header line. *) Bugfix: if an response different than 200 was returned to an request with body and connection went to the keep-alive state after the request, then nginx returned 400 for the next request. *) Bugfix: a segmentation fault occurred in worker process if invalid address was set in the "auth_http" directive. *) Bugfix: now nginx uses default listen backlog value 511 on all platforms except FreeBSD. Thanks to Jiang Hong. *) Bugfix: a worker process may got caught in an endless loop, if an "server" inside "upstream" block was marked as "down"; bug appeared in 0.6.6. *) Bugfix: now Solaris sendfilev() is not used to transfer the client request body to FastCGI-server via the unix domain socket.
author Igor Sysoev <http://sysoev.ru>
date Wed, 15 Aug 2007 00:00:00 +0400
parents 429900ca25ee
children 10cc350ed8a1
comparison
equal deleted inserted replaced
325:f395c7a4c8a8 326:9fc4ab6673f9
9 #include <ngx_http.h> 9 #include <ngx_http.h>
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 #if (NGX_PCRE)
15
16 typedef struct {
17 ngx_regex_t *regex;
18 ngx_str_t name;
19 } ngx_http_referer_regex_t;
20
21 #else
22
23 #define ngx_regex_t void
24
25 #endif
26
27
14 typedef struct { 28 typedef struct {
15 ngx_hash_combined_t hash; 29 ngx_hash_combined_t hash;
30
31 #if (NGX_PCRE)
32 ngx_array_t *regex;
33 #endif
16 34
17 ngx_flag_t no_referer; 35 ngx_flag_t no_referer;
18 ngx_flag_t blocked_referer; 36 ngx_flag_t blocked_referer;
19 37
20 ngx_hash_keys_arrays_t *keys; 38 ngx_hash_keys_arrays_t *keys;
26 void *child); 44 void *child);
27 static char *ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, 45 static char *ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd,
28 void *conf); 46 void *conf);
29 static char *ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys, 47 static char *ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
30 ngx_str_t *value, ngx_str_t *uri); 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);
31 static int ngx_libc_cdecl ngx_http_cmp_referer_wildcards(const void *one, 51 static int ngx_libc_cdecl ngx_http_cmp_referer_wildcards(const void *one,
32 const void *two); 52 const void *two);
33 53
34 54
35 static ngx_command_t ngx_http_referer_commands[] = { 55 static ngx_command_t ngx_http_referer_commands[] = {
78 98
79 static ngx_int_t 99 static ngx_int_t
80 ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, 100 ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
81 uintptr_t data) 101 uintptr_t data)
82 { 102 {
83 u_char *p, *ref, *last; 103 u_char *p, *ref, *last;
84 size_t len; 104 size_t len;
85 ngx_str_t *uri; 105 ngx_str_t *uri;
86 ngx_uint_t i, key; 106 ngx_uint_t i, key;
87 ngx_http_referer_conf_t *rlcf; 107 ngx_http_referer_conf_t *rlcf;
88 u_char buf[256]; 108 u_char buf[256];
109 #if (NGX_PCRE)
110 ngx_int_t n;
111 ngx_str_t referer;
112 ngx_http_referer_regex_t *regex;
113 #endif
89 114
90 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module); 115 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module);
91 116
92 if (rlcf->hash.hash.buckets == NULL 117 if (rlcf->hash.hash.buckets == NULL
93 && rlcf->hash.wc_head == NULL 118 && rlcf->hash.wc_head == NULL
94 && rlcf->hash.wc_tail == NULL) 119 && rlcf->hash.wc_tail == NULL
120 #if (NGX_PCRE)
121 && rlcf->regex == NULL
122 #endif
123 )
95 { 124 {
96 goto valid; 125 goto valid;
97 } 126 }
98 127
99 if (r->headers_in.referer == NULL) { 128 if (r->headers_in.referer == NULL) {
133 if (i == 256) { 162 if (i == 256) {
134 goto invalid; 163 goto invalid;
135 } 164 }
136 } 165 }
137 166
138 len = p - ref; 167 uri = ngx_hash_find_combined(&rlcf->hash, key, buf, p - ref);
139
140 uri = ngx_hash_find_combined(&rlcf->hash, key, buf, len);
141 168
142 if (uri) { 169 if (uri) {
143 goto uri; 170 goto uri;
144 } 171 }
172
173 #if (NGX_PCRE)
174
175 if (rlcf->regex) {
176
177 referer.len = len - 7;
178 referer.data = ref;
179
180 regex = rlcf->regex->elts;
181
182 for (i = 0; i < rlcf->regex->nelts; i++) {
183 n = ngx_regex_exec(regex[i].regex, &referer, NULL, 0);
184
185 if (n == NGX_REGEX_NO_MATCHED) {
186 continue;
187 }
188
189 if (n < 0) {
190 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
191 ngx_regex_exec_n
192 " failed: %d on \"%V\" using \"%V\"",
193 n, &referer, &regex[i].name);
194 return NGX_ERROR;
195 }
196
197 /* match */
198
199 goto valid;
200 }
201 }
202
203 #endif
145 204
146 invalid: 205 invalid:
147 206
148 *v = ngx_http_variable_true_value; 207 *v = ngx_http_variable_true_value;
149 208
355 414
356 cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module); 415 cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module);
357 416
358 sn = cscf->server_names.elts; 417 sn = cscf->server_names.elts;
359 for (n = 0; n < cscf->server_names.nelts; n++) { 418 for (n = 0; n < cscf->server_names.nelts; n++) {
419
420 #if (NGX_PCRE)
421 if (sn[n].regex) {
422
423 if (ngx_http_add_regex_referer(cf, rlcf, &sn[n].name,
424 sn[n].regex)
425 != NGX_OK)
426 {
427 return NGX_CONF_ERROR;
428 }
429
430 continue;
431 }
432 #endif
433
360 if (ngx_http_add_referer(cf, rlcf->keys, &sn[n].name, &uri) 434 if (ngx_http_add_referer(cf, rlcf->keys, &sn[n].name, &uri)
361 != NGX_OK) 435 != NGX_OK)
362 { 436 {
363 return NGX_CONF_ERROR; 437 return NGX_CONF_ERROR;
364 } 438 }
365 } 439 }
366 440
367 continue; 441 continue;
368 } 442 }
369 443
444 if (value[i].data[0] == '~') {
445 if (ngx_http_add_regex_referer(cf, rlcf, &value[i], NULL) != NGX_OK)
446 {
447 return NGX_CONF_ERROR;
448 }
449
450 continue;
451 }
452
370 p = (u_char *) ngx_strchr(value[i].data, '/'); 453 p = (u_char *) ngx_strchr(value[i].data, '/');
371 454
372 if (p) { 455 if (p) {
373 uri.len = (value[i].data + value[i].len) - p; 456 uri.len = (value[i].data + value[i].len) - p;
374 uri.data = p; 457 uri.data = p;
421 504
422 return NGX_CONF_ERROR; 505 return NGX_CONF_ERROR;
423 } 506 }
424 507
425 508
509 static char *
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)
512 {
513 #if (NGX_PCRE)
514 ngx_str_t err;
515 ngx_http_referer_regex_t *rr;
516 u_char errstr[NGX_MAX_CONF_ERRSTR];
517
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;
523 }
524 }
525
526 rr = ngx_array_push(rlcf->regex);
527 if (rr == NULL) {
528 return NGX_CONF_ERROR;
529 }
530
531 if (regex) {
532 rr->regex = regex;
533 rr->name = *name;
534
535 return NGX_CONF_OK;
536 }
537
538 err.len = NGX_MAX_CONF_ERRSTR;
539 err.data = errstr;
540
541 name->len--;
542 name->data++;
543
544 rr->regex = ngx_regex_compile(name, NGX_REGEX_CASELESS, cf->pool, &err);
545
546 if (rr->regex == NULL) {
547 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
548 return NGX_CONF_ERROR;
549 }
550
551 rr->name = *name;
552
553 return NGX_CONF_OK;
554
555 #else
556
557 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
558 "the using of the regex \"%V\" requires PCRE library",
559 name);
560
561 return NGX_CONF_ERROR;
562
563 #endif
564 }
565
566
426 static int ngx_libc_cdecl 567 static int ngx_libc_cdecl
427 ngx_http_cmp_referer_wildcards(const void *one, const void *two) 568 ngx_http_cmp_referer_wildcards(const void *one, const void *two)
428 { 569 {
429 ngx_hash_key_t *first, *second; 570 ngx_hash_key_t *first, *second;
430 571