Mercurial > hg > nginx-vendor-current
comparison src/http/ngx_http_variables.c @ 546:e19e5f542878 NGINX_0_8_25
nginx 0.8.25
*) Change: now no message is written in an error log if a variable is
not found by $r->variable() method.
*) Feature: the ngx_http_degradation_module.
*) Feature: regular expression named captures.
*) Feature: now URI part is not required a "proxy_pass" directive if
variables are used.
*) Feature: now the "msie_padding" directive works for Chrome too.
*) Bugfix: a segmentation fault occurred in a worker process on low
memory condition; the bug had appeared in 0.8.18.
*) Bugfix: nginx sent gzipped responses to clients those do not support
gzip, if "gzip_static on" and "gzip_vary off"; the bug had appeared
in 0.8.16.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 16 Nov 2009 00:00:00 +0300 |
parents | c04fa65fe604 |
children | ab7d265273ed |
comparison
equal
deleted
inserted
replaced
545:91e4b06e1a01 | 546:e19e5f542878 |
---|---|
1664 | 1664 |
1665 return NGX_OK; | 1665 return NGX_OK; |
1666 } | 1666 } |
1667 | 1667 |
1668 | 1668 |
1669 static ngx_int_t | |
1670 ngx_http_variable_not_found(ngx_http_request_t *r, ngx_http_variable_value_t *v, | |
1671 uintptr_t data) | |
1672 { | |
1673 v->not_found = 1; | |
1674 return NGX_OK; | |
1675 } | |
1676 | |
1677 | |
1678 ngx_http_regex_t * | |
1679 ngx_http_regex_compile(ngx_conf_t *cf, ngx_regex_compile_t *rc) | |
1680 { | |
1681 u_char *p; | |
1682 size_t size; | |
1683 ngx_str_t name; | |
1684 ngx_uint_t i, n; | |
1685 ngx_http_variable_t *v; | |
1686 ngx_http_regex_t *re; | |
1687 ngx_http_regex_variable_t *rv; | |
1688 ngx_http_core_main_conf_t *cmcf; | |
1689 | |
1690 rc->pool = cf->pool; | |
1691 | |
1692 if (ngx_regex_compile(rc) != NGX_OK) { | |
1693 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc->err); | |
1694 return NULL; | |
1695 } | |
1696 | |
1697 re = ngx_pcalloc(cf->pool, sizeof(ngx_http_regex_t)); | |
1698 if (re == NULL) { | |
1699 return NULL; | |
1700 } | |
1701 | |
1702 re->regex = rc->regex; | |
1703 re->ncaptures = rc->captures; | |
1704 | |
1705 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | |
1706 cmcf->ncaptures = ngx_max(cmcf->ncaptures, re->ncaptures); | |
1707 | |
1708 n = (ngx_uint_t) rc->named_captures; | |
1709 | |
1710 if (n == 0) { | |
1711 return re; | |
1712 } | |
1713 | |
1714 rv = ngx_palloc(rc->pool, n * sizeof(ngx_http_regex_variable_t)); | |
1715 if (rv == NULL) { | |
1716 return NULL; | |
1717 } | |
1718 | |
1719 re->variables = rv; | |
1720 re->nvariables = n; | |
1721 re->name = rc->pattern; | |
1722 | |
1723 size = rc->name_size; | |
1724 p = rc->names; | |
1725 | |
1726 for (i = 0; i < n; i++) { | |
1727 rv[i].capture = 2 * ((p[0] << 8) + p[1]); | |
1728 | |
1729 name.data = &p[2]; | |
1730 name.len = ngx_strlen(name.data); | |
1731 | |
1732 v = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE); | |
1733 if (v == NULL) { | |
1734 return NULL; | |
1735 } | |
1736 | |
1737 rv[i].index = ngx_http_get_variable_index(cf, &name); | |
1738 if (rv[i].index == NGX_ERROR) { | |
1739 return NULL; | |
1740 } | |
1741 | |
1742 v->get_handler = ngx_http_variable_not_found; | |
1743 | |
1744 p += i + size; | |
1745 } | |
1746 | |
1747 return re; | |
1748 } | |
1749 | |
1750 | |
1751 ngx_int_t | |
1752 ngx_http_regex_exec(ngx_http_request_t *r, ngx_http_regex_t *re, ngx_str_t *s) | |
1753 { | |
1754 ngx_int_t rc, index; | |
1755 ngx_uint_t i, n, len; | |
1756 ngx_http_variable_value_t *vv; | |
1757 ngx_http_core_main_conf_t *cmcf; | |
1758 | |
1759 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | |
1760 | |
1761 if (re->ncaptures) { | |
1762 len = (cmcf->ncaptures + 1) * 3; | |
1763 | |
1764 if (r->captures == NULL) { | |
1765 r->captures = ngx_palloc(r->pool, len * sizeof(int)); | |
1766 if (r->captures == NULL) { | |
1767 return NGX_ERROR; | |
1768 } | |
1769 } | |
1770 | |
1771 } else { | |
1772 len = 0; | |
1773 } | |
1774 | |
1775 rc = ngx_regex_exec(re->regex, s, r->captures, len); | |
1776 | |
1777 if (rc == NGX_REGEX_NO_MATCHED) { | |
1778 return NGX_DECLINED; | |
1779 } | |
1780 | |
1781 if (rc < 0) { | |
1782 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | |
1783 ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"", | |
1784 rc, s, &re->name); | |
1785 return NGX_ERROR; | |
1786 } | |
1787 | |
1788 for (i = 0; i < re->nvariables; i++) { | |
1789 | |
1790 n = re->variables[i].capture; | |
1791 index = re->variables[i].index; | |
1792 vv = &r->variables[index]; | |
1793 | |
1794 vv->len = r->captures[n + 1] - r->captures[n]; | |
1795 vv->valid = 1; | |
1796 vv->no_cacheable = 0; | |
1797 vv->not_found = 0; | |
1798 vv->data = &s->data[r->captures[n]]; | |
1799 | |
1800 #if (NGX_DEBUG) | |
1801 { | |
1802 ngx_http_variable_t *v; | |
1803 | |
1804 v = cmcf->variables.elts; | |
1805 | |
1806 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1807 "http regex set $%V to \"%*s\"", | |
1808 &v[index].name, vv->len, vv->data); | |
1809 } | |
1810 #endif | |
1811 } | |
1812 | |
1813 r->ncaptures = len; | |
1814 r->captures_data = s->data; | |
1815 | |
1816 return NGX_OK; | |
1817 } | |
1818 | |
1819 | |
1669 ngx_int_t | 1820 ngx_int_t |
1670 ngx_http_variables_add_core_vars(ngx_conf_t *cf) | 1821 ngx_http_variables_add_core_vars(ngx_conf_t *cf) |
1671 { | 1822 { |
1672 ngx_int_t rc; | 1823 ngx_int_t rc; |
1673 ngx_http_variable_t *v; | 1824 ngx_http_variable_t *v; |