comparison src/http/modules/ngx_http_ssi_filter_module.c @ 216:fa32d59d9a15 NGINX_0_3_55

nginx 0.3.55 *) Feature: the "stub" parameter in the "include" SSI command. *) Feature: the "block" SSI command. *) Feature: the unicode2nginx script was added to contrib. *) Bugfix: if a "root" was specified by variable only, then the root was relative to a server prefix. *) Bugfix: if the request contained "//" or "/./" and escaped symbols after them, then the proxied request was sent unescaped. *) Bugfix: the $r->headers_in("Cookie") of the ngx_http_perl_module now returns all "Cookie" header lines. *) Bugfix: a segmentation fault occurred if "client_body_in_file_only on" was used and nginx switched to a next upstream. *) Bugfix: on some condition while reconfiguration character codes inside the "charset_map" may be treated invalid; bug appeared in 0.3.50.
author Igor Sysoev <http://sysoev.ru>
date Fri, 28 Jul 2006 00:00:00 +0400
parents b12b3b1a9426
children 38e7b94d63ac
comparison
equal deleted inserted replaced
215:84a7f4bc1133 216:fa32d59d9a15
32 typedef struct { 32 typedef struct {
33 ngx_str_t name; 33 ngx_str_t name;
34 ngx_uint_t key; 34 ngx_uint_t key;
35 ngx_str_t value; 35 ngx_str_t value;
36 } ngx_http_ssi_var_t; 36 } ngx_http_ssi_var_t;
37
38
39 typedef struct {
40 ngx_str_t name;
41 ngx_chain_t *bufs;
42 ngx_uint_t count;
43 } ngx_http_ssi_block_t;
37 44
38 45
39 typedef enum { 46 typedef enum {
40 ssi_start_state = 0, 47 ssi_start_state = 0,
41 ssi_tag_state, 48 ssi_tag_state,
81 ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); 88 ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
82 static ngx_int_t ngx_http_ssi_else(ngx_http_request_t *r, 89 static ngx_int_t ngx_http_ssi_else(ngx_http_request_t *r,
83 ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); 90 ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
84 static ngx_int_t ngx_http_ssi_endif(ngx_http_request_t *r, 91 static ngx_int_t ngx_http_ssi_endif(ngx_http_request_t *r,
85 ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); 92 ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
93 static ngx_int_t ngx_http_ssi_block(ngx_http_request_t *r,
94 ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
95 static ngx_int_t ngx_http_ssi_endblock(ngx_http_request_t *r,
96 ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
86 97
87 static ngx_int_t ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, 98 static ngx_int_t ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
88 ngx_http_variable_value_t *v, uintptr_t gmt); 99 ngx_http_variable_value_t *v, uintptr_t gmt);
89 100
90 static char *ngx_http_ssi_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); 101 static char *ngx_http_ssi_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
187 static ngx_str_t ngx_http_ssi_none = ngx_string("(none)"); 198 static ngx_str_t ngx_http_ssi_none = ngx_string("(none)");
188 199
189 #define NGX_HTTP_SSI_INCLUDE_VIRTUAL 0 200 #define NGX_HTTP_SSI_INCLUDE_VIRTUAL 0
190 #define NGX_HTTP_SSI_INCLUDE_FILE 1 201 #define NGX_HTTP_SSI_INCLUDE_FILE 1
191 #define NGX_HTTP_SSI_INCLUDE_WAIT 2 202 #define NGX_HTTP_SSI_INCLUDE_WAIT 2
203 #define NGX_HTTP_SSI_INCLUDE_STUB 3
192 204
193 #define NGX_HTTP_SSI_ECHO_VAR 0 205 #define NGX_HTTP_SSI_ECHO_VAR 0
194 #define NGX_HTTP_SSI_ECHO_DEFAULT 1 206 #define NGX_HTTP_SSI_ECHO_DEFAULT 1
195 207
196 #define NGX_HTTP_SSI_CONFIG_ERRMSG 0 208 #define NGX_HTTP_SSI_CONFIG_ERRMSG 0
198 210
199 #define NGX_HTTP_SSI_SET_VAR 0 211 #define NGX_HTTP_SSI_SET_VAR 0
200 #define NGX_HTTP_SSI_SET_VALUE 1 212 #define NGX_HTTP_SSI_SET_VALUE 1
201 213
202 #define NGX_HTTP_SSI_IF_EXPR 0 214 #define NGX_HTTP_SSI_IF_EXPR 0
215
216 #define NGX_HTTP_SSI_BLOCK_NAME 0
203 217
204 218
205 static ngx_http_ssi_param_t ngx_http_ssi_include_params[] = { 219 static ngx_http_ssi_param_t ngx_http_ssi_include_params[] = {
206 { ngx_string("virtual"), NGX_HTTP_SSI_INCLUDE_VIRTUAL, 0, 0 }, 220 { ngx_string("virtual"), NGX_HTTP_SSI_INCLUDE_VIRTUAL, 0, 0 },
207 { ngx_string("file"), NGX_HTTP_SSI_INCLUDE_FILE, 0, 0 }, 221 { ngx_string("file"), NGX_HTTP_SSI_INCLUDE_FILE, 0, 0 },
208 { ngx_string("wait"), NGX_HTTP_SSI_INCLUDE_WAIT, 0, 0 }, 222 { ngx_string("wait"), NGX_HTTP_SSI_INCLUDE_WAIT, 0, 0 },
223 { ngx_string("stub"), NGX_HTTP_SSI_INCLUDE_STUB, 0, 0 },
209 { ngx_null_string, 0, 0, 0 } 224 { ngx_null_string, 0, 0, 0 }
210 }; 225 };
211 226
212 227
213 static ngx_http_ssi_param_t ngx_http_ssi_echo_params[] = { 228 static ngx_http_ssi_param_t ngx_http_ssi_echo_params[] = {
235 { ngx_string("expr"), NGX_HTTP_SSI_IF_EXPR, 1, 0 }, 250 { ngx_string("expr"), NGX_HTTP_SSI_IF_EXPR, 1, 0 },
236 { ngx_null_string, 0, 0, 0 } 251 { ngx_null_string, 0, 0, 0 }
237 }; 252 };
238 253
239 254
255 static ngx_http_ssi_param_t ngx_http_ssi_block_params[] = {
256 { ngx_string("name"), NGX_HTTP_SSI_BLOCK_NAME, 1, 0 },
257 { ngx_null_string, 0, 0, 0 }
258 };
259
260
240 static ngx_http_ssi_param_t ngx_http_ssi_no_params[] = { 261 static ngx_http_ssi_param_t ngx_http_ssi_no_params[] = {
241 { ngx_null_string, 0, 0, 0 } 262 { ngx_null_string, 0, 0, 0 }
242 }; 263 };
243 264
244 265
245 static ngx_http_ssi_command_t ngx_http_ssi_commands[] = { 266 static ngx_http_ssi_command_t ngx_http_ssi_commands[] = {
246 { ngx_string("include"), ngx_http_ssi_include, 267 { ngx_string("include"), ngx_http_ssi_include,
247 ngx_http_ssi_include_params, 0, 1 }, 268 ngx_http_ssi_include_params, 0, 0, 1 },
248 { ngx_string("echo"), ngx_http_ssi_echo, ngx_http_ssi_echo_params, 0, 0 }, 269 { ngx_string("echo"), ngx_http_ssi_echo,
270 ngx_http_ssi_echo_params, 0, 0, 0 },
249 { ngx_string("config"), ngx_http_ssi_config, 271 { ngx_string("config"), ngx_http_ssi_config,
250 ngx_http_ssi_config_params, 0, 0 }, 272 ngx_http_ssi_config_params, 0, 0, 0 },
251 { ngx_string("set"), ngx_http_ssi_set, ngx_http_ssi_set_params, 0, 0 }, 273 { ngx_string("set"), ngx_http_ssi_set, ngx_http_ssi_set_params, 0, 0, 0 },
252 274
253 { ngx_string("if"), ngx_http_ssi_if, ngx_http_ssi_if_params, 0, 0 }, 275 { ngx_string("if"), ngx_http_ssi_if, ngx_http_ssi_if_params, 0, 0, 0 },
254 { ngx_string("elif"), ngx_http_ssi_if, ngx_http_ssi_if_params, 276 { ngx_string("elif"), ngx_http_ssi_if, ngx_http_ssi_if_params,
255 NGX_HTTP_SSI_COND_IF, 0 }, 277 NGX_HTTP_SSI_COND_IF, 0, 0 },
256 { ngx_string("else"), ngx_http_ssi_else, ngx_http_ssi_no_params, 278 { ngx_string("else"), ngx_http_ssi_else, ngx_http_ssi_no_params,
257 NGX_HTTP_SSI_COND_IF, 0 }, 279 NGX_HTTP_SSI_COND_IF, 0, 0 },
258 { ngx_string("endif"), ngx_http_ssi_endif, ngx_http_ssi_no_params, 280 { ngx_string("endif"), ngx_http_ssi_endif, ngx_http_ssi_no_params,
259 NGX_HTTP_SSI_COND_ELSE, 0 }, 281 NGX_HTTP_SSI_COND_ELSE, 0, 0 },
260 282
261 { ngx_null_string, NULL, NULL, 0, 0 } 283 { ngx_string("block"), ngx_http_ssi_block,
284 ngx_http_ssi_block_params, 0, 0, 0 },
285 { ngx_string("endblock"), ngx_http_ssi_endblock,
286 ngx_http_ssi_no_params, 0, 1, 0 },
287
288 { ngx_null_string, NULL, NULL, 0, 0, 0 }
262 }; 289 };
263 290
264 291
265 static ngx_http_variable_t ngx_http_ssi_vars[] = { 292 static ngx_http_variable_t ngx_http_ssi_vars[] = {
266 293
346 373
347 374
348 static ngx_int_t 375 static ngx_int_t
349 ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in) 376 ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
350 { 377 {
378 size_t len;
351 ngx_int_t rc; 379 ngx_int_t rc;
352 ngx_buf_t *b; 380 ngx_buf_t *b;
353 ngx_uint_t i, index; 381 ngx_uint_t i, index;
354 ngx_chain_t *cl; 382 ngx_chain_t *cl, **ll;
355 ngx_table_elt_t *param; 383 ngx_table_elt_t *param;
356 ngx_connection_t *c; 384 ngx_connection_t *c;
357 ngx_http_ssi_ctx_t *ctx; 385 ngx_http_ssi_ctx_t *ctx, *mctx;
386 ngx_http_ssi_block_t *bl;
358 ngx_http_ssi_param_t *prm; 387 ngx_http_ssi_param_t *prm;
359 ngx_http_ssi_command_t *cmd; 388 ngx_http_ssi_command_t *cmd;
360 ngx_http_ssi_loc_conf_t *slcf; 389 ngx_http_ssi_loc_conf_t *slcf;
361 ngx_http_ssi_main_conf_t *smcf; 390 ngx_http_ssi_main_conf_t *smcf;
362 ngx_str_t *params[NGX_HTTP_SSI_MAX_PARAMS + 1]; 391 ngx_str_t *params[NGX_HTTP_SSI_MAX_PARAMS + 1];
508 cl->next = NULL; 537 cl->next = NULL;
509 *ctx->last_out = cl; 538 *ctx->last_out = cl;
510 ctx->last_out = &cl->next; 539 ctx->last_out = &cl->next;
511 540
512 } else { 541 } else {
542 if (ctx->block
543 && ctx->saved + (ctx->copy_end - ctx->copy_start))
544 {
545 b = ngx_create_temp_buf(r->pool,
546 ctx->saved + (ctx->copy_end - ctx->copy_start));
547
548 if (b == NULL) {
549 return NGX_ERROR;
550 }
551
552 if (ctx->saved) {
553 b->last = ngx_cpymem(b->pos, ngx_http_ssi_string,
554 ctx->saved);
555 }
556
557 b->last = ngx_cpymem(b->last, ctx->copy_start,
558 ctx->copy_end - ctx->copy_start);
559
560 cl = ngx_alloc_chain_link(r->pool);
561 if (cl == NULL) {
562 return NGX_ERROR;
563 }
564
565 cl->buf = b;
566 cl->next = NULL;
567
568 b = NULL;
569
570 mctx = ngx_http_get_module_ctx(r->main,
571 ngx_http_ssi_filter_module);
572 bl = mctx->blocks->elts;
573 for (ll = &bl[mctx->blocks->nelts - 1].bufs;
574 *ll;
575 ll = &(*ll)->next)
576 {
577 /* void */
578 }
579
580 *ll = cl;
581 }
582
513 ctx->saved = 0; 583 ctx->saved = 0;
514 } 584 }
515 } 585 }
516 586
517 if (ctx->state == ssi_start_state) { 587 if (ctx->state == ssi_start_state) {
557 "invalid context of SSI command: \"%V\"", 627 "invalid context of SSI command: \"%V\"",
558 &ctx->command); 628 &ctx->command);
559 goto ssi_error; 629 goto ssi_error;
560 } 630 }
561 631
562 if (!ctx->output && cmd->conditional == 0) { 632 if (!ctx->output && !cmd->block) {
563 continue; 633
634 if (ctx->block) {
635
636 /* reconstruct the SSI command text */
637
638 len = 5 + ctx->command.len + 4;
639
640 param = ctx->params.elts;
641 for (i = 0; i < ctx->params.nelts; i++) {
642 len += 1 + param[i].key.len + 2
643 + param[i].value.len + 1;
644 }
645
646 b = ngx_create_temp_buf(r->pool, len);
647
648 if (b == NULL) {
649 return NGX_ERROR;
650 }
651
652 cl = ngx_alloc_chain_link(r->pool);
653 if (cl == NULL) {
654 return NGX_ERROR;
655 }
656
657 cl->buf = b;
658 cl->next = NULL;
659
660 *b->last++ = '<';
661 *b->last++ = '!';
662 *b->last++ = '-';
663 *b->last++ = '-';
664 *b->last++ = '#';
665
666 b->last = ngx_cpymem(b->last, ctx->command.data,
667 ctx->command.len);
668
669 for (i = 0; i < ctx->params.nelts; i++) {
670 *b->last++ = ' ';
671 b->last = ngx_cpymem(b->last, param[i].key.data,
672 param[i].key.len);
673 *b->last++ = '=';
674 *b->last++ = '"';
675 b->last = ngx_cpymem(b->last, param[i].value.data,
676 param[i].value.len);
677 *b->last++ = '"';
678 }
679
680 *b->last++ = ' ';
681 *b->last++ = '-';
682 *b->last++ = '-';
683 *b->last++ = '>';
684
685 mctx = ngx_http_get_module_ctx(r->main,
686 ngx_http_ssi_filter_module);
687 bl = mctx->blocks->elts;
688 for (ll = &bl[mctx->blocks->nelts - 1].bufs;
689 *ll;
690 ll = &(*ll)->next)
691 {
692 /* void */
693 }
694
695 *ll = cl;
696
697 b = NULL;
698
699 continue;
700 }
701
702 if (cmd->conditional == 0) {
703 continue;
704 }
564 } 705 }
565 706
566 if (ctx->params.nelts > NGX_HTTP_SSI_MAX_PARAMS) { 707 if (ctx->params.nelts > NGX_HTTP_SSI_MAX_PARAMS) {
567 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 708 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
568 "too many SSI command paramters: \"%V\"", 709 "too many SSI command paramters: \"%V\"",
1380 ngx_http_ssi_var_t *var; 1521 ngx_http_ssi_var_t *var;
1381 ngx_http_ssi_ctx_t *ctx; 1522 ngx_http_ssi_ctx_t *ctx;
1382 1523
1383 ctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module); 1524 ctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
1384 1525
1385 var = ctx->variables.elts; 1526 if (ctx->variables == NULL) {
1386 for (i = 0; i < ctx->variables.nelts; i++) { 1527 return NULL;
1528 }
1529
1530 var = ctx->variables->elts;
1531 for (i = 0; i < ctx->variables->nelts; i++) {
1387 if (name->len != var[i].name.len) { 1532 if (name->len != var[i].name.len) {
1388 continue; 1533 continue;
1389 } 1534 }
1390 1535
1391 if (key != var[i].key) { 1536 if (key != var[i].key) {
1661 1806
1662 static ngx_int_t 1807 static ngx_int_t
1663 ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, 1808 ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
1664 ngx_str_t **params) 1809 ngx_str_t **params)
1665 { 1810 {
1666 ngx_int_t rc; 1811 ngx_int_t rc;
1667 ngx_str_t *uri, *file, *wait, args; 1812 ngx_str_t *uri, *file, *wait, *stub, args;
1668 ngx_uint_t flags; 1813 ngx_buf_t *b;
1814 ngx_uint_t flags, i;
1815 ngx_chain_t *out, *cl, *tl, **ll;
1816 ngx_http_ssi_ctx_t *mctx;
1817 ngx_http_ssi_block_t *bl;
1669 1818
1670 uri = params[NGX_HTTP_SSI_INCLUDE_VIRTUAL]; 1819 uri = params[NGX_HTTP_SSI_INCLUDE_VIRTUAL];
1671 file = params[NGX_HTTP_SSI_INCLUDE_FILE]; 1820 file = params[NGX_HTTP_SSI_INCLUDE_FILE];
1672 wait = params[NGX_HTTP_SSI_INCLUDE_WAIT]; 1821 wait = params[NGX_HTTP_SSI_INCLUDE_WAIT];
1822 stub = params[NGX_HTTP_SSI_INCLUDE_STUB];
1673 1823
1674 if (uri && file) { 1824 if (uri && file) {
1675 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 1825 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1676 "inlcusion may be either virtual=\"%V\" or file=\"%V\"", 1826 "inlcusion may be either virtual=\"%V\" or file=\"%V\"",
1677 uri, file); 1827 uri, file);
1685 } 1835 }
1686 1836
1687 if (wait) { 1837 if (wait) {
1688 if (uri == NULL) { 1838 if (uri == NULL) {
1689 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 1839 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1690 "\"wait\" may not be used with file=\"%V\"", 1840 "\"wait\" may not be used with file=\"%V\"", file);
1691 uri, file);
1692 return NGX_HTTP_SSI_ERROR; 1841 return NGX_HTTP_SSI_ERROR;
1693 } 1842 }
1694 1843
1695 if (wait->len == 2 && ngx_strncasecmp(wait->data, "no", 2) == 0) { 1844 if (wait->len == 2 && ngx_strncasecmp(wait->data, "no", 2) == 0) {
1696 wait = NULL; 1845 wait = NULL;
1697 1846
1698 } else if (wait->len != 3 || ngx_strncasecmp(wait->data, "yes", 3) != 0) 1847 } else if (wait->len != 3 || ngx_strncasecmp(wait->data, "yes", 3) != 0)
1699 { 1848 {
1700 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 1849 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1701 "invalid value \"%V\" in the \"wait\" parameter", 1850 "invalid value \"%V\" in the \"wait\" parameter",
1702 &wait); 1851 wait);
1703 return NGX_HTTP_SSI_ERROR; 1852 return NGX_HTTP_SSI_ERROR;
1704 } 1853 }
1705 } 1854 }
1706 1855
1707 if (uri == NULL) { 1856 if (uri == NULL) {
1723 1872
1724 if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) { 1873 if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) {
1725 return NGX_HTTP_SSI_ERROR; 1874 return NGX_HTTP_SSI_ERROR;
1726 } 1875 }
1727 1876
1728 rc = ngx_http_subrequest(r, uri, &args, flags); 1877 out = NULL;
1878
1879 if (stub) {
1880 mctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
1881
1882 if (mctx->blocks) {
1883 bl = mctx->blocks->elts;
1884 for (i = 0; i < mctx->blocks->nelts; i++) {
1885 if (stub->len == bl[i].name.len
1886 && ngx_strncmp(stub->data, bl[i].name.data, stub->len) == 0)
1887 {
1888 goto found;
1889 }
1890 }
1891 }
1892
1893 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1894 "\"stub\"=\"%V\" for \"include\" not found", stub);
1895 return NGX_HTTP_SSI_ERROR;
1896
1897 found:
1898
1899 if (bl[i].count++) {
1900
1901 ll = &out;
1902
1903 for (tl = bl[i].bufs; tl; tl = tl->next) {
1904
1905 if (ctx->free) {
1906 cl = ctx->free;
1907 ctx->free = ctx->free->next;
1908 b = cl->buf;
1909
1910 } else {
1911 b = ngx_alloc_buf(r->pool);
1912 if (b == NULL) {
1913 return NGX_ERROR;
1914 }
1915
1916 cl = ngx_alloc_chain_link(r->pool);
1917 if (cl == NULL) {
1918 return NGX_ERROR;
1919 }
1920
1921 cl->buf = b;
1922 }
1923
1924 ngx_memcpy(b, tl->buf, sizeof(ngx_buf_t));
1925
1926 b->pos = b->start;
1927
1928 *ll = cl;
1929 cl->next = NULL;
1930 ll = &cl->next;
1931 }
1932
1933 } else {
1934 out = bl[i].bufs;
1935 }
1936 }
1937
1938 rc = ngx_http_subrequest(r, uri, &args, out, flags);
1729 1939
1730 if (rc == NGX_ERROR) { 1940 if (rc == NGX_ERROR) {
1731 return NGX_HTTP_SSI_ERROR; 1941 return NGX_HTTP_SSI_ERROR;
1732 } 1942 }
1733 1943
1859 ngx_http_ssi_var_t *var; 2069 ngx_http_ssi_var_t *var;
1860 ngx_http_ssi_ctx_t *mctx; 2070 ngx_http_ssi_ctx_t *mctx;
1861 2071
1862 mctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module); 2072 mctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
1863 2073
1864 if (mctx->variables.elts == NULL) { 2074 if (mctx->variables == NULL) {
1865 if (ngx_array_init(&mctx->variables, r->pool, 4, 2075 mctx->variables = ngx_array_create(r->pool, 4,
1866 sizeof(ngx_http_ssi_var_t)) != NGX_OK) 2076 sizeof(ngx_http_ssi_var_t));
1867 { 2077 if (mctx->variables == NULL) {
1868 return NGX_HTTP_SSI_ERROR; 2078 return NGX_HTTP_SSI_ERROR;
1869 } 2079 }
1870 } 2080 }
1871 2081
1872 name = params[NGX_HTTP_SSI_SET_VAR]; 2082 name = params[NGX_HTTP_SSI_SET_VAR];
1891 if (vv) { 2101 if (vv) {
1892 *vv = *value; 2102 *vv = *value;
1893 return NGX_OK; 2103 return NGX_OK;
1894 } 2104 }
1895 2105
1896 var = ngx_array_push(&mctx->variables); 2106 var = ngx_array_push(mctx->variables);
1897 if (var == NULL) { 2107 if (var == NULL) {
1898 return NGX_HTTP_SSI_ERROR; 2108 return NGX_HTTP_SSI_ERROR;
1899 } 2109 }
1900 2110
1901 var->name = *name; 2111 var->name = *name;
2134 return NGX_OK; 2344 return NGX_OK;
2135 } 2345 }
2136 2346
2137 2347
2138 static ngx_int_t 2348 static ngx_int_t
2349 ngx_http_ssi_block(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
2350 ngx_str_t **params)
2351 {
2352 ngx_http_ssi_ctx_t *mctx;
2353 ngx_http_ssi_block_t *bl;
2354
2355 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2356 "ssi block");
2357
2358 mctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
2359
2360 if (mctx->blocks == NULL) {
2361 mctx->blocks = ngx_array_create(r->pool, 4,
2362 sizeof(ngx_http_ssi_block_t));
2363 if (mctx->blocks == NULL) {
2364 return NGX_HTTP_SSI_ERROR;
2365 }
2366 }
2367
2368 bl = ngx_array_push(mctx->blocks);
2369 if (bl == NULL) {
2370 return NGX_HTTP_SSI_ERROR;
2371 }
2372
2373 bl->name = *params[NGX_HTTP_SSI_BLOCK_NAME];
2374 bl->bufs = NULL;
2375 bl->count = 0;
2376
2377 ctx->output = 0;
2378 ctx->block = 1;
2379
2380 return NGX_OK;
2381 }
2382
2383
2384 static ngx_int_t
2385 ngx_http_ssi_endblock(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
2386 ngx_str_t **params)
2387 {
2388 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2389 "ssi endblock");
2390
2391 ctx->output = 1;
2392 ctx->block = 0;
2393
2394 return NGX_OK;
2395 }
2396
2397
2398 static ngx_int_t
2139 ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, 2399 ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
2140 ngx_http_variable_value_t *v, uintptr_t gmt) 2400 ngx_http_variable_value_t *v, uintptr_t gmt)
2141 { 2401 {
2142 ngx_http_ssi_ctx_t *ctx; 2402 ngx_http_ssi_ctx_t *ctx;
2143 ngx_time_t *tp; 2403 ngx_time_t *tp;