comparison src/http/modules/ngx_http_referer_module.c @ 144:e1c6ac408b68 NGINX_0_3_19

nginx 0.3.19 *) Feature: the "path" and "alias" directives support the variables. *) Change: now the "valid_referers" directive again checks the URI part. *) Bugfix: in SSI handling.
author Igor Sysoev <http://sysoev.ru>
date Wed, 28 Dec 2005 00:00:00 +0300
parents 84910468f6de
children ea622d8acb38
comparison
equal deleted inserted replaced
143:c2fa0caa07f2 144:e1c6ac408b68
6 6
7 #include <ngx_config.h> 7 #include <ngx_config.h>
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 #include <ngx_http.h> 9 #include <ngx_http.h>
10 10
11
12 #define NGX_HTTP_REFERER_NO_URI_PART ((void *) 4)
11 13
12 typedef struct { 14 typedef struct {
13 ngx_hash_t hash; 15 ngx_hash_t hash;
14 ngx_hash_wildcard_t *dns_wildcards; 16 ngx_hash_wildcard_t *dns_wildcards;
15 17
24 static char * ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, 26 static char * ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent,
25 void *child); 27 void *child);
26 static char *ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, 28 static char *ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd,
27 void *conf); 29 void *conf);
28 static char *ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys, 30 static char *ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
29 ngx_str_t *value); 31 ngx_str_t *value, ngx_str_t *uri);
30 static int ngx_libc_cdecl ngx_http_cmp_referer_wildcards(const void *one, 32 static int ngx_libc_cdecl ngx_http_cmp_referer_wildcards(const void *one,
31 const void *two); 33 const void *two);
32 34
33 35
34 static ngx_command_t ngx_http_referer_commands[] = { 36 static ngx_command_t ngx_http_referer_commands[] = {
77 79
78 static ngx_int_t 80 static ngx_int_t
79 ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, 81 ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
80 uintptr_t data) 82 uintptr_t data)
81 { 83 {
82 u_char *p, *ref; 84 u_char *p, *ref, *last;
83 size_t len; 85 size_t len;
86 ngx_str_t *uri;
87 ngx_uint_t i, key;
84 ngx_http_referer_conf_t *rlcf; 88 ngx_http_referer_conf_t *rlcf;
89 u_char buf[256];
85 90
86 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module); 91 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module);
87 92
88 if (rlcf->hash.buckets == NULL 93 if (rlcf->hash.buckets == NULL
89 && rlcf->dns_wildcards == NULL 94 && rlcf->dns_wildcards == NULL
90 && rlcf->dns_wildcards->hash.buckets == NULL) 95 && rlcf->dns_wildcards->hash.buckets == NULL)
91 { 96 {
92 *v = ngx_http_variable_null_value; 97 goto valid;
93 return NGX_OK;
94 } 98 }
95 99
96 if (r->headers_in.referer == NULL) { 100 if (r->headers_in.referer == NULL) {
97 if (rlcf->no_referer) { 101 if (rlcf->no_referer) {
98 *v = ngx_http_variable_null_value; 102 goto valid;
99 return NGX_OK; 103 }
100 104
101 } else { 105 goto invalid;
102 *v = ngx_http_variable_true_value;
103 return NGX_OK;
104 }
105 } 106 }
106 107
107 len = r->headers_in.referer->value.len; 108 len = r->headers_in.referer->value.len;
108 ref = r->headers_in.referer->value.data; 109 ref = r->headers_in.referer->value.data;
109 110
110 if (len < sizeof("http://i.ru") - 1 111 if (len < sizeof("http://i.ru") - 1
111 || (ngx_strncasecmp(ref, "http://", 7) != 0)) 112 || (ngx_strncasecmp(ref, "http://", 7) != 0))
112 { 113 {
113 if (rlcf->blocked_referer) { 114 if (rlcf->blocked_referer) {
114 *v = ngx_http_variable_null_value; 115 goto valid;
115 return NGX_OK; 116 }
116 117
117 } else { 118 goto invalid;
118 *v = ngx_http_variable_true_value; 119 }
119 return NGX_OK; 120
120 } 121 last = ref + len;
121 }
122
123 len -= 7;
124 ref += 7; 122 ref += 7;
125 123 i = 0;
126 for (p = ref; p < ref + len; p++) { 124 key = 0;
125
126 for (p = ref; p < last; p++) {
127 if (*p == '/' || *p == ':') { 127 if (*p == '/' || *p == ':') {
128 break; 128 break;
129 } 129 }
130
131 buf[i] = ngx_tolower(*p);
132 key = ngx_hash(key, buf[i++]);
133
134 if (i == 256) {
135 goto invalid;
136 }
130 } 137 }
131 138
132 len = p - ref; 139 len = p - ref;
133 140
134 if (rlcf->hash.buckets) { 141 if (rlcf->hash.buckets) {
135 if (ngx_hash_find(&rlcf->hash, ngx_hash_key_lc(ref, len), ref, len)) { 142 uri = ngx_hash_find(&rlcf->hash, key, buf, len);
136 *v = ngx_http_variable_null_value; 143 if (uri) {
137 return NGX_OK; 144 goto uri;
138 } 145 }
139 } 146 }
140 147
141 if (rlcf->dns_wildcards && rlcf->dns_wildcards->hash.buckets) { 148 if (rlcf->dns_wildcards && rlcf->dns_wildcards->hash.buckets) {
142 if (ngx_hash_find_wildcard(rlcf->dns_wildcards, ref, len)) { 149 uri = ngx_hash_find_wildcard(rlcf->dns_wildcards, buf, len);
143 *v = ngx_http_variable_null_value; 150 if (uri) {
144 return NGX_OK; 151 goto uri;
145 } 152 }
146 } 153 }
154
155 invalid:
147 156
148 *v = ngx_http_variable_true_value; 157 *v = ngx_http_variable_true_value;
158
159 return NGX_OK;
160
161 uri:
162
163 for ( /* void */ ; p < last; p++) {
164 if (*p == '/') {
165 break;
166 }
167 }
168
169 len = last - p;
170
171 if (len == 0) {
172 goto invalid;
173 }
174
175 if (uri == NGX_HTTP_REFERER_NO_URI_PART) {
176 goto valid;
177 }
178
179 if (len < uri->len || ngx_strncmp(uri->data, p, uri->len) != 0) {
180 goto invalid;
181 }
182
183 valid:
184
185 *v = ngx_http_variable_null_value;
149 186
150 return NGX_OK; 187 return NGX_OK;
151 } 188 }
152 189
153 190
239 ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 276 ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
240 { 277 {
241 ngx_http_referer_conf_t *rlcf = conf; 278 ngx_http_referer_conf_t *rlcf = conf;
242 279
243 u_char *p; 280 u_char *p;
244 ngx_str_t *value, name; 281 ngx_str_t *value, uri, name;
245 ngx_uint_t i, n; 282 ngx_uint_t i, n;
246 ngx_http_variable_t *var; 283 ngx_http_variable_t *var;
247 ngx_http_server_name_t *sn; 284 ngx_http_server_name_t *sn;
248 ngx_http_core_srv_conf_t *cscf; 285 ngx_http_core_srv_conf_t *cscf;
249 286
289 if (ngx_strcmp(value[i].data, "blocked") == 0) { 326 if (ngx_strcmp(value[i].data, "blocked") == 0) {
290 rlcf->blocked_referer = 1; 327 rlcf->blocked_referer = 1;
291 continue; 328 continue;
292 } 329 }
293 330
331 uri.len = 0;
332
294 if (ngx_strcmp(value[i].data, "server_names") == 0) { 333 if (ngx_strcmp(value[i].data, "server_names") == 0) {
295 334
296 cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module); 335 cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module);
297 336
298 sn = cscf->server_names.elts; 337 sn = cscf->server_names.elts;
299 for (n = 0; n < cscf->server_names.nelts; n++) { 338 for (n = 0; n < cscf->server_names.nelts; n++) {
300 if (ngx_http_add_referer(cf, rlcf->keys, &sn[n].name) != NGX_OK) { 339 if (ngx_http_add_referer(cf, rlcf->keys, &sn[n].name, &uri)
340 != NGX_OK)
341 {
301 return NGX_CONF_ERROR; 342 return NGX_CONF_ERROR;
302 } 343 }
303 } 344 }
304 345
305 continue; 346 continue;
306 } 347 }
307 348
308 p = (u_char *) ngx_strstr(value[i].data, "/"); 349 p = (u_char *) ngx_strstr(value[i].data, "/");
309 350
310 if (p) { 351 if (p) {
311 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 352 uri.len = (value[i].data + value[i].len) - p;
312 "URI part \"%s\" is deprecated, ignored", p); 353 uri.data = p;
313
314 value[i].len = p - value[i].data; 354 value[i].len = p - value[i].data;
315 } 355 }
316 356
317 if (ngx_http_add_referer(cf, rlcf->keys, &value[i]) != NGX_OK) { 357 if (ngx_http_add_referer(cf, rlcf->keys, &value[i], &uri) != NGX_OK) {
318 return NGX_CONF_ERROR; 358 return NGX_CONF_ERROR;
319 } 359 }
320 } 360 }
321 361
322 return NGX_CONF_OK; 362 return NGX_CONF_OK;
323 } 363 }
324 364
325 365
326 static char * 366 static char *
327 ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys, 367 ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
328 ngx_str_t *value) 368 ngx_str_t *value, ngx_str_t *uri)
329 { 369 {
330 u_char ch; 370 u_char ch;
331 ngx_int_t rc; 371 ngx_int_t rc;
332 ngx_uint_t flags; 372 ngx_str_t *u;
373 ngx_uint_t flags;
333 374
334 ch = value->data[0]; 375 ch = value->data[0];
335 376
336 if ((ch == '*' && (value->len < 3 || value->data[1] != '.')) 377 if ((ch == '*' && (value->len < 3 || value->data[1] != '.'))
337 || (ch == '.' && value->len < 2)) 378 || (ch == '.' && value->len < 2))
342 return NGX_CONF_ERROR; 383 return NGX_CONF_ERROR;
343 } 384 }
344 385
345 flags = (ch == '*' || ch == '.') ? NGX_HASH_WILDCARD_KEY : 0; 386 flags = (ch == '*' || ch == '.') ? NGX_HASH_WILDCARD_KEY : 0;
346 387
347 rc = ngx_hash_add_key(keys, value, (void *) 4, flags); 388 if (uri->len == 0) {
389 u = NGX_HTTP_REFERER_NO_URI_PART;
390
391 } else {
392 u = ngx_palloc(cf->pool, sizeof(ngx_str_t));
393 if (u == NULL) {
394 return NGX_CONF_ERROR;
395 }
396
397 *u = *uri;
398 }
399
400 rc = ngx_hash_add_key(keys, value, u, flags);
348 401
349 if (rc == NGX_OK) { 402 if (rc == NGX_OK) {
350 return NGX_CONF_OK; 403 return NGX_CONF_OK;
351 } 404 }
352 405