Mercurial > hg > nginx-vendor-0-8
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 |