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

« back to all changes in this revision

Viewing changes to src/http/modules/ngx_http_ssi_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:
22
22
    ngx_flag_t    silent_errors;
23
23
    ngx_flag_t    ignore_recycled_buffers;
24
24
 
25
 
    ngx_array_t  *types;     /* array of ngx_str_t */
 
25
    ngx_hash_t    types;
26
26
 
27
27
    size_t        min_file_chunk;
28
28
    size_t        value_len;
 
29
 
 
30
    ngx_array_t  *types_keys;
29
31
} ngx_http_ssi_loc_conf_t;
30
32
 
31
33
 
102
104
static ngx_int_t ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
103
105
    ngx_http_variable_value_t *v, uintptr_t gmt);
104
106
 
105
 
static char *ngx_http_ssi_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
106
 
 
107
107
static ngx_int_t ngx_http_ssi_preconfiguration(ngx_conf_t *cf);
108
108
static void *ngx_http_ssi_create_main_conf(ngx_conf_t *cf);
109
109
static char *ngx_http_ssi_init_main_conf(ngx_conf_t *cf, void *conf);
153
153
 
154
154
    { ngx_string("ssi_types"),
155
155
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
156
 
      ngx_http_ssi_types,
 
156
      ngx_http_types_slot,
157
157
      NGX_HTTP_LOC_CONF_OFFSET,
158
 
      0,
159
 
      NULL },
 
158
      offsetof(ngx_http_ssi_loc_conf_t, types_keys),
 
159
      &ngx_http_html_default_types[0] },
160
160
 
161
161
      ngx_null_command
162
162
};
316
316
static ngx_int_t
317
317
ngx_http_ssi_header_filter(ngx_http_request_t *r)
318
318
{
319
 
    ngx_uint_t                i;
320
 
    ngx_str_t                *type;
321
319
    ngx_http_ssi_ctx_t       *ctx;
322
320
    ngx_http_ssi_loc_conf_t  *slcf;
323
321
 
324
322
    slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module);
325
323
 
326
324
    if (!slcf->enable
327
 
        || r->headers_out.content_type.len == 0
328
 
        || r->headers_out.content_length_n == 0)
 
325
        || r->headers_out.content_length_n == 0
 
326
        || ngx_http_test_content_type(r, &slcf->types) == NULL)
329
327
    {
330
328
        return ngx_http_next_header_filter(r);
331
329
    }
332
330
 
333
 
 
334
 
    type = slcf->types->elts;
335
 
    for (i = 0; i < slcf->types->nelts; i++) {
336
 
        if (r->headers_out.content_type.len >= type[i].len
337
 
            && ngx_strncasecmp(r->headers_out.content_type.data,
338
 
                               type[i].data, type[i].len) == 0)
339
 
        {
340
 
            goto found;
341
 
        }
342
 
    }
343
 
 
344
 
    return ngx_http_next_header_filter(r);
345
 
 
346
 
 
347
 
found:
348
 
 
349
331
    ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_ssi_ctx_t));
350
332
    if (ctx == NULL) {
351
333
        return NGX_ERROR;
393
375
    ngx_uint_t                 i, index;
394
376
    ngx_chain_t               *cl, **ll;
395
377
    ngx_table_elt_t           *param;
396
 
    ngx_http_request_t        *pr;
397
378
    ngx_http_ssi_ctx_t        *ctx, *mctx;
398
379
    ngx_http_ssi_block_t      *bl;
399
380
    ngx_http_ssi_param_t      *prm;
416
397
    /* add the incoming chain to the chain ctx->in */
417
398
 
418
399
    if (in) {
419
 
        if (ngx_chain_add_copy(r->pool, &ctx->in, in) == NGX_ERROR) {
 
400
        if (ngx_chain_add_copy(r->pool, &ctx->in, in) != NGX_OK) {
420
401
            return NGX_ERROR;
421
402
        }
422
403
    }
423
404
 
 
405
    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
406
                   "http ssi filter \"%V?%V\"", &r->uri, &r->args);
 
407
 
424
408
    if (ctx->wait) {
425
 
        if (r->connection->data != r) {
426
 
            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
427
 
                           "http ssi filter \"%V\" wait", &r->uri);
 
409
 
 
410
        if (r != r->connection->data) {
 
411
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
412
                           "http ssi filter wait \"%V?%V\" non-active",
 
413
                           &ctx->wait->uri, &ctx->wait->args);
 
414
 
428
415
            return NGX_AGAIN;
429
416
        }
430
417
 
431
 
        for (pr = ctx->wait->parent; pr; pr = pr->parent) {
432
 
            if (pr == r) {
433
 
                ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
434
 
                               "http ssi filter \"%V\" flush", &r->uri);
435
 
 
436
 
                rc = ngx_http_next_body_filter(r, NULL);
437
 
 
438
 
                if (ctx->wait->done) {
439
 
                    ctx->wait = NULL;
440
 
                }
441
 
 
442
 
                if (rc == NGX_ERROR || rc == NGX_AGAIN) {
443
 
                    return rc;
444
 
                }
445
 
 
446
 
                break;
447
 
            }
448
 
        }
