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 }