Mercurial > hg > nginx
comparison src/http/modules/ngx_http_sub_filter_module.c @ 2588:a6954ce88b80
use complex values in add_header, auth_basic_user_file,
sub_filter, and xslt_stylesheet parameters
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 22 Mar 2009 09:39:19 +0000 |
parents | a6d6d762c554 |
children | c7d57b539248 |
comparison
equal
deleted
inserted
replaced
2587:8afc4df77ee8 | 2588:a6954ce88b80 |
---|---|
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 match; | 13 ngx_str_t match; |
14 ngx_str_t sub; | 14 ngx_http_complex_value_t value; |
15 | 15 |
16 ngx_hash_t types; | 16 ngx_hash_t types; |
17 | 17 |
18 ngx_array_t *sub_lengths; | 18 ngx_flag_t once; |
19 ngx_array_t *sub_values; | 19 |
20 | 20 ngx_array_t *types_keys; |
21 ngx_flag_t once; | |
22 | |
23 ngx_array_t *types_keys; | |
24 } ngx_http_sub_loc_conf_t; | 21 } ngx_http_sub_loc_conf_t; |
25 | 22 |
26 | 23 |
27 typedef enum { | 24 typedef enum { |
28 sub_start_state = 0, | 25 sub_start_state = 0, |
29 sub_match_state, | 26 sub_match_state, |
30 } ngx_http_sub_state_e; | 27 } ngx_http_sub_state_e; |
31 | 28 |
32 | 29 |
33 typedef struct { | 30 typedef struct { |
34 ngx_str_t match; | 31 ngx_str_t match; |
35 | 32 |
36 ngx_uint_t once; /* unsigned once:1 */ | 33 ngx_uint_t once; /* unsigned once:1 */ |
37 | 34 |
38 ngx_buf_t *buf; | 35 ngx_buf_t *buf; |
39 | 36 |
40 u_char *pos; | 37 u_char *pos; |
41 u_char *copy_start; | 38 u_char *copy_start; |
42 u_char *copy_end; | 39 u_char *copy_end; |
43 | 40 |
44 ngx_chain_t *in; | 41 ngx_chain_t *in; |
45 ngx_chain_t *out; | 42 ngx_chain_t *out; |
46 ngx_chain_t **last_out; | 43 ngx_chain_t **last_out; |
47 ngx_chain_t *busy; | 44 ngx_chain_t *busy; |
48 ngx_chain_t *free; | 45 ngx_chain_t *free; |
49 | 46 |
50 ngx_str_t sub; | 47 ngx_str_t sub; |
51 | 48 |
52 ngx_uint_t state; | 49 ngx_uint_t state; |
53 size_t saved; | 50 size_t saved; |
54 size_t looked; | 51 size_t looked; |
55 } ngx_http_sub_ctx_t; | 52 } ngx_http_sub_ctx_t; |
56 | 53 |
57 | 54 |
58 static ngx_int_t ngx_http_sub_output(ngx_http_request_t *r, | 55 static ngx_int_t ngx_http_sub_output(ngx_http_request_t *r, |
59 ngx_http_sub_ctx_t *ctx); | 56 ngx_http_sub_ctx_t *ctx); |
152 | 149 |
153 ngx_http_set_ctx(r, ctx, ngx_http_sub_filter_module); | 150 ngx_http_set_ctx(r, ctx, ngx_http_sub_filter_module); |
154 | 151 |
155 ctx->match = slcf->match; | 152 ctx->match = slcf->match; |
156 ctx->last_out = &ctx->out; | 153 ctx->last_out = &ctx->out; |
157 ctx->sub = slcf->sub; | |
158 | 154 |
159 r->filter_need_in_memory = 1; | 155 r->filter_need_in_memory = 1; |
160 | 156 |
161 if (r == r->main) { | 157 if (r == r->main) { |
162 ngx_http_clear_content_length(r); | 158 ngx_http_clear_content_length(r); |
344 | 340 |
345 slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module); | 341 slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module); |
346 | 342 |
347 if (ctx->sub.data == NULL) { | 343 if (ctx->sub.data == NULL) { |
348 | 344 |
349 if (ngx_http_script_run(r, &ctx->sub, slcf->sub_lengths->elts, | 345 if (ngx_http_complex_value(r, &slcf->value, &ctx->sub) |
350 0, slcf->sub_values->elts) | 346 != NGX_OK) |
351 == NULL) | |
352 { | 347 { |
353 return NGX_ERROR; | 348 return NGX_ERROR; |
354 } | 349 } |
355 } | 350 } |
356 | 351 |
607 static char * | 602 static char * |
608 ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 603 ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
609 { | 604 { |
610 ngx_http_sub_loc_conf_t *slcf = conf; | 605 ngx_http_sub_loc_conf_t *slcf = conf; |
611 | 606 |
612 ngx_str_t *value; | 607 ngx_str_t *value; |
613 ngx_int_t n; | 608 ngx_http_compile_complex_value_t ccv; |
614 ngx_http_script_compile_t sc; | |
615 | 609 |
616 if (slcf->match.len) { | 610 if (slcf->match.len) { |
617 return "is duplicate"; | 611 return "is duplicate"; |
618 } | 612 } |
619 | 613 |
621 | 615 |
622 ngx_strlow(value[1].data, value[1].data, value[1].len); | 616 ngx_strlow(value[1].data, value[1].data, value[1].len); |
623 | 617 |
624 slcf->match = value[1]; | 618 slcf->match = value[1]; |
625 | 619 |
626 n = ngx_http_script_variables_count(&value[2]); | 620 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
627 | 621 |
628 if (n == 0) { | 622 ccv.cf = cf; |
629 slcf->sub = value[2]; | 623 ccv.value = &value[2]; |
630 return NGX_CONF_OK; | 624 ccv.complex_value = &slcf->value; |
631 } | 625 |
632 | 626 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
633 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); | |
634 | |
635 sc.cf = cf; | |
636 sc.source = &value[2]; | |
637 sc.lengths = &slcf->sub_lengths; | |
638 sc.values = &slcf->sub_values; | |
639 sc.variables = n; | |
640 sc.complete_lengths = 1; | |
641 sc.complete_values = 1; | |
642 | |
643 if (ngx_http_script_compile(&sc) != NGX_OK) { | |
644 return NGX_CONF_ERROR; | 627 return NGX_CONF_ERROR; |
645 } | 628 } |
646 | 629 |
647 return NGX_CONF_OK; | 630 return NGX_CONF_OK; |
648 } | 631 } |
682 ngx_http_sub_loc_conf_t *conf = child; | 665 ngx_http_sub_loc_conf_t *conf = child; |
683 | 666 |
684 ngx_conf_merge_value(conf->once, prev->once, 1); | 667 ngx_conf_merge_value(conf->once, prev->once, 1); |
685 ngx_conf_merge_str_value(conf->match, prev->match, ""); | 668 ngx_conf_merge_str_value(conf->match, prev->match, ""); |
686 | 669 |
687 if (conf->sub.data == NULL && conf->sub_lengths == NULL) { | 670 if (conf->value.value.len == 0) { |
688 conf->sub = prev->sub; | 671 conf->value = prev->value; |
689 conf->sub_lengths = prev->sub_lengths; | |
690 conf->sub_values = prev->sub_values; | |
691 } | 672 } |
692 | 673 |
693 if (ngx_http_merge_types(cf, conf->types_keys, &conf->types, | 674 if (ngx_http_merge_types(cf, conf->types_keys, &conf->types, |
694 prev->types_keys, &prev->types, | 675 prev->types_keys, &prev->types, |
695 ngx_http_html_default_types) | 676 ngx_http_html_default_types) |