449
 
 
450
 
        if (ctx->wait == r) {
451
 
            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
452
 
                           "http ssi filter \"%V\" continue", &r->uri);
 
418
        if (ctx->wait->done) {
 
419
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
420
                           "http ssi filter wait \"%V?%V\" done",
 
421
                           &ctx->wait->uri, &ctx->wait->args);
 
422
 
453
423
            ctx->wait = NULL;
 
424
 
 
425
        } else {
 
426
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
427
                           "http ssi filter wait \"%V?%V\"",
 
428
                           &ctx->wait->uri, &ctx->wait->args);
 
429
 
 
430
            return ngx_http_next_body_filter(r, NULL);
454
431
        }
455
432
    }
456
433
 
457
434
    slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module);
458
435
 
459
 
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
460
 
                   "http ssi filter \"%V\"", &r->uri);
461
 
 
462
436
    while (ctx->in || ctx->buf) {
463
437
 
464
438
        if (ctx->buf == NULL ){
806
780
                    }
807
781
                }
808
782
 
809
 
                if (cmd->flush) {
810
 
 
811
 
                    if (ctx->out) {
812
 
                        rc = ngx_http_ssi_output(r, ctx);
813
 
 
814
 
                    } else {
815
 
                        rc = ngx_http_next_body_filter(r, NULL);
816
 
                    }
817
 
 
818
 
                    if (rc == NGX_ERROR) {
 
783
                if (cmd->flush && ctx->out) {
 
784
 
 
785
                    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
786
                                   "ssi flush");
 
787
 
 
788
                    if (ngx_http_ssi_output(r, ctx) == NGX_ERROR) {
819
789
                        return NGX_ERROR;
820
790
                    }
821
791
                }
965
935
            break;
966
936
        }
967
937
 
968
 
#if (NGX_HAVE_WRITE_ZEROCOPY)
969
 
        if (b->zerocopy_busy) {
970
 
            break;
971
 
        }
972
 
#endif
973
 
 
974
938
        if (b->shadow) {
975
939
            b->shadow->pos = b->shadow->last;
976
940
        }
1152
1116
 
1153
1117
            default:
1154
1118
                ctx->command.len = 1;
1155
 
                ctx->command.data = ngx_palloc(r->pool,
1156
 
                                               NGX_HTTP_SSI_COMMAND_LEN);
 
1119
                ctx->command.data = ngx_pnalloc(r->pool,
 
1120
                                                NGX_HTTP_SSI_COMMAND_LEN);
1157
1121
                if (ctx->command.data == NULL) {
1158
1122
                    return NGX_ERROR;
1159
1123
                }
1219
1183
                }
1220
1184
 
1221
1185
                ctx->param->key.len = 1;
1222
 
                ctx->param->key.data = ngx_palloc(r->pool,
1223
 
                                                  NGX_HTTP_SSI_PARAM_LEN);
 
1186
                ctx->param->key.data = ngx_pnalloc(r->pool,
 
1187
                                                   NGX_HTTP_SSI_PARAM_LEN);
1224
1188
                if (ctx->param->key.data == NULL) {
1225
1189
                    return NGX_ERROR;
1226
1190
                }
1230
1194
                ctx->param->value.len = 0;
1231
1195
 
