~ubuntu-branches/debian/squeeze/nginx/squeeze

« back to all changes in this revision

Viewing changes to src/http/modules/ngx_http_sub_filter_module.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabio Tranchitella
  • Date: 2009-05-31 18:38:56 UTC
  • mfrom: (1.1.10 upstream) (4.1.12 experimental)
  • Revision ID: james.westby@ubuntu.com-20090531183856-3xhvf6wd0bw5556i
Tags: 0.7.59-1
* New upstream release, first in Debian for the 0.7 branch. Among other
  issues, it also fixes the problem with wildcard dns names used with SSL.
  (Closes: #515904)
* debian/watch: updated.
* debian/postinst: fixed a bashism. (Closes: #507913)
* debian/conf/nginx.conf: removed default_type. (Closes: #509390)
* debian/control: updated Standards-Version to 3.8.1, no changes needed.
* debian/NEWS.Debian: documented the issues with
  server_names_hash_bucket_size. (Closes: #524785)

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
 
11
11
 
12
12
typedef struct {
13
 
    ngx_str_t      match;
14
 
    ngx_str_t      sub;
15
 
 
16
 
    ngx_array_t   *types;     /* array of ngx_str_t */
17
 
 
18
 
    ngx_array_t   *sub_lengths;
19
 
    ngx_array_t   *sub_values;
20
 
 
21
 
    ngx_flag_t     once;
 
13
    ngx_str_t                  match;
 
14
    ngx_http_complex_value_t   value;
 
15
 
 
16
    ngx_hash_t                 types;
 
17
 
 
18
    ngx_flag_t                 once;
 
19
 
 
20
    ngx_array_t               *types_keys;
22
21
} ngx_http_sub_loc_conf_t;
23
22
 
24
23
 
29
28
 
30
29
 
31
30
typedef struct {
32
 
    ngx_str_t      match;
33
 
 
34
 
    ngx_uint_t     once;   /* unsigned  once:1 */
35
 
 
36
 
    ngx_buf_t     *buf;
37
 
 
38
 
    u_char        *pos;
39
 
    u_char        *copy_start;
40
 
    u_char        *copy_end;
41
 
 
42
 
    ngx_chain_t   *in;
43
 
    ngx_chain_t   *out;
44
 
    ngx_chain_t  **last_out;
45
 
    ngx_chain_t   *busy;
46
 
    ngx_chain_t   *free;
47
 
 
48
 
    ngx_str_t      sub;
49
 
 
50
 
    ngx_uint_t     state;
51
 
    size_t         saved;
52
 
    size_t         looked;
 
31
    ngx_str_t                  match;
 
32
 
 
33
    ngx_uint_t                 once;   /* unsigned  once:1 */
 
34
 
 
35
    ngx_buf_t                 *buf;
 
36
 
 
37
    u_char                    *pos;
 
38
    u_char                    *copy_start;
 
39
    u_char                    *copy_end;
 
40
 
 
41
    ngx_chain_t               *in;
 
42
    ngx_chain_t               *out;
 
43
    ngx_chain_t              **last_out;
 
44
    ngx_chain_t               *busy;
 
45
    ngx_chain_t               *free;
 
46
 
 
47
    ngx_str_t                  sub;
 
48
 
 
49
    ngx_uint_t                 state;
 
50
    size_t                     saved;
 
51
    size_t                     looked;
53
52
} ngx_http_sub_ctx_t;
54
53
 
55
54
 
60
59
 
61
60
static char * ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd,
62
61
    void *conf);
63
 
static char *ngx_http_sub_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
64
62
static void *ngx_http_sub_create_conf(ngx_conf_t *cf);
65
63
static char *ngx_http_sub_merge_conf(ngx_conf_t *cf,
66
64
    void *parent, void *child);
78
76
 
79
77
    { ngx_string("sub_filter_types"),
80
78
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
81
 
      ngx_http_sub_types,
 
79
      ngx_http_types_slot,
82
80
      NGX_HTTP_LOC_CONF_OFFSET,
83
 
      0,
84
 
      NULL },
 
81
      offsetof(ngx_http_sub_loc_conf_t, types_keys),
 
82
      &ngx_http_html_default_types[0] },
85
83
 
86
84
    { ngx_string("sub_filter_once"),
87
85
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
132
130
static ngx_int_t
133
131
ngx_http_sub_header_filter(ngx_http_request_t *r)
134
132
{
135
 
    ngx_str_t                *type;
136
 
    ngx_uint_t                i;
137
133
    ngx_http_sub_ctx_t        *ctx;
138
134
    ngx_http_sub_loc_conf_t  *slcf;
139
135
 
140
136
    slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module);
141
137
 
142
138
    if (slcf->match.len == 0
143
 
        || r->headers_out.content_type.len == 0
144
 
        || r->headers_out.content_length_n == 0)
 
139
        || r->headers_out.content_length_n == 0
 
140
        || ngx_http_test_content_type(r, &slcf->types) == NULL)
145
141
    {
146
142
        return ngx_http_next_header_filter(r);
147
143
    }
148
144
 
149
 
    type = slcf->types->elts;
150
 
    for (i = 0; i < slcf->types->nelts; i++) {
151
 
        if (r->headers_out.content_type.len >= type[i].len
152
 
            && ngx_strncasecmp(r->headers_out.content_type.data,
153
 
                               type[i].data, type[i].len) == 0)
154
 
        {
155
 
            goto found;
156
 
        }
157
 
    }
158
 
 
159
 
    return ngx_http_next_header_filter(r);
160
 
 
161
 
found:
162
 
 
163
145
    ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_sub_ctx_t));
