Mercurial > hg > nginx-vendor-0-7
comparison src/http/modules/ngx_http_rewrite_module.c @ 126:df17fbafec8f NGINX_0_3_10
nginx 0.3.10
*) Change: the "valid_referers" directive and the "$invalid_referer"
variable were moved to the new ngx_http_referer_module from the
ngx_http_rewrite_module.
*) Change: the "$apache_bytes_sent" variable name was changed to
"$body_bytes_sent".
*) Feature: the "$sent_http_..." variables.
*) Feature: the "if" directive supports the "=" and "!=" operations.
*) Feature: the "proxy_pass" directive supports the HTTPS protocol.
*) Feature: the "proxy_set_body" directive.
*) Feature: the "post_action" directive.
*) Feature: the ngx_http_empty_gif_module.
*) Feature: the "worker_cpu_affinity" directive for Linux.
*) Bugfix: the "rewrite" directive did not unescape URI part in
redirect, now it is unescaped except the %00-%25 and %7F-%FF
characters.
*) Bugfix: nginx could not be built by the icc 9.0 compiler.
*) Bugfix: if the SSI was enabled for zero size static file, then the
chunked response was encoded incorrectly.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 15 Nov 2005 00:00:00 +0300 |
parents | d25a1d6034f1 |
children | 4cd3e70c4d60 |
comparison
equal
deleted
inserted
replaced
125:97504de1f89e | 126:df17fbafec8f |
---|---|
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_http.h> | 9 #include <ngx_http.h> |
10 | 10 |
11 | 11 |
12 typedef struct { | 12 typedef struct { |
13 ngx_str_t name; | 13 ngx_array_t *codes; /* uintptr_t */ |
14 ngx_uint_t wildcard; | 14 |
15 } ngx_http_rewrite_referer_t; | 15 ngx_uint_t captures; |
16 | 16 ngx_uint_t stack_size; |
17 | 17 |
18 typedef struct { | 18 ngx_flag_t log; |
19 ngx_array_t *codes; /* uintptr_t */ | |
20 ngx_array_t *referers; /* ngx_http_rewrite_referer_t */ | |
21 | |
22 ngx_uint_t captures; | |
23 ngx_uint_t stack_size; | |
24 | |
25 ngx_flag_t log; | |
26 | |
27 ngx_flag_t no_referer; | |
28 ngx_flag_t blocked_referer; | |
29 } ngx_http_rewrite_loc_conf_t; | 19 } ngx_http_rewrite_loc_conf_t; |
30 | 20 |
31 | 21 |
32 static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf); | 22 static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf); |
33 static char *ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf, | 23 static char *ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf, |
42 void *conf); | 32 void *conf); |
43 static char * ngx_http_rewrite_if_condition(ngx_conf_t *cf, | 33 static char * ngx_http_rewrite_if_condition(ngx_conf_t *cf, |
44 ngx_http_rewrite_loc_conf_t *lcf); | 34 ngx_http_rewrite_loc_conf_t *lcf); |
45 static char *ngx_http_rewrite_variable(ngx_conf_t *cf, | 35 static char *ngx_http_rewrite_variable(ngx_conf_t *cf, |
46 ngx_http_rewrite_loc_conf_t *lcf, ngx_str_t *value); | 36 ngx_http_rewrite_loc_conf_t *lcf, ngx_str_t *value); |
47 static char *ngx_http_rewrite_valid_referers(ngx_conf_t *cf, | |
48 ngx_command_t *cmd, void *conf); | |
49 static char *ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, | 37 static char *ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, |
50 void *conf); | 38 void *conf); |
39 static char * ngx_http_rewrite_value(ngx_conf_t *cf, | |
40 ngx_http_rewrite_loc_conf_t *lcf, ngx_str_t *value); | |
51 | 41 |
52 | 42 |
53 static ngx_command_t ngx_http_rewrite_commands[] = { | 43 static ngx_command_t ngx_http_rewrite_commands[] = { |
54 | 44 |
55 { ngx_string("rewrite"), | 45 { ngx_string("rewrite"), |
81 ngx_http_rewrite_if, | 71 ngx_http_rewrite_if, |
82 NGX_HTTP_LOC_CONF_OFFSET, | 72 NGX_HTTP_LOC_CONF_OFFSET, |
83 0, | 73 0, |
84 NULL }, | 74 NULL }, |
85 | 75 |
76 #if 0 | |
86 { ngx_string("valid_referers"), | 77 { ngx_string("valid_referers"), |
87 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | 78 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
88 ngx_http_rewrite_valid_referers, | 79 ngx_http_rewrite_valid_referers, |
89 NGX_HTTP_LOC_CONF_OFFSET, | 80 NGX_HTTP_LOC_CONF_OFFSET, |
90 0, | 81 0, |
91 NULL }, | 82 NULL }, |
83 #endif | |
92 | 84 |
93 { ngx_string("set"), | 85 { ngx_string("set"), |
94 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF | 86 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF |
95 |NGX_CONF_TAKE2, | 87 |NGX_CONF_TAKE2, |
96 ngx_http_rewrite_set, | 88 ngx_http_rewrite_set, |
125 }; | 117 }; |
126 | 118 |
127 | 119 |
128 ngx_module_t ngx_http_rewrite_module = { | 120 ngx_module_t ngx_http_rewrite_module = { |
129 NGX_MODULE_V1, | 121 NGX_MODULE_V1, |
130 &ngx_http_rewrite_module_ctx, /* module context */ | 122 &ngx_http_rewrite_module_ctx, /* module context */ |
131 ngx_http_rewrite_commands, /* module directives */ | 123 ngx_http_rewrite_commands, /* module directives */ |
132 NGX_HTTP_MODULE, /* module type */ | 124 NGX_HTTP_MODULE, /* module type */ |
133 NULL, /* init master */ | 125 NULL, /* init master */ |
134 ngx_http_rewrite_init, /* init module */ | 126 ngx_http_rewrite_init, /* init module */ |
135 NULL, /* init process */ | 127 NULL, /* init process */ |
139 NULL, /* exit master */ | 131 NULL, /* exit master */ |
140 NGX_MODULE_V1_PADDING | 132 NGX_MODULE_V1_PADDING |
141 }; | 133 }; |
142 | 134 |
143 | 135 |
144 static ngx_http_variable_value_t ngx_http_rewrite_null_value = | |
145 ngx_http_variable(""); | |
146 | |
147 | |
148 static ngx_int_t | 136 static ngx_int_t |
149 ngx_http_rewrite_handler(ngx_http_request_t *r) | 137 ngx_http_rewrite_handler(ngx_http_request_t *r) |
150 { | 138 { |
151 ngx_http_script_code_pt code; | 139 ngx_http_script_code_pt code; |
152 ngx_http_script_engine_t *e; | 140 ngx_http_script_engine_t *e; |
192 | 180 |
193 return e->status; | 181 return e->status; |
194 } | 182 } |
195 | 183 |
196 | 184 |
197 static void | |
198 ngx_http_rewrite_invalid_referer_code(ngx_http_script_engine_t *e) | |
199 { | |
200 u_char *ref; | |
201 size_t len; | |
202 ngx_uint_t i, n; | |
203 ngx_http_request_t *r; | |
204 ngx_http_rewrite_referer_t *refs; | |
205 ngx_http_rewrite_loc_conf_t *cf; | |
206 | |
207 r = e->request; | |
208 | |
209 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
210 "http rewrite invalid referer"); | |
211 | |
212 cf = ngx_http_get_module_loc_conf(r, ngx_http_rewrite_module); | |
213 | |
214 e->ip += sizeof(uintptr_t); | |
215 | |
216 if (cf->referers == NULL) { | |
217 e->sp->data = (u_char *) ""; | |
218 e->sp->len = 0; | |
219 e->sp++; | |
220 | |
221 return; | |
222 } | |
223 | |
224 if (r->headers_in.referer == NULL) { | |
225 if (cf->no_referer) { | |
226 e->sp->data = (u_char *) ""; | |
227 e->sp->len = 0; | |
228 e->sp++; | |
229 | |
230 return; | |
231 | |
232 } else { | |
233 e->sp->data = (u_char *) "1"; | |
234 e->sp->len = 1; | |
235 e->sp++; | |
236 | |
237 return; | |
238 } | |
239 } | |
240 | |
241 len = r->headers_in.referer->value.len; | |
242 ref = r->headers_in.referer->value.data; | |
243 | |
244 if (len < sizeof("http://i.ru") - 1 | |
245 || (ngx_strncasecmp(ref, "http://", 7) != 0)) | |
246 { | |
247 if (cf->blocked_referer) { | |
248 e->sp->data = (u_char *) ""; | |
249 e->sp->len = 0; | |
250 e->sp++; | |
251 | |
252 return; | |
253 | |
254 } else { | |
255 e->sp->data = (u_char *) "1"; | |
256 e->sp->len = 1; | |
257 e->sp++; | |
258 | |
259 return; | |
260 } | |
261 } | |
262 | |
263 len -= 7; | |
264 ref += 7; | |
265 | |
266 refs = cf->referers->elts; | |
267 for (i = 0; i < cf->referers->nelts; i++ ){ | |
268 | |
269 if (refs[i].name.len > len) { | |
270 continue; | |
271 } | |
272 | |
273 if (refs[i].wildcard) { | |
274 for (n = 0; n < len; n++) { | |
275 if (ref[n] == '/' || ref[n] == ':') { | |
276 break; | |
277 } | |
278 | |
279 if (ref[n] != '.') { | |
280 continue; | |
281 } | |
282 | |
283 if (ngx_strncmp(&ref[n], refs[i].name.data, | |
284 refs[i].name.len) == 0) | |
285 { | |
286 e->sp->data = (u_char *) ""; | |
287 e->sp->len = 0; | |
288 e->sp++; | |
289 | |
290 return; | |
291 } | |
292 } | |
293 | |
294 } else { | |
295 if (ngx_strncasecmp(refs[i].name.data, ref, refs[i].name.len) == 0) | |
296 { | |
297 e->sp->data = (u_char *) ""; | |
298 e->sp->len = 0; | |
299 e->sp++; | |
300 | |
301 return; | |
302 } | |
303 } | |
304 } | |
305 | |
306 e->sp->data = (u_char *) "1"; | |
307 e->sp->len = 1; | |
308 e->sp++; | |
309 } | |
310 | |
311 | |
312 static ngx_int_t | 185 static ngx_int_t |
313 ngx_http_rewrite_var(ngx_http_request_t *r, ngx_http_variable_value_t *v, | 186 ngx_http_rewrite_var(ngx_http_request_t *r, ngx_http_variable_value_t *v, |
314 uintptr_t data) | 187 uintptr_t data) |
315 { | 188 { |
316 ngx_http_variable_t *var; | 189 ngx_http_variable_t *var; |
327 */ | 200 */ |
328 | 201 |
329 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | 202 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, |
330 "using uninitialized \"%V\" variable", &var[data].name); | 203 "using uninitialized \"%V\" variable", &var[data].name); |
331 | 204 |
332 *v = ngx_http_rewrite_null_value; | 205 *v = ngx_http_variable_null_value; |
333 | 206 |
334 return NGX_OK; | 207 return NGX_OK; |
335 } | 208 } |
336 | 209 |
337 | 210 |
345 return NGX_CONF_ERROR; | 218 return NGX_CONF_ERROR; |
346 } | 219 } |
347 | 220 |
348 conf->stack_size = NGX_CONF_UNSET_UINT; | 221 conf->stack_size = NGX_CONF_UNSET_UINT; |
349 conf->log = NGX_CONF_UNSET; | 222 conf->log = NGX_CONF_UNSET; |
350 conf->no_referer = NGX_CONF_UNSET; | |
351 conf->blocked_referer = NGX_CONF_UNSET; | |
352 | 223 |
353 return conf; | 224 return conf; |
354 } | 225 } |
355 | 226 |
356 | 227 |
363 uintptr_t *code; | 234 uintptr_t *code; |
364 | 235 |
365 ngx_conf_merge_value(conf->log, prev->log, 0); | 236 ngx_conf_merge_value(conf->log, prev->log, 0); |
366 ngx_conf_merge_unsigned_value(conf->stack_size, prev->stack_size, 10); | 237 ngx_conf_merge_unsigned_value(conf->stack_size, prev->stack_size, 10); |
367 | 238 |
368 if (conf->referers == NULL) { | |
369 conf->referers = prev->referers; | |
370 ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0); | |
371 ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0); | |
372 } | |
373 | |
374 if (conf->no_referer == NGX_CONF_UNSET) { | |
375 conf->no_referer = 0; | |
376 } | |
377 | |
378 if (conf->blocked_referer == NGX_CONF_UNSET) { | |
379 conf->blocked_referer = 0; | |
380 } | |
381 | |
382 if (conf->codes == NULL) { | 239 if (conf->codes == NULL) { |
383 return NGX_CONF_OK; | 240 return NGX_CONF_OK; |
384 } | 241 } |
385 | 242 |
386 if (conf->codes == prev->codes) { | 243 if (conf->codes == prev->codes) { |
398 } | 255 } |
399 | 256 |
400 | 257 |
401 static ngx_int_t | 258 static ngx_int_t |
402 ngx_http_rewrite_init(ngx_cycle_t *cycle) | 259 ngx_http_rewrite_init(ngx_cycle_t *cycle) |
403 { | 260 { |
404 ngx_http_handler_pt *h; | 261 ngx_http_handler_pt *h; |
405 ngx_http_core_main_conf_t *cmcf; | 262 ngx_http_core_main_conf_t *cmcf; |
406 | 263 |
407 cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); | 264 cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); |
408 | 265 |
419 } | 276 } |
420 | 277 |
421 *h = ngx_http_rewrite_handler; | 278 *h = ngx_http_rewrite_handler; |
422 | 279 |
423 return NGX_OK; | 280 return NGX_OK; |
424 } | 281 } |
425 | 282 |
426 | 283 |
427 static char * | 284 static char * |
428 ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 285 ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
429 { | 286 { |
430 ngx_http_rewrite_loc_conf_t *lcf = conf; | 287 ngx_http_rewrite_loc_conf_t *lcf = conf; |
431 | 288 |
432 ngx_str_t *value, err; | 289 ngx_str_t *value, err; |
433 ngx_int_t n; | 290 ngx_int_t n; |
434 ngx_uint_t last; | 291 ngx_uint_t last; |
435 ngx_http_script_code_pt *code; | 292 ngx_http_script_code_pt *code; |
436 ngx_http_script_compile_t sc; | 293 ngx_http_script_compile_t sc; |
590 | 447 |
591 | 448 |
592 static char * | 449 static char * |
593 ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 450 ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
594 { | 451 { |
595 ngx_http_rewrite_loc_conf_t *lcf = conf; | 452 ngx_http_rewrite_loc_conf_t *lcf = conf; |
596 | 453 |
597 ngx_str_t *value; | 454 ngx_str_t *value; |
598 ngx_http_script_return_code_t *ret; | 455 ngx_http_script_return_code_t *ret; |
599 | 456 |
600 ret = ngx_http_script_start_code(cf->pool, &lcf->codes, | 457 ret = ngx_http_script_start_code(cf->pool, &lcf->codes, |
637 | 494 |
638 | 495 |
639 static char * | 496 static char * |
640 ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 497 ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
641 { | 498 { |
642 ngx_http_rewrite_loc_conf_t *lcf = conf; | 499 ngx_http_rewrite_loc_conf_t *lcf = conf; |
643 | 500 |
644 void *mconf; | 501 void *mconf; |
645 char *rv; | 502 char *rv; |
646 u_char *elts; | 503 u_char *elts; |
647 ngx_uint_t i; | 504 ngx_uint_t i; |
657 return NGX_CONF_ERROR; | 514 return NGX_CONF_ERROR; |
658 } | 515 } |
659 | 516 |
660 pctx = cf->ctx; | 517 pctx = cf->ctx; |
661 ctx->main_conf = pctx->main_conf; | 518 ctx->main_conf = pctx->main_conf; |
662 ctx->srv_conf = pctx->srv_conf; | 519 ctx->srv_conf = pctx->srv_conf; |
663 | 520 |
664 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); | 521 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); |
665 if (ctx->loc_conf == NULL) { | 522 if (ctx->loc_conf == NULL) { |
666 return NGX_CONF_ERROR; | 523 return NGX_CONF_ERROR; |
667 } | 524 } |
670 if (ngx_modules[i]->type != NGX_HTTP_MODULE) { | 527 if (ngx_modules[i]->type != NGX_HTTP_MODULE) { |
671 continue; | 528 continue; |
672 } | 529 } |
673 | 530 |
674 module = ngx_modules[i]->ctx; | 531 module = ngx_modules[i]->ctx; |
675 | 532 |
676 if (module->create_loc_conf) { | 533 if (module->create_loc_conf) { |
677 | 534 |
678 mconf = module->create_loc_conf(cf); | 535 mconf = module->create_loc_conf(cf); |
679 if (mconf == NULL) { | 536 if (mconf == NULL) { |
680 return NGX_CONF_ERROR; | 537 return NGX_CONF_ERROR; |
772 static char * | 629 static char * |
773 ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf) | 630 ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf) |
774 { | 631 { |
775 ngx_str_t *value, err; | 632 ngx_str_t *value, err; |
776 ngx_uint_t cur, last, n; | 633 ngx_uint_t cur, last, n; |
634 ngx_http_script_code_pt *code; | |
777 ngx_http_script_regex_code_t *regex; | 635 ngx_http_script_regex_code_t *regex; |
778 u_char errstr[NGX_MAX_CONF_ERRSTR]; | 636 u_char errstr[NGX_MAX_CONF_ERRSTR]; |
779 | 637 |
780 value = cf->args->elts; | 638 value = cf->args->elts; |
781 last = cf->args->nelts - 1; | 639 last = cf->args->nelts - 1; |
815 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 673 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
816 "invalid condition \"%V\"", &value[cur]); | 674 "invalid condition \"%V\"", &value[cur]); |
817 return NGX_CONF_ERROR; | 675 return NGX_CONF_ERROR; |
818 } | 676 } |
819 | 677 |
820 if (ngx_http_rewrite_variable(cf, lcf, &value[cur])!= NGX_CONF_OK) { | 678 if (ngx_http_rewrite_variable(cf, lcf, &value[cur]) != NGX_CONF_OK) { |
821 return NGX_CONF_ERROR; | 679 return NGX_CONF_ERROR; |
822 } | 680 } |
823 | 681 |
824 if (cur == last) { | 682 if (cur == last) { |
825 return NGX_CONF_OK; | 683 return NGX_CONF_OK; |
826 } | 684 } |
827 | 685 |
828 cur++; | 686 cur++; |
829 | 687 |
830 if ((value[cur].len == 1 && value[cur].data[0] != '~') | 688 if (value[cur].len == 1 && value[cur].data[0] == '=') { |
689 | |
690 if (ngx_http_rewrite_value(cf, lcf, &value[last]) != NGX_CONF_OK) { | |
691 return NGX_CONF_ERROR; | |
692 } | |
693 | |
694 code = ngx_http_script_start_code(cf->pool, &lcf->codes, | |
695 sizeof(uintptr_t)); | |
696 if (code == NULL) { | |
697 return NGX_CONF_ERROR; | |
698 } | |
699 | |
700 *code = ngx_http_script_equal_code; | |
701 | |
702 return NGX_CONF_OK; | |
703 } | |
704 | |
705 if (value[cur].len == 2 | |
706 && value[cur].data[0] == '!' && value[cur].data[1] == '=') | |
707 { | |
708 if (ngx_http_rewrite_value(cf, lcf, &value[last]) != NGX_CONF_OK) { | |
709 return NGX_CONF_ERROR; | |
710 } | |
711 | |
712 code = ngx_http_script_start_code(cf->pool, &lcf->codes, | |
713 sizeof(uintptr_t)); | |
714 if (code == NULL) { | |
715 return NGX_CONF_ERROR; | |
716 } | |
717 | |
718 *code = ngx_http_script_not_equal_code; | |
719 return NGX_CONF_OK; | |
720 } | |
721 | |
722 if ((value[cur].len == 1 && value[cur].data[0] == '~') | |
831 || (value[cur].len == 2 | 723 || (value[cur].len == 2 |
832 && value[cur].data[0] != '~' && value[cur].data[1] != '*')) | 724 && value[cur].data[0] == '~' && value[cur].data[1] == '*')) |
833 { | 725 { |
834 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 726 regex = ngx_http_script_start_code(cf->pool, &lcf->codes, |
835 "unexpected \"%V\" in condition", &value[cur]); | |
836 return NGX_CONF_ERROR; | |
837 } | |
838 | |
839 regex = ngx_http_script_start_code(cf->pool, &lcf->codes, | |
840 sizeof(ngx_http_script_regex_code_t)); | 727 sizeof(ngx_http_script_regex_code_t)); |
841 if (regex == NULL) { | 728 if (regex == NULL) { |
842 return NGX_CONF_ERROR; | 729 return NGX_CONF_ERROR; |
843 } | |
844 | |
845 ngx_memzero(regex, sizeof(ngx_http_script_regex_code_t)); | |
846 | |
847 err.len = NGX_MAX_CONF_ERRSTR; | |
848 err.data = errstr; | |
849 | |
850 regex->regex = ngx_regex_compile(&value[last], | |
851 (value[cur].len == 2) ? NGX_REGEX_CASELESS : 0, | |
852 cf->pool, &err); | |
853 | |
854 if (regex->regex == NULL) { | |
855 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); | |
856 return NGX_CONF_ERROR; | |
857 } | |
858 | |
859 regex->code = ngx_http_script_regex_start_code; | |
860 regex->next = sizeof(ngx_http_script_regex_code_t); | |
861 regex->test = 1; | |
862 regex->name = value[last]; | |
863 | |
864 n = ngx_regex_capture_count(regex->regex); | |
865 | |
866 if (n) { | |
867 regex->ncaptures = (n + 1) * 3; | |
868 | |
869 if (lcf->captures < regex->ncaptures) { | |
870 lcf->captures = regex->ncaptures; | |
871 } | 730 } |
872 } | 731 |
873 | 732 ngx_memzero(regex, sizeof(ngx_http_script_regex_code_t)); |
874 return NGX_CONF_OK; | 733 |
734 err.len = NGX_MAX_CONF_ERRSTR; | |
735 err.data = errstr; | |
736 | |
737 regex->regex = ngx_regex_compile(&value[last], | |
738 (value[cur].len == 2) ? NGX_REGEX_CASELESS : 0, | |
739 cf->pool, &err); | |
740 | |
741 if (regex->regex == NULL) { | |
742 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); | |
743 return NGX_CONF_ERROR; | |
744 } | |
745 | |
746 regex->code = ngx_http_script_regex_start_code; | |
747 regex->next = sizeof(ngx_http_script_regex_code_t); | |
748 regex->test = 1; | |
749 regex->name = value[last]; | |
750 | |
751 n = ngx_regex_capture_count(regex->regex); | |
752 | |
753 if (n) { | |
754 regex->ncaptures = (n + 1) * 3; | |
755 | |
756 if (lcf->captures < regex->ncaptures) { | |
757 lcf->captures = regex->ncaptures; | |
758 } | |
759 } | |
760 | |
761 return NGX_CONF_OK; | |
762 } | |
763 | |
764 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
765 "unexpected \"%V\" in condition", &value[cur]); | |
766 return NGX_CONF_ERROR; | |
875 } | 767 } |
876 | 768 |
877 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 769 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
878 "invalid condition \"%V\"", &value[cur]); | 770 "invalid condition \"%V\"", &value[cur]); |
879 | 771 |
884 static char * | 776 static char * |
885 ngx_http_rewrite_variable(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf, | 777 ngx_http_rewrite_variable(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf, |
886 ngx_str_t *value) | 778 ngx_str_t *value) |
887 { | 779 { |
888 ngx_int_t index; | 780 ngx_int_t index; |
889 ngx_http_script_code_pt *code; | |
890 ngx_http_script_var_code_t *var_code; | 781 ngx_http_script_var_code_t *var_code; |
891 | 782 |
892 value->len--; | 783 value->len--; |
893 value->data++; | 784 value->data++; |
894 | 785 |
895 if (value->len == sizeof("invalid_referer") - 1 | 786 index = ngx_http_get_variable_index(cf, value); |
896 && ngx_strncmp(value->data, "invalid_referer", | 787 |
897 sizeof("invalid_referer") - 1) == 0) | 788 if (index == NGX_ERROR) { |
898 { | 789 return NGX_CONF_ERROR; |
899 code = ngx_http_script_start_code(cf->pool, &lcf->codes, | 790 } |
900 sizeof(ngx_http_script_code_pt)); | 791 |
901 if (code == NULL) { | 792 var_code = ngx_http_script_start_code(cf->pool, &lcf->codes, |
902 return NGX_CONF_ERROR; | 793 sizeof(ngx_http_script_var_code_t)); |
903 } | 794 if (var_code == NULL) { |
904 | 795 return NGX_CONF_ERROR; |
905 *code = ngx_http_rewrite_invalid_referer_code; | 796 } |
906 | 797 |
907 } else { | 798 var_code->code = ngx_http_script_var_code; |
908 index = ngx_http_get_variable_index(cf, value); | 799 var_code->index = index; |
909 | |
910 if (index == NGX_ERROR) { | |
911 return NGX_CONF_ERROR; | |
912 } | |
913 | |
914 var_code = ngx_http_script_start_code(cf->pool, &lcf->codes, | |
915 sizeof(ngx_http_script_var_code_t)); | |
916 if (var_code == NULL) { | |
917 return NGX_CONF_ERROR; | |
918 } | |
919 | |
920 var_code->code = ngx_http_script_var_code; | |
921 var_code->index = index; | |
922 } | |
923 | |
924 return NGX_CONF_OK; | |
925 } | |
926 | |
927 | |
928 static char * | |
929 ngx_http_rewrite_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
930 { | |
931 ngx_http_rewrite_loc_conf_t *lcf = conf; | |
932 | |
933 ngx_uint_t i, server_names; | |
934 ngx_str_t *value; | |
935 ngx_http_server_name_t *sn; | |
936 ngx_http_core_srv_conf_t *cscf; | |
937 ngx_http_rewrite_referer_t *ref; | |
938 | |
939 cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module); | |
940 | |
941 if (lcf->referers == NULL) { | |
942 lcf->referers = ngx_array_create(cf->pool, | |
943 cf->args->nelts + cscf->server_names.nelts, | |
944 sizeof(ngx_http_rewrite_referer_t)); | |
945 if (lcf->referers == NULL) { | |
946 return NGX_CONF_ERROR; | |
947 } | |
948 } | |
949 | |
950 value = cf->args->elts; | |
951 server_names = 0; | |
952 | |
953 for (i = 1; i < cf->args->nelts; i++) { | |
954 if (value[i].len == 0) { | |
955 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
956 "invalid referer \"%V\"", &value[i]); | |
957 return NGX_CONF_ERROR; | |
958 } | |
959 | |
960 if (ngx_strcmp(value[i].data, "none") == 0) { | |
961 lcf->no_referer = 1; | |
962 continue; | |
963 } | |
964 | |
965 if (ngx_strcmp(value[i].data, "blocked") == 0) { | |
966 lcf->blocked_referer = 1; | |
967 continue; | |
968 } | |
969 | |
970 if (ngx_strcmp(value[i].data, "server_names") == 0) { | |
971 server_names = 1; | |
972 continue; | |
973 } | |
974 | |
975 ref = ngx_array_push(lcf->referers); | |
976 if (ref == NULL) { | |
977 return NGX_CONF_ERROR; | |
978 } | |
979 | |
980 if (value[i].data[0] != '*') { | |
981 ref->name = value[i]; | |
982 ref->wildcard = 0; | |
983 continue; | |
984 } | |
985 | |
986 if (value[i].data[1] != '.') { | |
987 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
988 "invalid wildcard referer \"%V\"", &value[i]); | |
989 return NGX_CONF_ERROR; | |
990 } | |
991 | |
992 ref->name.len = value[i].len - 1; | |
993 ref->name.data = value[i].data + 1; | |
994 ref->wildcard = 1; | |
995 } | |
996 | |
997 if (!server_names) { | |
998 return NGX_CONF_OK; | |
999 } | |
1000 | |
1001 sn = cscf->server_names.elts; | |
1002 for (i = 0; i < cscf->server_names.nelts; i++) { | |
1003 ref = ngx_array_push(lcf->referers); | |
1004 if (ref == NULL) { | |
1005 return NGX_CONF_ERROR; | |
1006 } | |
1007 | |
1008 ref->name.len = sn[i].name.len + 1; | |
1009 ref->name.data = ngx_palloc(cf->pool, ref->name.len); | |
1010 if (ref->name.data == NULL) { | |
1011 return NGX_CONF_ERROR; | |
1012 } | |
1013 | |
1014 ngx_memcpy(ref->name.data, sn[i].name.data, sn[i].name.len); | |
1015 ref->name.data[sn[i].name.len] = '/'; | |
1016 ref->wildcard = sn[i].wildcard; | |
1017 } | |
1018 | 800 |
1019 return NGX_CONF_OK; | 801 return NGX_CONF_OK; |
1020 } | 802 } |
1021 | 803 |
1022 | 804 |
1023 static char * | 805 static char * |
1024 ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 806 ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
1025 { | 807 { |
1026 ngx_http_rewrite_loc_conf_t *lcf = conf; | 808 ngx_http_rewrite_loc_conf_t *lcf = conf; |
1027 | 809 |
1028 ngx_int_t n, index; | 810 ngx_int_t index; |
1029 ngx_str_t *value; | 811 ngx_str_t *value; |
1030 ngx_http_variable_t *v; | 812 ngx_http_variable_t *v; |
1031 ngx_http_script_compile_t sc; | 813 ngx_http_script_var_code_t *var; |
1032 ngx_http_script_var_code_t *var; | |
1033 ngx_http_script_value_code_t *val; | |
1034 ngx_http_script_complex_value_code_t *complex; | |
1035 | 814 |
1036 value = cf->args->elts; | 815 value = cf->args->elts; |
1037 | 816 |
1038 if (value[1].data[0] != '$') { | 817 if (value[1].data[0] != '$') { |
1039 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 818 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
1057 if (v->handler == NULL) { | 836 if (v->handler == NULL) { |
1058 v->handler = ngx_http_rewrite_var; | 837 v->handler = ngx_http_rewrite_var; |
1059 v->data = index; | 838 v->data = index; |
1060 } | 839 } |
1061 | 840 |
1062 n = ngx_http_script_variables_count(&value[2]); | 841 if (ngx_http_rewrite_value(cf, lcf, &value[2]) != NGX_CONF_OK) { |
842 return NGX_CONF_ERROR; | |
843 } | |
844 | |
845 var = ngx_http_script_start_code(cf->pool, &lcf->codes, | |
846 sizeof(ngx_http_script_var_code_t)); | |
847 if (var == NULL) { | |
848 return NGX_CONF_ERROR; | |
849 } | |
850 | |
851 var->code = ngx_http_script_set_var_code; | |
852 var->index = (uintptr_t) index; | |
853 | |
854 return NGX_CONF_OK; | |
855 } | |
856 | |
857 | |
858 static char * | |
859 ngx_http_rewrite_value(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf, | |
860 ngx_str_t *value) | |
861 { | |
862 ngx_int_t n; | |
863 ngx_http_script_compile_t sc; | |
864 ngx_http_script_value_code_t *val; | |
865 ngx_http_script_complex_value_code_t *complex; | |
866 | |
867 n = ngx_http_script_variables_count(value); | |
1063 | 868 |
1064 if (n == 0) { | 869 if (n == 0) { |
1065 val = ngx_http_script_start_code(cf->pool, &lcf->codes, | 870 val = ngx_http_script_start_code(cf->pool, &lcf->codes, |
1066 sizeof(ngx_http_script_value_code_t)); | 871 sizeof(ngx_http_script_value_code_t)); |
1067 if (val == NULL) { | 872 if (val == NULL) { |
1068 return NGX_CONF_ERROR; | 873 return NGX_CONF_ERROR; |
1069 } | 874 } |
1070 | 875 |
1071 n = ngx_atoi(value[2].data, value[2].len); | 876 n = ngx_atoi(value->data, value->len); |
1072 | 877 |
1073 if (n == NGX_ERROR) { | 878 if (n == NGX_ERROR) { |
1074 n = 0; | 879 n = 0; |
1075 } | 880 } |
1076 | 881 |
1077 val->code = ngx_http_script_value_code; | 882 val->code = ngx_http_script_value_code; |
1078 val->value = (uintptr_t) n; | 883 val->value = (uintptr_t) n; |
1079 val->text_len = (uintptr_t) value[2].len; | 884 val->text_len = (uintptr_t) value->len; |
1080 val->text_data = (uintptr_t) value[2].data; | 885 val->text_data = (uintptr_t) value->data; |
1081 | 886 |
1082 } else { | 887 return NGX_CONF_OK; |
1083 complex = ngx_http_script_start_code(cf->pool, &lcf->codes, | 888 } |
889 | |
890 complex = ngx_http_script_start_code(cf->pool, &lcf->codes, | |
1084 sizeof(ngx_http_script_complex_value_code_t)); | 891 sizeof(ngx_http_script_complex_value_code_t)); |
1085 if (complex == NULL) { | 892 if (complex == NULL) { |
1086 return NGX_CONF_ERROR; | 893 return NGX_CONF_ERROR; |
1087 } | 894 } |
1088 | 895 |
1089 complex->code = ngx_http_script_complex_value_code; | 896 complex->code = ngx_http_script_complex_value_code; |
1090 complex->lengths = NULL; | 897 complex->lengths = NULL; |
1091 | 898 |
1092 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); | 899 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); |
1093 | 900 |
1094 sc.cf = cf; | 901 sc.cf = cf; |
1095 sc.source = &value[2]; | 902 sc.source = value; |
1096 sc.lengths = &complex->lengths; | 903 sc.lengths = &complex->lengths; |
1097 sc.values = &lcf->codes; | 904 sc.values = &lcf->codes; |
1098 sc.variables = n; | 905 sc.variables = n; |
1099 sc.complete_lengths = 1; | 906 sc.complete_lengths = 1; |
1100 | 907 |
1101 if (ngx_http_script_compile(&sc) != NGX_OK) { | 908 if (ngx_http_script_compile(&sc) != NGX_OK) { |
1102 return NGX_CONF_ERROR; | 909 return NGX_CONF_ERROR; |
1103 } | 910 } |
1104 } | |
1105 | |
1106 var = ngx_http_script_start_code(cf->pool, &lcf->codes, | |
1107 sizeof(ngx_http_script_var_code_t)); | |
1108 if (var == NULL) { | |
1109 return NGX_CONF_ERROR; | |
1110 } | |
1111 | |
1112 var->code = ngx_http_script_set_var_code; | |
1113 var->index = (uintptr_t) index; | |
1114 | 911 |
1115 return NGX_CONF_OK; | 912 return NGX_CONF_OK; |
1116 } | 913 } |