1232
1196
                if (ctx->value_buf == NULL) {
1233
 
                    ctx->param->value.data = ngx_palloc(r->pool,
1234
 
                                                        ctx->value_len);
 
1197
                    ctx->param->value.data = ngx_pnalloc(r->pool,
 
1198
                                                         ctx->value_len);
1235
1199
                    if (ctx->param->value.data == NULL) {
1236
1200
                        return NGX_ERROR;
1237
1201
                    }
1409
1373
        case ssi_postparam_state:
1410
1374
 
1411
1375
            if (ctx->param->value.len + 1 < ctx->value_len / 2) {
1412
 
                value = ngx_palloc(r->pool, ctx->param->value.len + 1);
 
1376
                value = ngx_pnalloc(r->pool, ctx->param->value.len + 1);
1413
1377
                if (value == NULL) {
1414
1378
                    return NGX_ERROR;
1415
1379
                }
1605
1569
    size_t                     *size, len, prefix, part_len;
1606
1570
    ngx_str_t                   var, *val;
1607
1571
    ngx_int_t                   key;
1608
 
    ngx_uint_t                  i, j, n, bracket, quoted;
 
1572
    ngx_uint_t                  i, n, bracket, quoted;
1609
1573
    ngx_array_t                 lengths, values;
1610
1574
    ngx_http_variable_value_t  *vv;
1611
1575
 
1627
1591
            if (prefix) {
1628
1592
                len = prefix + text->len;
1629
1593
 
1630
 
                data = ngx_palloc(r->pool, len);
 
1594
                data = ngx_pnalloc(r->pool, len);
1631
1595
                if (data == NULL) {
1632
1596
                    return NGX_ERROR;
1633
1597
                }
1731
1695
                goto invalid_variable;
1732
1696
            }
1733
1697
 
1734
 
            key = 0;
1735
 
 
1736
 
            for (j = 0; j < var.len; j++) {
1737
 
                var.data[j] = ngx_tolower(var.data[j]);
1738
 
                key = ngx_hash(key, var.data[j]);
1739
 
            }
 
1698
            key = ngx_hash_strlow(var.data, var.data, var.len);
1740
1699
 
1741
1700
            val = ngx_http_ssi_get_variable(r, &var, key);
1742
1701
 
1830
1789
        }
1831
1790
    }
1832
1791
 
1833
 
    p = ngx_palloc(r->pool, len + ((flags & NGX_HTTP_SSI_ADD_ZERO) ? 1 : 0));
 
1792
    p = ngx_pnalloc(r->pool, len + ((flags & NGX_HTTP_SSI_ADD_ZERO) ? 1 : 0));
1834
1793
    if (p == NULL) {
1835
1794
        return NGX_ERROR;
1836
1795
    }
1922
1881
 
1923
1882
    if (uri == NULL) {
1924
1883
        uri = file;
 
1884
        wait = (ngx_str_t *) -1;
1925
1885
    }
1926
1886
 
1927
1887
    rc = ngx_http_ssi_evaluate_string(r, ctx, uri, NGX_HTTP_SSI_ADD_PREFIX);
2024
1984
        }
2025
1985
    }
2026
1986
 
 
1987
    if (wait) {
 
1988
        flags |= NGX_HTTP_SUBREQUEST_WAITED;
 
1989
    }
 
1990
 
2027
1991
    if (set) {
2028
 
        key = 0;
2029
 
 
2030
 
        for (i = 0; i < set->len; i++) {
2031
 
            set->data[i] = ngx_tolower(set->data[i]);
2032
 
            key = ngx_hash(key, set->data[i]);
2033
 
        }
 
1992
        key = ngx_hash_strlow(set->data, set->data, set->len);
2034
1993
 
2035
1994
        psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
2036
1995
        if (psr == NULL) {
2061
2020
            psr->data = &var->value;
2062
2021
        }
2063
2022
 
2064
 
        flags |= NGX_HTTP_SUBREQUEST_IN_MEMORY;
2065
 
    }
2066
 
 
2067
 
    rc = ngx_http_subrequest(r, uri, &args, &sr, psr, flags);
2068
 
 
2069
 
    if (rc == NGX_DONE) {
2070
 
        return NGX_DONE;
2071
 
    }
2072
 
 
2073
 
    if (rc == NGX_ERROR) {
 
2023
        flags |= NGX_HTTP_SUBREQUEST_IN_MEMORY|NGX_HTTP_SUBREQUEST_WAITED;
 
2024
    }
 
2025
 
 
2026
    if (ngx_http_subrequest(r, uri, &args, &sr, psr, flags) != NGX_OK) {
2074
2027
        return NGX_HTTP_SSI_ERROR;
2075
2028
    }
2076
2029
 
2078
2031
        return NGX_OK;
2079
2032
    }
2080
2033
 
2081
 
    if (rc == NGX_AGAIN) {
2082
 
        if (ctx->wait == NULL) {
2083
 
            ctx->wait = sr;
2084
 
 
2085
 
        } else {
2086
 
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
2087
 
                          "only one subrequest may be waited at the same time");
2088
 
        }
 