164
146
    if (ctx == NULL) {
165
147
        return NGX_ERROR;
169
151
 
170
152
    ctx->match = slcf->match;
171
153
    ctx->last_out = &ctx->out;
172
 
    ctx->sub = slcf->sub;
173
154
 
174
155
    r->filter_need_in_memory = 1;
175
156
 
219
200
    /* add the incoming chain to the chain ctx->in */
220
201
 
221
202
    if (in) {
222
 
        if (ngx_chain_add_copy(r->pool, &ctx->in, in) == NGX_ERROR) {
 
203
        if (ngx_chain_add_copy(r->pool, &ctx->in, in) != NGX_OK) {
223
204
            return NGX_ERROR;
224
205
        }
225
206
    }
361
342
 
362
343
            if (ctx->sub.data == NULL) {
363
344
 
364
 
                if (ngx_http_script_run(r, &ctx->sub, slcf->sub_lengths->elts,
365
 
                                        0, slcf->sub_values->elts)
366
 
                    == NULL)
 
345
                if (ngx_http_complex_value(r, &slcf->value, &ctx->sub)
 
346
                    != NGX_OK)
367
347
                {
368
348
                    return NGX_ERROR;
369
349
                }
480
460
            break;
481
461
        }
482
462
 
483
 
#if (NGX_HAVE_WRITE_ZEROCOPY)
484
 
        if (b->zerocopy_busy) {
485
 
            break;
486
 
        }
487
 
#endif
488
 
 
489
463
        if (b->shadow) {
490
464
            b->shadow->pos = b->shadow->last;
491
465
        }
630
604
{
631
605
    ngx_http_sub_loc_conf_t *slcf = conf;
632
606
 
633
 
    ngx_str_t                  *value;
634
 
    ngx_int_t                   n;
635
 
    ngx_uint_t                  i;
636
 
    ngx_http_script_compile_t   sc;
 
607
    ngx_str_t                         *value;
 
608
    ngx_http_compile_complex_value_t   ccv;
637
609
 
638
610
    if (slcf->match.len) {
639
611
        return "is duplicate";
641
613
 
642
614
    value = cf->args->elts;
643
615
 
 
616
    ngx_strlow(value[1].data, value[1].data, value[1].len);
 
617
 
644
618
    slcf->match = value[1];
645
619
 
646
 
    for (i = 0; i < value[1].len; i++) {
647
 
        value[1].data[i] = ngx_tolower(value[1].data[i]);
648
 
    }
649
 
 
650
 
    n = ngx_http_script_variables_count(&value[2]);
651
 
 
652
 
    if (n == 0) {
653
 
        slcf->sub = value[2];
654
 
        return NGX_CONF_OK;
655
 
    }
656
 
 
657
 
    ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
658
 
 
659
 
    sc.cf = cf;
660
 
    sc.source = &value[2];
661
 
    sc.lengths = &slcf->sub_lengths;
662
 
    sc.values = &slcf->sub_values;
663
 
    sc.variables = n;
664
 
    sc.complete_lengths = 1;
665
 
    sc.complete_values = 1;
666
 
 
667
 
    if (ngx_http_script_compile(&sc) != NGX_OK) {
 
620
    ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
 
621
 
 
622
    ccv.cf = cf;
 
623
    ccv.value = &value[2];
 
624
    ccv.complex_value = &slcf->value;
 
625
 
 
626
    if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
668
627
        return NGX_CONF_ERROR;
669
628
    }
670
629
 
672
631
}
673
632
 
674
633
 
675
 
static char *
676
 
ngx_http_sub_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
677
 
{
678
 
    ngx_http_sub_loc_conf_t *slcf = conf;
679
 
 
680
 
    ngx_str_t   *value, *type;
681
 
    ngx_uint_t   i;
682
 
 
683
 
    if (slcf->types == NULL) {
684
 
        slcf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
685
 
        if (slcf->types == NULL) {
686
 
            return NGX_CONF_ERROR;
687
 
        }
688
 
 
689
 
        type = ngx_array_push(slcf->types);
690
 
        if (type == NULL) {
691
 
            return NGX_CONF_ERROR;
692
 
        }
693
 
 
694
 
        type->len = sizeof("text/html") - 1;
695
 
        type->data = (u_char *) "text/html";
696
 
    }
697
 
 
698
 
    value = cf->args->elts;
699
 
 
700
 
    for (i = 1; i < cf->args->nelts; i++) {
701
 
 
702
 
        if (ngx_strcmp(value[i].data, "text/html") == 0) {
703
 
            continue;
704
 
        }
705
 
 
706
 
        type = ngx_array_push(slcf->types);
707
 
        if (type == NULL) {
708
 
            return NGX_CONF_ERROR;
709
 
        }
710
 
 
711
 
        type->len = value[i].len;
712
 
 
713
 
        type->data = ngx_palloc(cf->pool, type->len + 1);
714
 
        if (type->data == NULL) {
715
 
            return NGX_CONF_ERROR;
716
 
        }
717
 
 
718
 
        ngx_cpystrn(type->data, value[i].data, type->len + 1);
719
 
    }
720
 
 
721
 
    return NGX_CONF_OK;
722
 
}
723
 
 
724
 
 
725
634
static void *
726
635
ngx_http_sub_create_conf(ngx_conf_t *cf)
727
636
{
735
644
    /*
736
645
     * set by ngx_pcalloc():
737
646
     *
738
 
     *     conf->match.len = 0;
739
 
     *     conf->match.data = NULL;
740
 
     *     conf->sub.len = 0;
741
 
     *     conf->sub.data = NULL;
 
647
     *     conf->match = { 0, NULL };
 
648
     *     conf->sub = { 0, NULL };
742
649
     *     conf->sub_lengths = NULL;
743
650
     *     conf->sub_values = NULL;
744
 
     *     conf->types = NULL;
 
651
     *     conf->types = { NULL };
 
652
     *     conf->types_keys = NULL;
745
653
     */
746
654
 
747
655
    slcf->once = NGX_CONF_UNSET;
756
664
    ngx_http_sub_loc_conf_t *prev = parent;
757
665
    ngx_http_sub_loc_conf_t *conf = child;
758
666
 
759
 
    ngx_str_t  *type;
760
 
 
761
667
    ngx_conf_merge_value(conf->once, prev->once, 1);
762
668
    ngx_conf_merge_str_value(conf->match, prev->match, "");
763
669
 
764
 
    if (conf->sub.data == NULL && conf->sub_lengths == NULL) {
765
 
        conf->sub = prev->sub;
766
 
        conf->sub_lengths = prev->sub_lengths;
767
 
        conf->sub_values = prev->sub_values;
 
670
    if (conf->value.value.len == 0) {
 
671
        conf->value = prev->value;
768
672
    }
769
673
 
770
 
    if (conf->types == NULL) {
771
 
        if (prev->types == NULL) {
772
 
            conf->types = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t));
773
 
            if (conf->types == NULL) {
774
 
                return NGX_CONF_ERROR;
775
 
            }
776
 
 
777
 
            type = ngx_array_push(conf->types);
778
 
            if (type == NULL) {
779
 
                return NGX_CONF_ERROR;
780
 
            }
781
 
 
782
 
            type->len = sizeof("text/html") - 1;
783
 
            type->data = (u_char *) "text/html";
784
 
 
785
 
        } else {
786
 
            conf->types = prev->types;
787
 
        }
 
674
    if (ngx_http_merge_types(cf, conf->types_keys, &conf->types,
 
675
                             prev->types_keys, &prev->types,
 
676
                             ngx_http_html_default_types)
 
677
        != NGX_OK)
 
678
    {
 
679
        return NGX_CONF_ERROR;
788
680
    }
789
681
 
790
682
    return NGX_CONF_OK;