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;