2034
    if (ctx->wait == NULL) {
 
2035
        ctx->wait = sr;
 
2036
 
 
2037
        return NGX_AGAIN;
 
2038
 
 
2039
    } else {
 
2040
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
 
2041
                      "only one subrequest may be waited at the same time");
2089
2042
    }
2090
2043
 
2091
 
    return rc;
 
2044
    return NGX_OK;
2092
2045
}
2093
2046
 
2094
2047
 
2107
2060
    out = data;
2108
2061
 
2109
2062
    if (!r->header_sent) {
2110
 
        if (ngx_http_set_content_type(r) == NGX_ERROR) {
 
2063
        if (ngx_http_set_content_type(r) != NGX_OK) {
2111
2064
            return NGX_ERROR;
2112
2065
        }
2113
2066
 
2141
2094
    u_char                     *p;
2142
2095
    uintptr_t                   len;
2143
2096
    ngx_int_t                   key;
2144
 
    ngx_uint_t                  i;
2145
2097
    ngx_buf_t                  *b;
2146
2098
    ngx_str_t                  *var, *value, *enc, text;
2147
2099
    ngx_chain_t                *cl;
2152
2104
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2153
2105
                   "ssi echo \"%V\"", var);
2154
2106
 
2155
 
    key = 0;
2156
 
 
2157
 
    for (i = 0; i < var->len; i++) {
2158
 
        var->data[i] = ngx_tolower(var->data[i]);
2159
 
        key = ngx_hash(key, var->data[i]);
2160
 
    }
 
2107
    key = ngx_hash_strlow(var->data, var->data, var->len);
2161
2108
 
2162
2109
    value = ngx_http_ssi_get_variable(r, var, key);
2163
2110
 
2223
2170
                                 NGX_ESCAPE_HTML);
2224
2171
 
2225
2172
        if (len) {
2226
 
            p = ngx_palloc(r->pool, value->len + len);
 
2173
            p = ngx_pnalloc(r->pool, value->len + len);
2227
2174
            if (p == NULL) {
2228
2175
                return NGX_HTTP_SSI_ERROR;
2229
2176
            }
2240
2187
        len = ngx_escape_html(NULL, value->data, value->len);
2241
2188
 
2242
2189
        if (len) {
2243
 
            p = ngx_palloc(r->pool, value->len + len);
 
2190
            p = ngx_pnalloc(r->pool, value->len + len);
2244
2191
            if (p == NULL) {
2245
2192
                return NGX_HTTP_SSI_ERROR;
2246
2193
            }
2287
2234
 
2288
2235
    if (value) {
2289
2236
        ctx->timefmt.len = value->len;
2290
 
        ctx->timefmt.data = ngx_palloc(r->pool, value->len + 1);
 
2237
        ctx->timefmt.data = ngx_pnalloc(r->pool, value->len + 1);
2291
2238
        if (ctx->timefmt.data == NULL) {
2292
2239
            return NGX_HTTP_SSI_ERROR;
2293
2240
        }
2310
2257
    ngx_str_t **params)
2311
2258
{
2312
2259
    ngx_int_t            key, rc;
2313
 
    ngx_uint_t           i;
2314
2260
    ngx_str_t           *name, *value, *vv;
2315
2261
    ngx_http_ssi_var_t  *var;
2316
2262
    ngx_http_ssi_ctx_t  *mctx;
2337
2283
        return rc;
2338
2284
    }
2339
2285
 
2340
 
    key = 0;
2341
 
 
2342
 
    for (i = 0; i < name->len; i++) {
2343
 
        name->data[i] = ngx_tolower(name->data[i]);
2344
 
        key = ngx_hash(key, name->data[i]);
2345
 
    }
 
2286
    key = ngx_hash_strlow(name->data, name->data, name->len);
2346
2287
 
2347
2288
    vv = ngx_http_ssi_get_variable(r, name, key);
2348
2289
 
2667
2608
        || (ctx->timefmt.len == sizeof("%s") - 1
2668
2609
            && ctx->timefmt.data[0] == '%' && ctx->timefmt.data[1] == 's'))
2669
2610
    {
2670
 
        v->data = ngx_palloc(r->pool, NGX_TIME_T_LEN);
 
2611
        v->data = ngx_pnalloc(r->pool, NGX_TIME_T_LEN);
2671
2612
        if (v->data == NULL) {
2672
2613
            return NGX_ERROR;
2673
2614
        }
2690
2631
        return NGX_ERROR;
2691
2632
    }
2692
2633
 
2693
 
    v->data = ngx_palloc(r->pool, v->len);
 
2634
    v->data = ngx_pnalloc(r->pool, v->len);
2694
2635
    if (v->data == NULL) {
2695
2636
        return NGX_ERROR;
2696
2637
    }
2701
2642
}
2702
2643
 
