Mercurial > hg > nginx-ranges
comparison src/http/ngx_http_variables.c @ 578:f3a9e57d2e17
Merge with current.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 11 Mar 2010 21:27:17 +0300 |
parents | da3c99095432 |
children | 566e105a89f1 |
comparison
equal
deleted
inserted
replaced
539:5f4de8cf0d9d | 578:f3a9e57d2e17 |
---|---|
12 | 12 |
13 static ngx_int_t ngx_http_variable_request(ngx_http_request_t *r, | 13 static ngx_int_t ngx_http_variable_request(ngx_http_request_t *r, |
14 ngx_http_variable_value_t *v, uintptr_t data); | 14 ngx_http_variable_value_t *v, uintptr_t data); |
15 static void ngx_http_variable_request_set(ngx_http_request_t *r, | 15 static void ngx_http_variable_request_set(ngx_http_request_t *r, |
16 ngx_http_variable_value_t *v, uintptr_t data); | 16 ngx_http_variable_value_t *v, uintptr_t data); |
17 static ngx_int_t ngx_http_variable_request_get_size(ngx_http_request_t *r, | |
18 ngx_http_variable_value_t *v, uintptr_t data); | |
17 static void ngx_http_variable_request_set_size(ngx_http_request_t *r, | 19 static void ngx_http_variable_request_set_size(ngx_http_request_t *r, |
18 ngx_http_variable_value_t *v, uintptr_t data); | 20 ngx_http_variable_value_t *v, uintptr_t data); |
19 static ngx_int_t ngx_http_variable_header(ngx_http_request_t *r, | 21 static ngx_int_t ngx_http_variable_header(ngx_http_request_t *r, |
20 ngx_http_variable_value_t *v, uintptr_t data); | 22 ngx_http_variable_value_t *v, uintptr_t data); |
21 static ngx_int_t ngx_http_variable_headers(ngx_http_request_t *r, | 23 static ngx_int_t ngx_http_variable_headers(ngx_http_request_t *r, |
22 ngx_http_variable_value_t *v, uintptr_t data); | 24 ngx_http_variable_value_t *v, uintptr_t data); |
23 | 25 |
24 static ngx_int_t ngx_http_variable_unknown_header_in(ngx_http_request_t *r, | 26 static ngx_int_t ngx_http_variable_unknown_header_in(ngx_http_request_t *r, |
25 ngx_http_variable_value_t *v, uintptr_t data); | 27 ngx_http_variable_value_t *v, uintptr_t data); |
26 static ngx_int_t ngx_http_variable_unknown_header_out(ngx_http_request_t *r, | 28 static ngx_int_t ngx_http_variable_unknown_header_out(ngx_http_request_t *r, |
29 ngx_http_variable_value_t *v, uintptr_t data); | |
30 static ngx_int_t ngx_http_variable_request_line(ngx_http_request_t *r, | |
27 ngx_http_variable_value_t *v, uintptr_t data); | 31 ngx_http_variable_value_t *v, uintptr_t data); |
28 static ngx_int_t ngx_http_variable_cookie(ngx_http_request_t *r, | 32 static ngx_int_t ngx_http_variable_cookie(ngx_http_request_t *r, |
29 ngx_http_variable_value_t *v, uintptr_t data); | 33 ngx_http_variable_value_t *v, uintptr_t data); |
30 static ngx_int_t ngx_http_variable_argument(ngx_http_request_t *r, | 34 static ngx_int_t ngx_http_variable_argument(ngx_http_request_t *r, |
31 ngx_http_variable_value_t *v, uintptr_t data); | 35 ngx_http_variable_value_t *v, uintptr_t data); |
162 | 166 |
163 { ngx_string("document_uri"), NULL, ngx_http_variable_request, | 167 { ngx_string("document_uri"), NULL, ngx_http_variable_request, |
164 offsetof(ngx_http_request_t, uri), | 168 offsetof(ngx_http_request_t, uri), |
165 NGX_HTTP_VAR_NOCACHEABLE, 0 }, | 169 NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
166 | 170 |
167 { ngx_string("request"), NULL, ngx_http_variable_request, | 171 { ngx_string("request"), NULL, ngx_http_variable_request_line, 0, 0, 0 }, |
168 offsetof(ngx_http_request_t, request_line), 0, 0 }, | |
169 | 172 |
170 { ngx_string("document_root"), NULL, | 173 { ngx_string("document_root"), NULL, |
171 ngx_http_variable_document_root, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, | 174 ngx_http_variable_document_root, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
172 | 175 |
173 { ngx_string("realpath_root"), NULL, | 176 { ngx_string("realpath_root"), NULL, |
191 NGX_HTTP_VAR_NOCACHEABLE, 0 }, | 194 NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
192 | 195 |
193 { ngx_string("server_name"), NULL, ngx_http_variable_server_name, 0, 0, 0 }, | 196 { ngx_string("server_name"), NULL, ngx_http_variable_server_name, 0, 0, 0 }, |
194 | 197 |
195 { ngx_string("request_method"), NULL, | 198 { ngx_string("request_method"), NULL, |
196 ngx_http_variable_request_method, 0, 0, 0 }, | 199 ngx_http_variable_request_method, 0, |
200 NGX_HTTP_VAR_NOCACHEABLE, 0 }, | |
197 | 201 |
198 { ngx_string("remote_user"), NULL, ngx_http_variable_remote_user, 0, 0, 0 }, | 202 { ngx_string("remote_user"), NULL, ngx_http_variable_remote_user, 0, 0, 0 }, |
199 | 203 |
200 { ngx_string("body_bytes_sent"), NULL, ngx_http_variable_body_bytes_sent, | 204 { ngx_string("body_bytes_sent"), NULL, ngx_http_variable_body_bytes_sent, |
201 0, 0, 0 }, | 205 0, 0, 0 }, |
235 | 239 |
236 { ngx_string("sent_http_cache_control"), NULL, ngx_http_variable_headers, | 240 { ngx_string("sent_http_cache_control"), NULL, ngx_http_variable_headers, |
237 offsetof(ngx_http_request_t, headers_out.cache_control), 0, 0 }, | 241 offsetof(ngx_http_request_t, headers_out.cache_control), 0, 0 }, |
238 | 242 |
239 { ngx_string("limit_rate"), ngx_http_variable_request_set_size, | 243 { ngx_string("limit_rate"), ngx_http_variable_request_set_size, |
240 ngx_http_variable_request, | 244 ngx_http_variable_request_get_size, |
241 offsetof(ngx_http_request_t, limit_rate), | 245 offsetof(ngx_http_request_t, limit_rate), |
242 NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 }, | 246 NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
243 | 247 |
244 { ngx_string("nginx_version"), NULL, ngx_http_variable_nginx_version, | 248 { ngx_string("nginx_version"), NULL, ngx_http_variable_nginx_version, |
245 0, 0, 0 }, | 249 0, 0, 0 }, |
489 } | 493 } |
490 | 494 |
491 return NULL; | 495 return NULL; |
492 } | 496 } |
493 | 497 |
494 if (ngx_strncmp(name->data, "upstream_http_", 10) == 0) { | 498 if (ngx_strncmp(name->data, "upstream_http_", 14) == 0) { |
495 | 499 |
496 if (ngx_http_upstream_header_variable(r, vv, (uintptr_t) name) | 500 if (ngx_http_upstream_header_variable(r, vv, (uintptr_t) name) |
497 == NGX_OK) | 501 == NGX_OK) |
498 { | 502 { |
499 return vv; | 503 return vv; |
565 s->len = v->len; | 569 s->len = v->len; |
566 s->data = v->data; | 570 s->data = v->data; |
567 } | 571 } |
568 | 572 |
569 | 573 |
574 static ngx_int_t | |
575 ngx_http_variable_request_get_size(ngx_http_request_t *r, | |
576 ngx_http_variable_value_t *v, uintptr_t data) | |
577 { | |
578 size_t *sp; | |
579 | |
580 sp = (size_t *) ((char *) r + data); | |
581 | |
582 v->data = ngx_pnalloc(r->pool, NGX_SIZE_T_LEN); | |
583 if (v->data == NULL) { | |
584 return NGX_ERROR; | |
585 } | |
586 | |
587 v->len = ngx_sprintf(v->data, "%uz", *sp) - v->data; | |
588 v->valid = 1; | |
589 v->no_cacheable = 0; | |
590 v->not_found = 0; | |
591 | |
592 return NGX_OK; | |
593 } | |
594 | |
595 | |
570 static void | 596 static void |
571 ngx_http_variable_request_set_size(ngx_http_request_t *r, | 597 ngx_http_variable_request_set_size(ngx_http_request_t *r, |
572 ngx_http_variable_value_t *v, uintptr_t data) | 598 ngx_http_variable_value_t *v, uintptr_t data) |
573 { | 599 { |
574 ssize_t s, *sp; | 600 ssize_t s, *sp; |
749 return NGX_OK; | 775 return NGX_OK; |
750 } | 776 } |
751 | 777 |
752 | 778 |
753 static ngx_int_t | 779 static ngx_int_t |
780 ngx_http_variable_request_line(ngx_http_request_t *r, | |
781 ngx_http_variable_value_t *v, uintptr_t data) | |
782 { | |
783 u_char *p, *s; | |
784 | |
785 s = r->request_line.data; | |
786 | |
787 if (s == NULL) { | |
788 s = r->request_start; | |
789 | |
790 if (s == NULL) { | |
791 v->not_found = 1; | |
792 return NGX_OK; | |
793 } | |
794 | |
795 for (p = s; p < r->header_in->last; p++) { | |
796 if (*p == CR || *p == LF) { | |
797 break; | |
798 } | |
799 } | |
800 | |
801 r->request_line.len = p - s; | |
802 r->request_line.data = s; | |
803 } | |
804 | |
805 v->len = r->request_line.len; | |
806 v->valid = 1; | |
807 v->no_cacheable = 0; | |
808 v->not_found = 0; | |
809 v->data = s; | |
810 | |
811 return NGX_OK; | |
812 } | |
813 | |
814 | |
815 static ngx_int_t | |
754 ngx_http_variable_cookie(ngx_http_request_t *r, ngx_http_variable_value_t *v, | 816 ngx_http_variable_cookie(ngx_http_request_t *r, ngx_http_variable_value_t *v, |
755 uintptr_t data) | 817 uintptr_t data) |
756 { | 818 { |
757 ngx_str_t *name = (ngx_str_t *) data; | 819 ngx_str_t *name = (ngx_str_t *) data; |
758 | 820 |
848 | 910 |
849 v->len = sizeof(struct in6_addr); | 911 v->len = sizeof(struct in6_addr); |
850 v->valid = 1; | 912 v->valid = 1; |
851 v->no_cacheable = 0; | 913 v->no_cacheable = 0; |
852 v->not_found = 0; | 914 v->not_found = 0; |
853 v->data = (u_char *) &sin6->sin6_addr; | 915 v->data = sin6->sin6_addr.s6_addr; |
854 | 916 |
855 break; | 917 break; |
856 #endif | 918 #endif |
857 | 919 |
858 default: /* AF_INET */ | 920 default: /* AF_INET */ |
1601 v->not_found = 0; | 1663 v->not_found = 0; |
1602 v->data = p; | 1664 v->data = p; |
1603 | 1665 |
1604 return NGX_OK; | 1666 return NGX_OK; |
1605 } | 1667 } |
1668 | |
1669 | |
1670 #if (NGX_PCRE) | |
1671 | |
1672 static ngx_int_t | |
1673 ngx_http_variable_not_found(ngx_http_request_t *r, ngx_http_variable_value_t *v, | |
1674 uintptr_t data) | |
1675 { | |
1676 v->not_found = 1; | |
1677 return NGX_OK; | |
1678 } | |
1679 | |
1680 | |
1681 ngx_http_regex_t * | |
1682 ngx_http_regex_compile(ngx_conf_t *cf, ngx_regex_compile_t *rc) | |
1683 { | |
1684 u_char *p; | |
1685 size_t size; | |
1686 ngx_str_t name; | |
1687 ngx_uint_t i, n; | |
1688 ngx_http_variable_t *v; | |
1689 ngx_http_regex_t *re; | |
1690 ngx_http_regex_variable_t *rv; | |
1691 ngx_http_core_main_conf_t *cmcf; | |
1692 | |
1693 rc->pool = cf->pool; | |
1694 | |
1695 if (ngx_regex_compile(rc) != NGX_OK) { | |
1696 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc->err); | |
1697 return NULL; | |
1698 } | |
1699 | |
1700 re = ngx_pcalloc(cf->pool, sizeof(ngx_http_regex_t)); | |
1701 if (re == NULL) { | |
1702 return NULL; | |
1703 } | |
1704 | |
1705 re->regex = rc->regex; | |
1706 re->ncaptures = rc->captures; | |
1707 | |
1708 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | |
1709 cmcf->ncaptures = ngx_max(cmcf->ncaptures, re->ncaptures); | |
1710 | |
1711 n = (ngx_uint_t) rc->named_captures; | |
1712 | |
1713 if (n == 0) { | |
1714 return re; | |
1715 } | |
1716 | |
1717 rv = ngx_palloc(rc->pool, n * sizeof(ngx_http_regex_variable_t)); | |
1718 if (rv == NULL) { | |
1719 return NULL; | |
1720 } | |
1721 | |
1722 re->variables = rv; | |
1723 re->nvariables = n; | |
1724 re->name = rc->pattern; | |
1725 | |
1726 size = rc->name_size; | |
1727 p = rc->names; | |
1728 | |
1729 for (i = 0; i < n; i++) { | |
1730 rv[i].capture = 2 * ((p[0] << 8) + p[1]); | |
1731 | |
1732 name.data = &p[2]; | |
1733 name.len = ngx_strlen(name.data); | |
1734 | |
1735 v = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE); | |
1736 if (v == NULL) { | |
1737 return NULL; | |
1738 } | |
1739 | |
1740 rv[i].index = ngx_http_get_variable_index(cf, &name); | |
1741 if (rv[i].index == NGX_ERROR) { | |
1742 return NULL; | |
1743 } | |
1744 | |
1745 v->get_handler = ngx_http_variable_not_found; | |
1746 | |
1747 p += size; | |
1748 } | |
1749 | |
1750 return re; | |
1751 } | |
1752 | |
1753 | |
1754 ngx_int_t | |
1755 ngx_http_regex_exec(ngx_http_request_t *r, ngx_http_regex_t *re, ngx_str_t *s) | |
1756 { | |
1757 ngx_int_t rc, index; | |
1758 ngx_uint_t i, n, len; | |
1759 ngx_http_variable_value_t *vv; | |
1760 ngx_http_core_main_conf_t *cmcf; | |
1761 | |
1762 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | |
1763 | |
1764 if (re->ncaptures) { | |
1765 len = cmcf->ncaptures; | |
1766 | |
1767 if (r->captures == NULL) { | |
1768 r->captures = ngx_palloc(r->pool, len * sizeof(int)); | |
1769 if (r->captures == NULL) { | |
1770 return NGX_ERROR; | |
1771 } | |
1772 } | |
1773 | |
1774 } else { | |
1775 len = 0; | |
1776 } | |
1777 | |
1778 rc = ngx_regex_exec(re->regex, s, r->captures, len); | |
1779 | |
1780 if (rc == NGX_REGEX_NO_MATCHED) { | |
1781 return NGX_DECLINED; | |
1782 } | |
1783 | |
1784 if (rc < 0) { | |
1785 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | |
1786 ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"", | |
1787 rc, s, &re->name); | |
1788 return NGX_ERROR; | |
1789 } | |
1790 | |
1791 for (i = 0; i < re->nvariables; i++) { | |
1792 | |
1793 n = re->variables[i].capture; | |
1794 index = re->variables[i].index; | |
1795 vv = &r->variables[index]; | |
1796 | |
1797 vv->len = r->captures[n + 1] - r->captures[n]; | |
1798 vv->valid = 1; | |
1799 vv->no_cacheable = 0; | |
1800 vv->not_found = 0; | |
1801 vv->data = &s->data[r->captures[n]]; | |
1802 | |
1803 #if (NGX_DEBUG) | |
1804 { | |
1805 ngx_http_variable_t *v; | |
1806 | |
1807 v = cmcf->variables.elts; | |
1808 | |
1809 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1810 "http regex set $%V to \"%*s\"", | |
1811 &v[index].name, vv->len, vv->data); | |
1812 } | |
1813 #endif | |
1814 } | |
1815 | |
1816 r->ncaptures = rc * 2; | |
1817 r->captures_data = s->data; | |
1818 | |
1819 return NGX_OK; | |
1820 } | |
1821 | |
1822 #endif | |
1606 | 1823 |
1607 | 1824 |
1608 ngx_int_t | 1825 ngx_int_t |
1609 ngx_http_variables_add_core_vars(ngx_conf_t *cf) | 1826 ngx_http_variables_add_core_vars(ngx_conf_t *cf) |
1610 { | 1827 { |