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);
105
static char *ngx_http_ssi_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
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);
154
154
{ ngx_string("ssi_types"),
155
155
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
157
157
NGX_HTTP_LOC_CONF_OFFSET,
158
offsetof(ngx_http_ssi_loc_conf_t, types_keys),
159
&ngx_http_html_default_types[0] },
317
317
ngx_http_ssi_header_filter(ngx_http_request_t *r)
321
319
ngx_http_ssi_ctx_t *ctx;
322
320
ngx_http_ssi_loc_conf_t *slcf;
324
322
slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module);
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)
330
328
return ngx_http_next_header_filter(r);
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)
344
return ngx_http_next_header_filter(r);
349
331
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_ssi_ctx_t));
350
332
if (ctx == NULL) {
351
333
return NGX_ERROR;
416
397
/* add the incoming chain to the chain ctx->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;
405
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
406
"http ssi filter \"%V?%V\"", &r->uri, &r->args);
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);
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);
428
415
return NGX_AGAIN;
431
for (pr = ctx->wait->parent; pr; pr = pr->parent) {
433
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
434
"http ssi filter \"%V\" flush", &r->uri);
436
rc = ngx_http_next_body_filter(r, NULL);
438
if (ctx->wait->done) {
442
if (rc == NGX_ERROR || rc == NGX_AGAIN) {
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);
453
423
ctx->wait = NULL;
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);
430
return ngx_http_next_body_filter(r, NULL);
457
434
slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module);
459
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
460
"http ssi filter \"%V\"", &r->uri);
462
436
while (ctx->in || ctx->buf) {
464
438
if (ctx->buf == NULL ){
812
rc = ngx_http_ssi_output(r, ctx);
815
rc = ngx_http_next_body_filter(r, NULL);
818
if (rc == NGX_ERROR) {
783
if (cmd->flush && ctx->out) {
785
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
788
if (ngx_http_ssi_output(r, ctx) == NGX_ERROR) {
819
789
return NGX_ERROR;
1605
1569
size_t *size, len, prefix, part_len;
1606
1570
ngx_str_t var, *val;
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;
1731
1695
goto invalid_variable;
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]);
1698
key = ngx_hash_strlow(var.data, var.data, var.len);
1741
1700
val = ngx_http_ssi_get_variable(r, &var, key);
1988
flags |= NGX_HTTP_SUBREQUEST_WAITED;
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]);
1992
key = ngx_hash_strlow(set->data, set->data, set->len);
2035
1994
psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
2036
1995
if (psr == NULL) {
2061
2020
psr->data = &var->value;
2064
flags |= NGX_HTTP_SUBREQUEST_IN_MEMORY;
2067
rc = ngx_http_subrequest(r, uri, &args, &sr, psr, flags);
2069
if (rc == NGX_DONE) {
2073
if (rc == NGX_ERROR) {
2023
flags |= NGX_HTTP_SUBREQUEST_IN_MEMORY|NGX_HTTP_SUBREQUEST_WAITED;
2026
if (ngx_http_subrequest(r, uri, &args, &sr, psr, flags) != NGX_OK) {
2074
2027
return NGX_HTTP_SSI_ERROR;
2081
if (rc == NGX_AGAIN) {
2082
if (ctx->wait == NULL) {
2086
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
2087
"only one subrequest may be waited at the same time");
2034
if (ctx->wait == NULL) {
2040
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
2041
"only one subrequest may be waited at the same time");
2152
2104
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2153
2105
"ssi echo \"%V\"", var);
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]);
2107
key = ngx_hash_strlow(var->data, var->data, var->len);
2162
2109
value = ngx_http_ssi_get_variable(r, var, key);
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]);
2286
key = ngx_hash_strlow(name->data, name->data, name->len);
2347
2288
vv = ngx_http_ssi_get_variable(r, name, key);
2705
ngx_http_ssi_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2707
ngx_http_ssi_loc_conf_t *slcf = conf;
2709
ngx_str_t *value, *type;
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;
2718
type = ngx_array_push(slcf->types);
2720
return NGX_CONF_ERROR;
2723
type->len = sizeof("text/html") - 1;
2724
type->data = (u_char *) "text/html";
2727
value = cf->args->elts;
2729
for (i = 1; i < cf->args->nelts; i++) {
2731
if (ngx_strcmp(value[i].data, "text/html") == 0) {
2735
type = ngx_array_push(slcf->types);
2737
return NGX_CONF_ERROR;
2740
type->len = value[i].len;
2742
type->data = ngx_palloc(cf->pool, type->len + 1);
2743
if (type->data == NULL) {
2744
return NGX_CONF_ERROR;
2747
ngx_cpystrn(type->data, value[i].data, type->len + 1);
2754
2645
static ngx_int_t
2755
2646
ngx_http_ssi_preconfiguration(ngx_conf_t *cf)
2871
2763
ngx_http_ssi_loc_conf_t *prev = parent;
2872
2764
ngx_http_ssi_loc_conf_t *conf = child;
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);
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;
2891
type = ngx_array_push(conf->types);
2893
return NGX_CONF_ERROR;
2896
type->len = sizeof("text/html") - 1;
2897
type->data = (u_char *) "text/html";
2900
conf->types = prev->types;
2774
if (ngx_http_merge_types(cf, conf->types_keys, &conf->types,
2775
prev->types_keys, &prev->types,
2776
ngx_http_html_default_types)
2779
return NGX_CONF_ERROR;
2904
2782
return NGX_CONF_OK;