2703
2644
 
2704
 
static char *
2705
 
ngx_http_ssi_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2706
 
{
2707
 
    ngx_http_ssi_loc_conf_t *slcf = conf;
2708
 
 
2709
 
    ngx_str_t   *value, *type;
2710
 
    ngx_uint_t   i;
2711
 
 
2712
 
    if (slcf->types == NULL) {
2713
 
        slcf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
2714
 
        if (slcf->types == NULL) {
2715
 
            return NGX_CONF_ERROR;
2716
 
        }
2717
 
 
2718
 
        type = ngx_array_push(slcf->types);
2719
 
        if (type == NULL) {
2720
 
            return NGX_CONF_ERROR;
2721
 
        }
2722
 
 
2723
 
        type->len = sizeof("text/html") - 1;
2724
 
        type->data = (u_char *) "text/html";
2725
 
    }
2726
 
 
2727
 
    value = cf->args->elts;
2728
 
 
2729
 
    for (i = 1; i < cf->args->nelts; i++) {
2730
 
 
2731
 
        if (ngx_strcmp(value[i].data, "text/html") == 0) {
2732
 
            continue;
2733
 
        }
2734
 
 
2735
 
        type = ngx_array_push(slcf->types);
2736
 
        if (type == NULL) {
2737
 
            return NGX_CONF_ERROR;
2738
 
        }
2739
 
 
2740
 
        type->len = value[i].len;
2741
 
 
2742
 
        type->data = ngx_palloc(cf->pool, type->len + 1);
2743
 
        if (type->data == NULL) {
2744
 
            return NGX_CONF_ERROR;
2745
 
        }
2746
 
 
2747
 
        ngx_cpystrn(type->data, value[i].data, type->len + 1);
2748
 
    }
2749
 
 
2750
 
    return NGX_CONF_OK;
2751
 
}
2752
 
 
2753
 
 
2754
2645
static ngx_int_t
2755
2646
ngx_http_ssi_preconfiguration(ngx_conf_t *cf)
2756
2647
{
2851
2742
    /*
2852
2743
     * set by ngx_pcalloc():
2853
2744
     *
2854
 
     *     conf->types = NULL;
 
2745
     *     conf->types = { NULL };
 
2746
     *     conf->types_keys = NULL;
2855
2747
     */
2856
2748
 
2857
2749
    slcf->enable = NGX_CONF_UNSET;
2871
2763
    ngx_http_ssi_loc_conf_t *prev = parent;
2872
2764
    ngx_http_ssi_loc_conf_t *conf = child;
2873
2765
 
2874
 
    ngx_str_t  *type;
2875
 
 
2876
2766
    ngx_conf_merge_value(conf->enable, prev->enable, 0);
2877
2767
    ngx_conf_merge_value(conf->silent_errors, prev->silent_errors, 0);
2878
2768
    ngx_conf_merge_value(conf->ignore_recycled_buffers,
2881
2771
    ngx_conf_merge_size_value(conf->min_file_chunk, prev->min_file_chunk, 1024);
2882
2772
    ngx_conf_merge_size_value(conf->value_len, prev->value_len, 256);
2883
2773
 
2884
 
    if (conf->types == NULL) {
2885
 
        if (prev->types == NULL) {
2886
 
            conf->types = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t));
2887
 
            if (conf->types == NULL) {
2888
 
                return NGX_CONF_ERROR;
2889
 
            }
2890
 
 
2891
 
            type = ngx_array_push(conf->types);
2892
 
            if (type == NULL) {
2893
 
                return NGX_CONF_ERROR;
2894
 
            }
2895
 
 
2896
 
            type->len = sizeof("text/html") - 1;
2897
 
            type->data = (u_char *) "text/html";
2898
 
 
2899
 
        } else {
2900
 
            conf->types = prev->types;
2901
 
        }
 
2774
    if (ngx_http_merge_types(cf, conf->types_keys, &conf->types,
 
2775
                             prev->types_keys, &prev->types,
 
2776
                             ngx_http_html_default_types)
 
2777
        != NGX_OK)
 
2778
    {
 
2779
        return NGX_CONF_ERROR;
2902
2780
    }
2903
2781
 
2904
2782
    return NGX_CONF_OK;