Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_ssi_filter_module.c @ 573:58475592100c release-0.3.8
nginx-0.3.8-RELEASE import
*) Security: nginx now checks URI got from a backend in
"X-Accel-Redirect" header line or in SSI file for the "/../" paths
and zeroes.
*) Change: nginx now does not treat the empty user name in the
"Authorization" header line as valid one.
*) Feature: the "ssl_session_timeout" directives of the
ngx_http_ssl_module and ngx_imap_ssl_module.
*) Feature: the "auth_http_header" directive of the
ngx_imap_auth_http_module.
*) Feature: the "add_header" directive.
*) Feature: the ngx_http_realip_module.
*) Feature: the new variables to use in the "log_format" directive:
$bytes_sent, $apache_bytes_sent, $status, $time_gmt, $uri,
$request_time, $request_length, $upstream_status,
$upstream_response_time, $gzip_ratio, $uid_got, $uid_set,
$connection, $pipe, and $msec. The parameters in the "%name" form
will be canceled soon.
*) Change: now the false variable values in the "if" directive are the
empty string "" and string starting with "0".
*) Bugfix: while using proxied or FastCGI-server nginx may leave
connections and temporary files with client requests in open state.
*) Bugfix: the worker processes did not flush the buffered logs on
graceful exit.
*) Bugfix: if the request URI was changes by the "rewrite" directive
and the request was proxied in location given by regular expression,
then the incorrect request was transferred to backend; the bug had
appeared in 0.2.6.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" header.
*) Bugfix: nginx may stop to accept requests if the "rtsig" method and
several worker processes were used.
*) Bugfix: the "\"" and "\'" escape symbols were incorrectly handled in
SSI commands.
*) Bugfix: if the response was ended just after the SSI command and
gzipping was used, then the response did not transferred complete or
did not transferred at all.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 09 Nov 2005 17:25:55 +0000 |
parents | 174f1e853e1e |
children | 4d9ea73a627a |
comparison
equal
deleted
inserted
replaced
572:ae8920455206 | 573:58475592100c |
---|---|
142 static ngx_int_t ngx_http_ssi_else(ngx_http_request_t *r, | 142 static ngx_int_t ngx_http_ssi_else(ngx_http_request_t *r, |
143 ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); | 143 ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); |
144 static ngx_int_t ngx_http_ssi_endif(ngx_http_request_t *r, | 144 static ngx_int_t ngx_http_ssi_endif(ngx_http_request_t *r, |
145 ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); | 145 ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); |
146 | 146 |
147 static ngx_http_variable_value_t * | 147 static ngx_int_t ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, |
148 ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, uintptr_t gmt); | 148 ngx_http_variable_value_t *v, uintptr_t gmt); |
149 | 149 |
150 static char *ngx_http_ssi_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | 150 static char *ngx_http_ssi_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
151 | 151 |
152 static ngx_int_t ngx_http_ssi_add_variables(ngx_conf_t *cf); | 152 static ngx_int_t ngx_http_ssi_add_variables(ngx_conf_t *cf); |
153 static void *ngx_http_ssi_create_conf(ngx_conf_t *cf); | 153 static void *ngx_http_ssi_create_conf(ngx_conf_t *cf); |
560 if (rc == NGX_AGAIN) { | 560 if (rc == NGX_AGAIN) { |
561 continue; | 561 continue; |
562 } | 562 } |
563 | 563 |
564 | 564 |
565 b = NULL; | |
566 | |
565 if (rc == NGX_OK) { | 567 if (rc == NGX_OK) { |
566 | 568 |
567 for (cmd = ngx_http_ssi_commands; cmd->handler; cmd++) { | 569 for (cmd = ngx_http_ssi_commands; cmd->handler; cmd++) { |
568 if (cmd->name.len == 0) { | 570 if (cmd->name.len == 0) { |
569 cmd = (ngx_http_ssi_command_t *) cmd->handler; | 571 cmd = (ngx_http_ssi_command_t *) cmd->handler; |
1198 if (ch == '\\') { | 1200 if (ch == '\\') { |
1199 break; | 1201 break; |
1200 } | 1202 } |
1201 | 1203 |
1202 if (ch == '"' && state == ssi_double_quoted_value_state) { | 1204 if (ch == '"' && state == ssi_double_quoted_value_state) { |
1205 ctx->param->value.data[ctx->param->value.len - 1] = ch; | |
1203 break; | 1206 break; |
1204 } | 1207 } |
1205 | 1208 |
1206 if (ch == '\'' && state == ssi_quoted_value_state) { | 1209 if (ch == '\'' && state == ssi_quoted_value_state) { |
1210 ctx->param->value.data[ctx->param->value.len - 1] = ch; | |
1207 break; | 1211 break; |
1208 } | 1212 } |
1209 | 1213 |
1210 ctx->param->value.data[ctx->param->value.len++] = ch; | 1214 ctx->param->value.data[ctx->param->value.len++] = ch; |
1211 | 1215 |
1376 | 1380 |
1377 static ngx_int_t | 1381 static ngx_int_t |
1378 ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, | 1382 ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, |
1379 ngx_str_t *text, ngx_uint_t flags) | 1383 ngx_str_t *text, ngx_uint_t flags) |
1380 { | 1384 { |
1381 u_char ch, *p, **value, *data; | 1385 u_char ch, *p, **value, *data, *part_data; |
1382 size_t *size, len, prefix; | 1386 size_t *size, len, prefix, part_len; |
1383 ngx_str_t var, part, *val; | 1387 ngx_str_t var, *val; |
1384 ngx_uint_t i, j, n, bracket; | 1388 ngx_uint_t i, j, n, bracket; |
1385 ngx_array_t lengths, values; | 1389 ngx_array_t lengths, values; |
1386 ngx_http_variable_value_t *vv; | 1390 ngx_http_variable_value_t *vv; |
1387 | 1391 |
1388 n = ngx_http_script_variables_count(text); | 1392 n = ngx_http_script_variables_count(text); |
1406 data = ngx_palloc(r->pool, len); | 1410 data = ngx_palloc(r->pool, len); |
1407 if (data == NULL) { | 1411 if (data == NULL) { |
1408 return NGX_ERROR; | 1412 return NGX_ERROR; |
1409 } | 1413 } |
1410 | 1414 |
1411 p = ngx_cpymem(data, r->uri.data, prefix); | 1415 p = ngx_copy(data, r->uri.data, prefix); |
1412 ngx_memcpy(p, text->data, text->len); | 1416 ngx_memcpy(p, text->data, text->len); |
1413 | 1417 |
1414 text->len = len; | 1418 text->len = len; |
1415 text->data = data; | 1419 text->data = data; |
1416 } | 1420 } |
1496 | 1500 |
1497 if (vv == NULL) { | 1501 if (vv == NULL) { |
1498 return NGX_ERROR; | 1502 return NGX_ERROR; |
1499 } | 1503 } |
1500 | 1504 |
1501 if (vv == NGX_HTTP_VAR_NOT_FOUND) { | 1505 if (vv->not_found) { |
1502 continue; | 1506 continue; |
1503 } | 1507 } |
1504 | 1508 |
1505 part = vv->text; | 1509 part_data = vv->data; |
1510 part_len = vv->len; | |
1506 | 1511 |
1507 } else { | 1512 } else { |
1508 part = *val; | 1513 part_data = val->data; |
1514 part_len = val->len; | |
1509 } | 1515 } |
1510 | 1516 |
1511 } else { | 1517 } else { |
1512 part.data = &text->data[i]; | 1518 part_data = &text->data[i]; |
1513 | 1519 |
1514 for (p = part.data; i < text->len; i++) { | 1520 for (p = part_data; i < text->len; i++) { |
1515 ch = text->data[i]; | 1521 ch = text->data[i]; |
1516 | 1522 |
1517 if (ch == '$') { | 1523 if (ch == '$') { |
1518 if (text->data[i - 1] != '\\') { | 1524 if (text->data[i - 1] != '\\') { |
1519 break; | 1525 break; |
1525 } | 1531 } |
1526 | 1532 |
1527 *p++ = ch; | 1533 *p++ = ch; |
1528 } | 1534 } |
1529 | 1535 |
1530 part.len = p - part.data; | 1536 part_len = p - part_data; |
1531 } | 1537 } |
1532 | 1538 |
1533 len += part.len; | 1539 len += part_len; |
1534 | 1540 |
1535 size = ngx_array_push(&lengths); | 1541 size = ngx_array_push(&lengths); |
1536 if (size == NULL) { | 1542 if (size == NULL) { |
1537 return NGX_ERROR; | 1543 return NGX_ERROR; |
1538 } | 1544 } |
1539 | 1545 |
1540 *size = part.len; | 1546 *size = part_len; |
1541 | 1547 |
1542 value = ngx_array_push(&values); | 1548 value = ngx_array_push(&values); |
1543 if (value == NULL) { | 1549 if (value == NULL) { |
1544 return NGX_ERROR; | 1550 return NGX_ERROR; |
1545 } | 1551 } |
1546 | 1552 |
1547 *value = part.data; | 1553 *value = part_data; |
1548 } | 1554 } |
1549 | 1555 |
1550 prefix = 0; | 1556 prefix = 0; |
1551 | 1557 |
1552 size = lengths.elts; | 1558 size = lengths.elts; |
1575 } | 1581 } |
1576 | 1582 |
1577 text->len = len; | 1583 text->len = len; |
1578 text->data = p; | 1584 text->data = p; |
1579 | 1585 |
1580 if (prefix) { | 1586 p = ngx_copy(p, r->uri.data, prefix); |
1581 p = ngx_cpymem(p, r->uri.data, prefix); | |
1582 } | |
1583 | 1587 |
1584 for (i = 0; i < values.nelts; i++) { | 1588 for (i = 0; i < values.nelts; i++) { |
1585 p = ngx_cpymem(p, value[i], size[i]); | 1589 p = ngx_copy(p, value[i], size[i]); |
1586 } | 1590 } |
1587 | 1591 |
1588 return NGX_OK; | 1592 return NGX_OK; |
1589 | 1593 |
1590 invalid_variable: | 1594 invalid_variable: |
1599 static ngx_int_t | 1603 static ngx_int_t |
1600 ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, | 1604 ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, |
1601 ngx_str_t **params) | 1605 ngx_str_t **params) |
1602 { | 1606 { |
1603 ngx_str_t *uri, *file, args; | 1607 ngx_str_t *uri, *file, args; |
1604 ngx_uint_t i; | 1608 ngx_uint_t flags; |
1605 | 1609 |
1606 uri = params[NGX_HTTP_SSI_INCLUDE_VIRTUAL]; | 1610 uri = params[NGX_HTTP_SSI_INCLUDE_VIRTUAL]; |
1607 file = params[NGX_HTTP_SSI_INCLUDE_FILE]; | 1611 file = params[NGX_HTTP_SSI_INCLUDE_FILE]; |
1608 | 1612 |
1609 if (uri && file) { | 1613 if (uri && file) { |
1629 return NGX_HTTP_SSI_ERROR; | 1633 return NGX_HTTP_SSI_ERROR; |
1630 } | 1634 } |
1631 | 1635 |
1632 args.len = 0; | 1636 args.len = 0; |
1633 args.data = NULL; | 1637 args.data = NULL; |
1634 | 1638 flags = 0; |
1635 if (params[NGX_HTTP_SSI_INCLUDE_VIRTUAL]) { | 1639 |
1636 for (i = 0; i < uri->len; i++) { | 1640 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1637 if (uri->data[i] == '?') { | 1641 "ssi include: \"%V\"", uri); |
1638 args.len = uri->len - i - 1; | 1642 |
1639 args.data = &uri->data[i + 1]; | 1643 if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) { |
1640 uri->len -= args.len + 1; | 1644 return NGX_HTTP_SSI_ERROR; |
1641 | 1645 } |
1642 break; | 1646 |
1643 } | 1647 if (ngx_http_subrequest(r, uri, &args, flags) != NGX_OK) { |
1644 } | |
1645 } | |
1646 | |
1647 if (ngx_http_subrequest(r, uri, &args) != NGX_OK) { | |
1648 return NGX_HTTP_SSI_ERROR; | 1648 return NGX_HTTP_SSI_ERROR; |
1649 } | 1649 } |
1650 | 1650 |
1651 return NGX_OK; | 1651 return NGX_OK; |
1652 } | 1652 } |
1656 ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, | 1656 ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, |
1657 ngx_str_t **params) | 1657 ngx_str_t **params) |
1658 { | 1658 { |
1659 ngx_uint_t i; | 1659 ngx_uint_t i; |
1660 ngx_buf_t *b; | 1660 ngx_buf_t *b; |
1661 ngx_str_t *var, *value; | 1661 ngx_str_t *var, *value, text; |
1662 ngx_chain_t *cl; | 1662 ngx_chain_t *cl; |
1663 ngx_http_variable_value_t *vv; | 1663 ngx_http_variable_value_t *vv; |
1664 | 1664 |
1665 var = params[NGX_HTTP_SSI_ECHO_VAR]; | 1665 var = params[NGX_HTTP_SSI_ECHO_VAR]; |
1666 | 1666 |
1675 | 1675 |
1676 if (vv == NULL) { | 1676 if (vv == NULL) { |
1677 return NGX_HTTP_SSI_ERROR; | 1677 return NGX_HTTP_SSI_ERROR; |
1678 } | 1678 } |
1679 | 1679 |
1680 if (vv != NGX_HTTP_VAR_NOT_FOUND) { | 1680 if (!vv->not_found) { |
1681 value = &vv->text; | 1681 text.data = vv->data; |
1682 text.len = vv->len; | |
1683 value = &text; | |
1682 } | 1684 } |
1683 } | 1685 } |
1684 | 1686 |
1685 if (value == NULL) { | 1687 if (value == NULL) { |
1686 value = params[NGX_HTTP_SSI_ECHO_DEFAULT]; | 1688 value = params[NGX_HTTP_SSI_ECHO_DEFAULT]; |
1815 continue; | 1817 continue; |
1816 } | 1818 } |
1817 | 1819 |
1818 if ((*p >= 'a' && *p <= 'z') | 1820 if ((*p >= 'a' && *p <= 'z') |
1819 || (*p >= '0' && *p <= '9') | 1821 || (*p >= '0' && *p <= '9') |
1820 || *p == '$' || *p == '{' || *p == '}' || *p == '_') | 1822 || *p == '$' || *p == '{' || *p == '}' || *p == '_' |
1823 || *p == '"' || *p == '\'') | |
1821 { | 1824 { |
1822 continue; | 1825 continue; |
1823 } | 1826 } |
1824 | 1827 |
1825 break; | 1828 break; |
1969 | 1972 |
1970 return NGX_OK; | 1973 return NGX_OK; |
1971 } | 1974 } |
1972 | 1975 |
1973 | 1976 |
1974 static ngx_http_variable_value_t * | 1977 static ngx_int_t |
1975 ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, uintptr_t gmt) | 1978 ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, |
1979 ngx_http_variable_value_t *v, uintptr_t gmt) | |
1976 { | 1980 { |
1977 ngx_http_ssi_ctx_t *ctx; | 1981 ngx_http_ssi_ctx_t *ctx; |
1978 ngx_http_variable_value_t *vv; | 1982 ngx_time_t *tp; |
1979 ngx_time_t *tp; | 1983 struct tm tm; |
1980 struct tm tm; | 1984 char buf[NGX_HTTP_SSI_DATE_LEN]; |
1981 char buf[NGX_HTTP_SSI_DATE_LEN]; | 1985 |
1982 | 1986 v->valid = 1; |
1983 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | 1987 v->no_cachable = 0; |
1984 if (vv == NULL) { | 1988 v->not_found = 0; |
1985 return NULL; | |
1986 } | |
1987 | 1989 |
1988 tp = ngx_timeofday(); | 1990 tp = ngx_timeofday(); |
1989 | 1991 |
1990 ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module); | 1992 ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module); |
1991 | 1993 |
1992 if (ctx->timefmt.len == sizeof("%s") - 1 | 1994 if (ctx->timefmt.len == sizeof("%s") - 1 |
1993 && ctx->timefmt.data[0] == '%' && ctx->timefmt.data[1] == 's') | 1995 && ctx->timefmt.data[0] == '%' && ctx->timefmt.data[1] == 's') |
1994 { | 1996 { |
1995 vv->value = tp->sec + (gmt ? 0 : tp->gmtoff); | 1997 v->data = ngx_palloc(r->pool, NGX_TIME_T_LEN); |
1996 | 1998 if (v->data == NULL) { |
1997 vv->text.data = ngx_palloc(r->pool, NGX_TIME_T_LEN); | 1999 return NGX_ERROR; |
1998 if (vv->text.data == NULL) { | 2000 } |
1999 return NULL; | 2001 |
2000 } | 2002 v->len = ngx_sprintf(v->data, "%T", tp->sec + (gmt ? 0 : tp->gmtoff)) |
2001 | 2003 - v->data; |
2002 vv->text.len = ngx_sprintf(vv->text.data, "%T", vv->value) | 2004 return NGX_OK; |
2003 - vv->text.data; | |
2004 return vv; | |
2005 } | 2005 } |
2006 | 2006 |
2007 if (gmt) { | 2007 if (gmt) { |
2008 ngx_libc_gmtime(tp->sec, &tm); | 2008 ngx_libc_gmtime(tp->sec, &tm); |
2009 } else { | 2009 } else { |
2010 ngx_libc_localtime(tp->sec, &tm); | 2010 ngx_libc_localtime(tp->sec, &tm); |
2011 } | 2011 } |
2012 | 2012 |
2013 vv->value = tp->sec + (gmt ? 0 : tp->gmtoff); | 2013 v->len = strftime(buf, NGX_HTTP_SSI_DATE_LEN, |
2014 | 2014 (char *) ctx->timefmt.data, &tm); |
2015 vv->text.len = strftime(buf, NGX_HTTP_SSI_DATE_LEN, | 2015 if (v->len == 0) { |
2016 (char *) ctx->timefmt.data, &tm); | 2016 return NGX_ERROR; |
2017 if (vv->text.len == 0) { | 2017 } |
2018 return NULL; | 2018 |
2019 } | 2019 v->data = ngx_palloc(r->pool, v->len); |
2020 | 2020 if (v->data == NULL) { |
2021 vv->text.data = ngx_palloc(r->pool, vv->text.len); | 2021 return NGX_ERROR; |
2022 if (vv->text.data == NULL) { | 2022 } |
2023 return NULL; | 2023 |
2024 } | 2024 ngx_memcpy(v->data, buf, v->len); |
2025 | 2025 |
2026 ngx_memcpy(vv->text.data, buf, vv->text.len); | 2026 return NGX_OK; |
2027 | |
2028 return vv; | |
2029 } | 2027 } |
2030 | 2028 |
2031 | 2029 |
2032 static char * | 2030 static char * |
2033 ngx_http_ssi_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 2031 ngx_http_ssi_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |