3 * Copyright (C) Igor Sysoev
7 #include <ngx_config.h>
13 ngx_array_t
*codes
; /* uintptr_t */
15 ngx_uint_t stack_size
;
18 ngx_flag_t uninitialized_variable_warn
;
19 } ngx_http_rewrite_loc_conf_t
;
22 static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t
*cf
);
23 static char *ngx_http_rewrite_merge_loc_conf(ngx_conf_t
*cf
,
24 void *parent
, void *child
);
25 static ngx_int_t
ngx_http_rewrite_init(ngx_conf_t
*cf
);
26 static char *ngx_http_rewrite(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
);
27 static char *ngx_http_rewrite_return(ngx_conf_t
*cf
, ngx_command_t
*cmd
,
29 static char *ngx_http_rewrite_break(ngx_conf_t
*cf
, ngx_command_t
*cmd
,
31 static char *ngx_http_rewrite_if(ngx_conf_t
*cf
, ngx_command_t
*cmd
,
33 static char * ngx_http_rewrite_if_condition(ngx_conf_t
*cf
,
34 ngx_http_rewrite_loc_conf_t
*lcf
);
35 static char *ngx_http_rewrite_variable(ngx_conf_t
*cf
,
36 ngx_http_rewrite_loc_conf_t
*lcf
, ngx_str_t
*value
);
37 static char *ngx_http_rewrite_set(ngx_conf_t
*cf
, ngx_command_t
*cmd
,
39 static char * ngx_http_rewrite_value(ngx_conf_t
*cf
,
40 ngx_http_rewrite_loc_conf_t
*lcf
, ngx_str_t
*value
);
43 static ngx_command_t ngx_http_rewrite_commands
[] = {
45 { ngx_string("rewrite"),
46 NGX_HTTP_SRV_CONF
|NGX_HTTP_SIF_CONF
|NGX_HTTP_LOC_CONF
|NGX_HTTP_LIF_CONF
49 NGX_HTTP_LOC_CONF_OFFSET
,
53 { ngx_string("return"),
54 NGX_HTTP_SRV_CONF
|NGX_HTTP_SIF_CONF
|NGX_HTTP_LOC_CONF
|NGX_HTTP_LIF_CONF
56 ngx_http_rewrite_return
,
57 NGX_HTTP_LOC_CONF_OFFSET
,
61 { ngx_string("break"),
62 NGX_HTTP_SRV_CONF
|NGX_HTTP_SIF_CONF
|NGX_HTTP_LOC_CONF
|NGX_HTTP_LIF_CONF
64 ngx_http_rewrite_break
,
65 NGX_HTTP_LOC_CONF_OFFSET
,
70 NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_BLOCK
|NGX_CONF_1MORE
,
72 NGX_HTTP_LOC_CONF_OFFSET
,
77 NGX_HTTP_SRV_CONF
|NGX_HTTP_SIF_CONF
|NGX_HTTP_LOC_CONF
|NGX_HTTP_LIF_CONF
80 NGX_HTTP_LOC_CONF_OFFSET
,
84 { ngx_string("rewrite_log"),
85 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_SIF_CONF
|NGX_HTTP_LOC_CONF
86 |NGX_HTTP_LIF_CONF
|NGX_CONF_FLAG
,
87 ngx_conf_set_flag_slot
,
88 NGX_HTTP_LOC_CONF_OFFSET
,
89 offsetof(ngx_http_rewrite_loc_conf_t
, log
),
92 { ngx_string("uninitialized_variable_warn"),
93 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_SIF_CONF
|NGX_HTTP_LOC_CONF
94 |NGX_HTTP_LIF_CONF
|NGX_CONF_FLAG
,
95 ngx_conf_set_flag_slot
,
96 NGX_HTTP_LOC_CONF_OFFSET
,
97 offsetof(ngx_http_rewrite_loc_conf_t
, uninitialized_variable_warn
),
104 static ngx_http_module_t ngx_http_rewrite_module_ctx
= {
105 NULL
, /* preconfiguration */
106 ngx_http_rewrite_init
, /* postconfiguration */
108 NULL
, /* create main configuration */
109 NULL
, /* init main configuration */
111 NULL
, /* create server configuration */
112 NULL
, /* merge server configuration */
114 ngx_http_rewrite_create_loc_conf
, /* create location configration */
115 ngx_http_rewrite_merge_loc_conf
/* merge location configration */
119 ngx_module_t ngx_http_rewrite_module
= {
121 &ngx_http_rewrite_module_ctx
, /* module context */
122 ngx_http_rewrite_commands
, /* module directives */
123 NGX_HTTP_MODULE
, /* module type */
124 NULL
, /* init master */
125 NULL
, /* init module */
126 NULL
, /* init process */
127 NULL
, /* init thread */
128 NULL
, /* exit thread */
129 NULL
, /* exit process */
130 NULL
, /* exit master */
131 NGX_MODULE_V1_PADDING
136 ngx_http_rewrite_handler(ngx_http_request_t
*r
)
138 ngx_http_script_code_pt code
;
139 ngx_http_script_engine_t
*e
;
140 ngx_http_rewrite_loc_conf_t
*rlcf
;
142 rlcf
= ngx_http_get_module_loc_conf(r
, ngx_http_rewrite_module
);
144 if (rlcf
->codes
== NULL
) {
148 e
= ngx_pcalloc(r
->pool
, sizeof(ngx_http_script_engine_t
));
150 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
153 e
->sp
= ngx_pcalloc(r
->pool
,
154 rlcf
->stack_size
* sizeof(ngx_http_variable_value_t
));
156 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
159 e
->ip
= rlcf
->codes
->elts
;
163 e
->status
= NGX_DECLINED
;
165 while (*(uintptr_t *) e
->ip
) {
166 code
= *(ngx_http_script_code_pt
*) e
->ip
;
170 if (e
->status
== NGX_DECLINED
) {
174 if (r
->err_status
== 0) {
178 return r
->err_status
;
183 ngx_http_rewrite_var(ngx_http_request_t
*r
, ngx_http_variable_value_t
*v
,
186 ngx_http_variable_t
*var
;
187 ngx_http_core_main_conf_t
*cmcf
;
188 ngx_http_rewrite_loc_conf_t
*rlcf
;
190 rlcf
= ngx_http_get_module_loc_conf(r
, ngx_http_rewrite_module
);
192 if (rlcf
->uninitialized_variable_warn
== 0) {
193 *v
= ngx_http_variable_null_value
;
197 cmcf
= ngx_http_get_module_main_conf(r
, ngx_http_core_module
);
199 var
= cmcf
->variables
.elts
;
202 * the ngx_http_rewrite_module sets variables directly in r->variables,
203 * and they should be handled by ngx_http_get_indexed_variable(),
204 * so the handler is called only if the variable is not initialized
207 ngx_log_error(NGX_LOG_WARN
, r
->connection
->log
, 0,
208 "using uninitialized \"%V\" variable", &var
[data
].name
);
210 *v
= ngx_http_variable_null_value
;
217 ngx_http_rewrite_create_loc_conf(ngx_conf_t
*cf
)
219 ngx_http_rewrite_loc_conf_t
*conf
;
221 conf
= ngx_pcalloc(cf
->pool
, sizeof(ngx_http_rewrite_loc_conf_t
));
226 conf
->stack_size
= NGX_CONF_UNSET_UINT
;
227 conf
->log
= NGX_CONF_UNSET
;
228 conf
->uninitialized_variable_warn
= NGX_CONF_UNSET
;
235 ngx_http_rewrite_merge_loc_conf(ngx_conf_t
*cf
, void *parent
, void *child
)
237 ngx_http_rewrite_loc_conf_t
*prev
= parent
;
238 ngx_http_rewrite_loc_conf_t
*conf
= child
;
242 ngx_conf_merge_value(conf
->log
, prev
->log
, 0);
243 ngx_conf_merge_value(conf
->uninitialized_variable_warn
,
244 prev
->uninitialized_variable_warn
, 1);
245 ngx_conf_merge_uint_value(conf
->stack_size
, prev
->stack_size
, 10);
247 if (conf
->codes
== NULL
) {
251 if (conf
->codes
== prev
->codes
) {
255 code
= ngx_array_push_n(conf
->codes
, sizeof(uintptr_t));
257 return NGX_CONF_ERROR
;
260 *code
= (uintptr_t) NULL
;
267 ngx_http_rewrite_init(ngx_conf_t
*cf
)
269 ngx_http_handler_pt
*h
;
270 ngx_http_core_main_conf_t
*cmcf
;
272 cmcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_core_module
);
274 h
= ngx_array_push(&cmcf
->phases
[NGX_HTTP_SERVER_REWRITE_PHASE
].handlers
);
279 *h
= ngx_http_rewrite_handler
;
281 h
= ngx_array_push(&cmcf
->phases
[NGX_HTTP_REWRITE_PHASE
].handlers
);
286 *h
= ngx_http_rewrite_handler
;
293 ngx_http_rewrite(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
295 ngx_http_rewrite_loc_conf_t
*lcf
= conf
;
299 ngx_regex_compile_t rc
;
300 ngx_http_script_code_pt
*code
;
301 ngx_http_script_compile_t sc
;
302 ngx_http_script_regex_code_t
*regex
;
303 ngx_http_script_regex_end_code_t
*regex_end
;
304 u_char errstr
[NGX_MAX_CONF_ERRSTR
];
306 regex
= ngx_http_script_start_code(cf
->pool
, &lcf
->codes
,
307 sizeof(ngx_http_script_regex_code_t
));
309 return NGX_CONF_ERROR
;
312 ngx_memzero(regex
, sizeof(ngx_http_script_regex_code_t
));
314 value
= cf
->args
->elts
;
316 ngx_memzero(&rc
, sizeof(ngx_regex_compile_t
));
318 rc
.pattern
= value
[1];
319 rc
.err
.len
= NGX_MAX_CONF_ERRSTR
;
320 rc
.err
.data
= errstr
;
322 /* TODO: NGX_REGEX_CASELESS */
324 regex
->regex
= ngx_http_regex_compile(cf
, &rc
);
325 if (regex
->regex
== NULL
) {
326 return NGX_CONF_ERROR
;
329 regex
->code
= ngx_http_script_regex_start_code
;
331 regex
->name
= value
[1];
333 if (value
[2].data
[value
[2].len
- 1] == '?') {
335 /* the last "?" drops the original arguments */
344 if (ngx_strncmp(value
[2].data
, "http://", sizeof("http://") - 1) == 0
345 || ngx_strncmp(value
[2].data
, "https://", sizeof("https://") - 1) == 0
346 || ngx_strncmp(value
[2].data
, "$scheme", sizeof("$scheme") - 1) == 0)
348 regex
->status
= NGX_HTTP_MOVED_TEMPORARILY
;
353 if (value
[2].data
[0] == '@') {
354 regex
->named_redirect
= 1;
358 if (cf
->args
->nelts
== 4) {
359 if (ngx_strcmp(value
[3].data
, "last") == 0) {
362 } else if (ngx_strcmp(value
[3].data
, "break") == 0) {
363 regex
->break_cycle
= 1;
366 } else if (ngx_strcmp(value
[3].data
, "redirect") == 0) {
367 regex
->status
= NGX_HTTP_MOVED_TEMPORARILY
;
371 } else if (ngx_strcmp(value
[3].data
, "permanent") == 0) {
372 regex
->status
= NGX_HTTP_MOVED_PERMANENTLY
;
377 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
378 "invalid parameter \"%V\"", &value
[3]);
379 return NGX_CONF_ERROR
;
383 ngx_memzero(&sc
, sizeof(ngx_http_script_compile_t
));
386 sc
.source
= &value
[2];
387 sc
.lengths
= ®ex
->lengths
;
388 sc
.values
= &lcf
->codes
;
389 sc
.variables
= ngx_http_script_variables_count(&value
[2]);
391 sc
.complete_lengths
= 1;
392 sc
.compile_args
= !regex
->redirect
;
394 if (ngx_http_script_compile(&sc
) != NGX_OK
) {
395 return NGX_CONF_ERROR
;
400 regex
->size
= sc
.size
;
401 regex
->args
= sc
.args
;
403 if (sc
.variables
== 0 && !sc
.dup_capture
) {
404 regex
->lengths
= NULL
;
407 regex_end
= ngx_http_script_add_code(lcf
->codes
,
408 sizeof(ngx_http_script_regex_end_code_t
),
410 if (regex_end
== NULL
) {
411 return NGX_CONF_ERROR
;
414 regex_end
->code
= ngx_http_script_regex_end_code
;
415 regex_end
->uri
= regex
->uri
;
416 regex_end
->args
= regex
->args
;
417 regex_end
->add_args
= regex
->add_args
;
418 regex_end
->redirect
= regex
->redirect
;
419 regex_end
->named_redirect
= regex
->named_redirect
;
422 code
= ngx_http_script_add_code(lcf
->codes
, sizeof(uintptr_t), ®ex
);
424 return NGX_CONF_ERROR
;
430 regex
->next
= (u_char
*) lcf
->codes
->elts
+ lcf
->codes
->nelts
438 ngx_http_rewrite_return(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
440 ngx_http_rewrite_loc_conf_t
*lcf
= conf
;
443 ngx_http_script_return_code_t
*ret
;
445 ret
= ngx_http_script_start_code(cf
->pool
, &lcf
->codes
,
446 sizeof(ngx_http_script_return_code_t
));
448 return NGX_CONF_ERROR
;
451 value
= cf
->args
->elts
;
453 ret
->code
= ngx_http_script_return_code
;
454 ret
->null
= (uintptr_t) NULL
;
456 ret
->status
= ngx_atoi(value
[1].data
, value
[1].len
);
458 if (ret
->status
== (uintptr_t) NGX_ERROR
) {
459 return NGX_CONF_ERROR
;
467 ngx_http_rewrite_break(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
469 ngx_http_rewrite_loc_conf_t
*lcf
= conf
;
471 ngx_http_script_code_pt
*code
;
473 code
= ngx_http_script_start_code(cf
->pool
, &lcf
->codes
, sizeof(uintptr_t));
475 return NGX_CONF_ERROR
;
478 *code
= ngx_http_script_break_code
;
485 ngx_http_rewrite_if(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
487 ngx_http_rewrite_loc_conf_t
*lcf
= conf
;
494 ngx_http_module_t
*module
;
495 ngx_http_conf_ctx_t
*ctx
, *pctx
;
496 ngx_http_core_loc_conf_t
*clcf
, *pclcf
;
497 ngx_http_script_if_code_t
*if_code
;
498 ngx_http_rewrite_loc_conf_t
*nlcf
;
500 ctx
= ngx_pcalloc(cf
->pool
, sizeof(ngx_http_conf_ctx_t
));
502 return NGX_CONF_ERROR
;
506 ctx
->main_conf
= pctx
->main_conf
;
507 ctx
->srv_conf
= pctx
->srv_conf
;
509 ctx
->loc_conf
= ngx_pcalloc(cf
->pool
, sizeof(void *) * ngx_http_max_module
);
510 if (ctx
->loc_conf
== NULL
) {
511 return NGX_CONF_ERROR
;
514 for (i
= 0; ngx_modules
[i
]; i
++) {
515 if (ngx_modules
[i
]->type
!= NGX_HTTP_MODULE
) {
519 module
= ngx_modules
[i
]->ctx
;
521 if (module
->create_loc_conf
) {
523 mconf
= module
->create_loc_conf(cf
);
525 return NGX_CONF_ERROR
;
528 ctx
->loc_conf
[ngx_modules
[i
]->ctx_index
] = mconf
;
532 pclcf
= pctx
->loc_conf
[ngx_http_core_module
.ctx_index
];
534 clcf
= ctx
->loc_conf
[ngx_http_core_module
.ctx_index
];
535 clcf
->loc_conf
= ctx
->loc_conf
;
536 clcf
->name
= pclcf
->name
;
539 if (ngx_http_add_location(cf
, &pclcf
->locations
, clcf
) != NGX_OK
) {
540 return NGX_CONF_ERROR
;
543 if (ngx_http_rewrite_if_condition(cf
, lcf
) != NGX_CONF_OK
) {
544 return NGX_CONF_ERROR
;
547 if_code
= ngx_array_push_n(lcf
->codes
, sizeof(ngx_http_script_if_code_t
));
548 if (if_code
== NULL
) {
549 return NGX_CONF_ERROR
;
552 if_code
->code
= ngx_http_script_if_code
;
554 elts
= lcf
->codes
->elts
;
557 /* the inner directives must be compiled to the same code array */
559 nlcf
= ctx
->loc_conf
[ngx_http_rewrite_module
.ctx_index
];
560 nlcf
->codes
= lcf
->codes
;
566 if (pclcf
->name
.len
== 0) {
567 if_code
->loc_conf
= NULL
;
568 cf
->cmd_type
= NGX_HTTP_SIF_CONF
;
571 if_code
->loc_conf
= ctx
->loc_conf
;
572 cf
->cmd_type
= NGX_HTTP_LIF_CONF
;
575 rv
= ngx_conf_parse(cf
, NULL
);
579 if (rv
!= NGX_CONF_OK
) {
584 if (elts
!= lcf
->codes
->elts
) {
585 if_code
= (ngx_http_script_if_code_t
*)
586 ((u_char
*) if_code
+ ((u_char
*) lcf
->codes
->elts
- elts
));
589 if_code
->next
= (u_char
*) lcf
->codes
->elts
+ lcf
->codes
->nelts
590 - (u_char
*) if_code
;
592 /* the code array belong to parent block */
601 ngx_http_rewrite_if_condition(ngx_conf_t
*cf
, ngx_http_rewrite_loc_conf_t
*lcf
)
606 ngx_uint_t cur
, last
;
607 ngx_regex_compile_t rc
;
608 ngx_http_script_code_pt
*code
;
609 ngx_http_script_file_code_t
*fop
;
610 ngx_http_script_regex_code_t
*regex
;
611 u_char errstr
[NGX_MAX_CONF_ERRSTR
];
613 value
= cf
->args
->elts
;
614 last
= cf
->args
->nelts
- 1;
616 if (value
[1].len
< 1 || value
[1].data
[0] != '(') {
617 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
618 "invalid condition \"%V\"", &value
[1]);
619 return NGX_CONF_ERROR
;
622 if (value
[1].len
== 1) {
631 if (value
[last
].len
< 1 || value
[last
].data
[value
[last
].len
- 1] != ')') {
632 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
633 "invalid condition \"%V\"", &value
[last
]);
634 return NGX_CONF_ERROR
;
637 if (value
[last
].len
== 1) {
642 value
[last
].data
[value
[last
].len
] = '\0';
645 len
= value
[cur
].len
;
648 if (len
> 1 && p
[0] == '$') {
650 if (cur
!= last
&& cur
+ 2 != last
) {
651 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
652 "invalid condition \"%V\"", &value
[cur
]);
653 return NGX_CONF_ERROR
;
656 if (ngx_http_rewrite_variable(cf
, lcf
, &value
[cur
]) != NGX_CONF_OK
) {
657 return NGX_CONF_ERROR
;
666 len
= value
[cur
].len
;
669 if (len
== 1 && p
[0] == '=') {
671 if (ngx_http_rewrite_value(cf
, lcf
, &value
[last
]) != NGX_CONF_OK
) {
672 return NGX_CONF_ERROR
;
675 code
= ngx_http_script_start_code(cf
->pool
, &lcf
->codes
,
678 return NGX_CONF_ERROR
;
681 *code
= ngx_http_script_equal_code
;
686 if (len
== 2 && p
[0] == '!' && p
[1] == '=') {
688 if (ngx_http_rewrite_value(cf
, lcf
, &value
[last
]) != NGX_CONF_OK
) {
689 return NGX_CONF_ERROR
;
692 code
= ngx_http_script_start_code(cf
->pool
, &lcf
->codes
,
695 return NGX_CONF_ERROR
;
698 *code
= ngx_http_script_not_equal_code
;
702 if (len
== 1 && p
[0] == '>') {
704 if (ngx_http_rewrite_value(cf
, lcf
, &value
[last
]) != NGX_CONF_OK
) {
705 return NGX_CONF_ERROR
;
708 code
= ngx_http_script_start_code(cf
->pool
, &lcf
->codes
,
711 return NGX_CONF_ERROR
;
714 *code
= ngx_http_script_more_code
;
719 if (len
== 2 && p
[0] == '!' && p
[1] == '>') {
721 if (ngx_http_rewrite_value(cf
, lcf
, &value
[last
]) != NGX_CONF_OK
) {
722 return NGX_CONF_ERROR
;
725 code
= ngx_http_script_start_code(cf
->pool
, &lcf
->codes
,
728 return NGX_CONF_ERROR
;
731 *code
= ngx_http_script_not_more_code
;
735 if (len
== 1 && p
[0] == '<') {
737 if (ngx_http_rewrite_value(cf
, lcf
, &value
[last
]) != NGX_CONF_OK
) {
738 return NGX_CONF_ERROR
;
741 code
= ngx_http_script_start_code(cf
->pool
, &lcf
->codes
,
744 return NGX_CONF_ERROR
;
747 *code
= ngx_http_script_less_code
;
752 if (len
== 2 && p
[0] == '!' && p
[1] == '<') {
754 if (ngx_http_rewrite_value(cf
, lcf
, &value
[last
]) != NGX_CONF_OK
) {
755 return NGX_CONF_ERROR
;
758 code
= ngx_http_script_start_code(cf
->pool
, &lcf
->codes
,
761 return NGX_CONF_ERROR
;
764 *code
= ngx_http_script_not_less_code
;
768 if ((len
== 1 && p
[0] == '~')
769 || (len
== 2 && p
[0] == '~' && p
[1] == '*')
770 || (len
== 2 && p
[0] == '!' && p
[1] == '~')
771 || (len
== 3 && p
[0] == '!' && p
[1] == '~' && p
[2] == '*'))
773 regex
= ngx_http_script_start_code(cf
->pool
, &lcf
->codes
,
774 sizeof(ngx_http_script_regex_code_t
));
776 return NGX_CONF_ERROR
;
779 ngx_memzero(regex
, sizeof(ngx_http_script_regex_code_t
));
781 ngx_memzero(&rc
, sizeof(ngx_regex_compile_t
));
783 rc
.pattern
= value
[last
];
784 rc
.options
= (p
[len
- 1] == '*') ? NGX_REGEX_CASELESS
: 0;
785 rc
.err
.len
= NGX_MAX_CONF_ERRSTR
;
786 rc
.err
.data
= errstr
;
788 regex
->regex
= ngx_http_regex_compile(cf
, &rc
);
789 if (regex
->regex
== NULL
) {
790 return NGX_CONF_ERROR
;
793 regex
->code
= ngx_http_script_regex_start_code
;
794 regex
->next
= sizeof(ngx_http_script_regex_code_t
);
797 regex
->negative_test
= 1;
799 regex
->name
= value
[last
];
804 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
805 "unexpected \"%V\" in condition", &value
[cur
]);
806 return NGX_CONF_ERROR
;
808 } else if ((len
== 2 && p
[0] == '-')
809 || (len
== 3 && p
[0] == '!' && p
[1] == '-'))
811 if (cur
+ 1 != last
) {
812 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
813 "invalid condition \"%V\"", &value
[cur
]);
814 return NGX_CONF_ERROR
;
817 value
[last
].data
[value
[last
].len
] = '\0';
820 if (ngx_http_rewrite_value(cf
, lcf
, &value
[last
]) != NGX_CONF_OK
) {
821 return NGX_CONF_ERROR
;
824 fop
= ngx_http_script_start_code(cf
->pool
, &lcf
->codes
,
825 sizeof(ngx_http_script_file_code_t
));
827 return NGX_CONF_ERROR
;
830 fop
->code
= ngx_http_script_file_code
;
833 fop
->op
= ngx_http_script_file_plain
;
838 fop
->op
= ngx_http_script_file_dir
;
843 fop
->op
= ngx_http_script_file_exists
;
848 fop
->op
= ngx_http_script_file_exec
;
854 fop
->op
= ngx_http_script_file_not_plain
;
859 fop
->op
= ngx_http_script_file_not_dir
;
864 fop
->op
= ngx_http_script_file_not_exists
;
869 fop
->op
= ngx_http_script_file_not_exec
;
874 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
875 "invalid condition \"%V\"", &value
[cur
]);
876 return NGX_CONF_ERROR
;
879 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
880 "invalid condition \"%V\"", &value
[cur
]);
882 return NGX_CONF_ERROR
;
887 ngx_http_rewrite_variable(ngx_conf_t
*cf
, ngx_http_rewrite_loc_conf_t
*lcf
,
891 ngx_http_script_var_code_t
*var_code
;
896 index
= ngx_http_get_variable_index(cf
, value
);
898 if (index
== NGX_ERROR
) {
899 return NGX_CONF_ERROR
;
902 var_code
= ngx_http_script_start_code(cf
->pool
, &lcf
->codes
,
903 sizeof(ngx_http_script_var_code_t
));
904 if (var_code
== NULL
) {
905 return NGX_CONF_ERROR
;
908 var_code
->code
= ngx_http_script_var_code
;
909 var_code
->index
= index
;
916 ngx_http_rewrite_set(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
918 ngx_http_rewrite_loc_conf_t
*lcf
= conf
;
922 ngx_http_variable_t
*v
;
923 ngx_http_script_var_code_t
*vcode
;
924 ngx_http_script_var_handler_code_t
*vhcode
;
926 value
= cf
->args
->elts
;
928 if (value
[1].data
[0] != '$') {
929 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
930 "invalid variable name \"%V\"", &value
[1]);
931 return NGX_CONF_ERROR
;
937 v
= ngx_http_add_variable(cf
, &value
[1], NGX_HTTP_VAR_CHANGEABLE
);
939 return NGX_CONF_ERROR
;
942 index
= ngx_http_get_variable_index(cf
, &value
[1]);
943 if (index
== NGX_ERROR
) {
944 return NGX_CONF_ERROR
;
947 if (v
->get_handler
== NULL
948 && ngx_strncasecmp(value
[1].data
, (u_char
*) "http_", 5) != 0
949 && ngx_strncasecmp(value
[1].data
, (u_char
*) "sent_http_", 10) != 0
950 && ngx_strncasecmp(value
[1].data
, (u_char
*) "upstream_http_", 14) != 0)
952 v
->get_handler
= ngx_http_rewrite_var
;
956 if (ngx_http_rewrite_value(cf
, lcf
, &value
[2]) != NGX_CONF_OK
) {
957 return NGX_CONF_ERROR
;
960 if (v
->set_handler
) {
961 vhcode
= ngx_http_script_start_code(cf
->pool
, &lcf
->codes
,
962 sizeof(ngx_http_script_var_handler_code_t
));
963 if (vhcode
== NULL
) {
964 return NGX_CONF_ERROR
;
967 vhcode
->code
= ngx_http_script_var_set_handler_code
;
968 vhcode
->handler
= v
->set_handler
;
969 vhcode
->data
= v
->data
;
974 vcode
= ngx_http_script_start_code(cf
->pool
, &lcf
->codes
,
975 sizeof(ngx_http_script_var_code_t
));
977 return NGX_CONF_ERROR
;
980 vcode
->code
= ngx_http_script_set_var_code
;
981 vcode
->index
= (uintptr_t) index
;
988 ngx_http_rewrite_value(ngx_conf_t
*cf
, ngx_http_rewrite_loc_conf_t
*lcf
,
992 ngx_http_script_compile_t sc
;
993 ngx_http_script_value_code_t
*val
;
994 ngx_http_script_complex_value_code_t
*complex;
996 n
= ngx_http_script_variables_count(value
);
999 val
= ngx_http_script_start_code(cf
->pool
, &lcf
->codes
,
1000 sizeof(ngx_http_script_value_code_t
));
1002 return NGX_CONF_ERROR
;
1005 n
= ngx_atoi(value
->data
, value
->len
);
1007 if (n
== NGX_ERROR
) {
1011 val
->code
= ngx_http_script_value_code
;
1012 val
->value
= (uintptr_t) n
;
1013 val
->text_len
= (uintptr_t) value
->len
;
1014 val
->text_data
= (uintptr_t) value
->data
;
1019 complex = ngx_http_script_start_code(cf
->pool
, &lcf
->codes
,
1020 sizeof(ngx_http_script_complex_value_code_t
));
1021 if (complex == NULL
) {
1022 return NGX_CONF_ERROR
;
1025 complex->code
= ngx_http_script_complex_value_code
;
1026 complex->lengths
= NULL
;
1028 ngx_memzero(&sc
, sizeof(ngx_http_script_compile_t
));
1032 sc
.lengths
= &complex->lengths
;
1033 sc
.values
= &lcf
->codes
;
1035 sc
.complete_lengths
= 1;
1037 if (ngx_http_script_compile(&sc
) != NGX_OK
) {
1038 return NGX_CONF_ERROR
;