Mercurial > hg > nginx-vendor-0-5
comparison src/http/ngx_http_core_module.c @ 322:56675f002600 NGINX_0_5_31
nginx 0.5.31
*) Feature: named locations.
*) Feature: the "proxy_store" and "fastcgi_store" directives.
*) Feature: the "proxy_store_access" and "fastcgi_store_access"
directives.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Wed, 15 Aug 2007 00:00:00 +0400 |
parents | 95d92ec39071 |
children | 7cf404023f50 |
comparison
equal
deleted
inserted
replaced
321:6762c33c7da8 | 322:56675f002600 |
---|---|
931 static ngx_int_t | 931 static ngx_int_t |
932 ngx_http_core_find_location(ngx_http_request_t *r, | 932 ngx_http_core_find_location(ngx_http_request_t *r, |
933 ngx_array_t *locations, ngx_uint_t regex_start, size_t len) | 933 ngx_array_t *locations, ngx_uint_t regex_start, size_t len) |
934 { | 934 { |
935 ngx_int_t n, rc; | 935 ngx_int_t n, rc; |
936 ngx_uint_t i, found, noregex; | 936 ngx_uint_t i, found; |
937 ngx_http_core_loc_conf_t *clcf, **clcfp; | 937 ngx_http_core_loc_conf_t *clcf, **clcfp; |
938 #if (NGX_PCRE) | |
939 ngx_uint_t noregex; | |
940 #endif | |
938 | 941 |
939 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 942 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
940 "find location for \"%V\"", &r->uri); | 943 "find location for \"%V\"", &r->uri); |
941 | 944 |
942 found = 0; | 945 found = 0; |
946 #if (NGX_PCRE) | |
943 noregex = 0; | 947 noregex = 0; |
948 #endif | |
944 | 949 |
945 clcfp = locations->elts; | 950 clcfp = locations->elts; |
946 for (i = 0; i < locations->nelts; i++) { | 951 for (i = 0; i < locations->nelts; i++) { |
947 | 952 |
953 if (clcfp[i]->noname | |
948 #if (NGX_PCRE) | 954 #if (NGX_PCRE) |
949 if (clcfp[i]->regex) { | 955 || clcfp[i]->regex |
950 break; | |
951 } | |
952 #endif | 956 #endif |
953 | 957 || clcfp[i]->named) |
954 if (clcfp[i]->noname) { | 958 { |
955 break; | 959 break; |
956 } | 960 } |
957 | 961 |
958 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 962 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
959 "find location: %s\"%V\"", | 963 "find location: %s\"%V\"", |
997 if (len > clcfp[i]->name.len) { | 1001 if (len > clcfp[i]->name.len) { |
998 /* the previous match is longer */ | 1002 /* the previous match is longer */ |
999 break; | 1003 break; |
1000 } | 1004 } |
1001 | 1005 |
1006 found = 1; | |
1007 | |
1002 r->loc_conf = clcfp[i]->loc_conf; | 1008 r->loc_conf = clcfp[i]->loc_conf; |
1009 #if (NGX_PCRE) | |
1003 noregex = clcfp[i]->noregex; | 1010 noregex = clcfp[i]->noregex; |
1004 found = 1; | 1011 #endif |
1005 } | 1012 } |
1006 } | 1013 } |
1007 | 1014 |
1008 if (found) { | 1015 if (found) { |
1009 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 1016 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
1026 | 1033 |
1027 /* regex matches */ | 1034 /* regex matches */ |
1028 | 1035 |
1029 for (i = regex_start; i < locations->nelts; i++) { | 1036 for (i = regex_start; i < locations->nelts; i++) { |
1030 | 1037 |
1031 if (clcfp[i]->noname) { | 1038 if (!clcfp[i]->regex) { |
1032 break; | 1039 break; |
1033 } | 1040 } |
1034 | 1041 |
1035 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 1042 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1036 "find location: ~ \"%V\"", &clcfp[i]->name); | 1043 "find location: ~ \"%V\"", &clcfp[i]->name); |
1511 | 1518 |
1512 return NGX_DONE; | 1519 return NGX_DONE; |
1513 } | 1520 } |
1514 | 1521 |
1515 | 1522 |
1523 ngx_int_t | |
1524 ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name) | |
1525 { | |
1526 ngx_uint_t i; | |
1527 ngx_http_core_srv_conf_t *cscf; | |
1528 ngx_http_core_loc_conf_t **clcfp; | |
1529 ngx_http_core_main_conf_t *cmcf; | |
1530 | |
1531 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); | |
1532 | |
1533 clcfp = cscf->locations.elts; | |
1534 | |
1535 for (i = cscf->named_start; i < cscf->locations.nelts; i++) { | |
1536 | |
1537 if (name->len != clcfp[i]->name.len | |
1538 || ngx_strncmp(name->data, clcfp[i]->name.data, name->len) != 0) | |
1539 { | |
1540 continue; | |
1541 } | |
1542 | |
1543 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1544 "named location: %V \"%V?%V\"", name, &r->uri, &r->args); | |
1545 | |
1546 r->internal = 1; | |
1547 | |
1548 r->loc_conf = clcfp[i]->loc_conf; | |
1549 | |
1550 ngx_http_update_location_config(r); | |
1551 | |
1552 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | |
1553 | |
1554 r->phase_handler = cmcf->phase_engine.location_rewrite_index; | |
1555 ngx_http_core_run_phases(r); | |
1556 | |
1557 return NGX_DONE; | |
1558 } | |
1559 | |
1560 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
1561 "could not find name location \"%V\"", name); | |
1562 | |
1563 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1564 return NGX_DONE; | |
1565 } | |
1566 | |
1567 | |
1516 ngx_http_cleanup_t * | 1568 ngx_http_cleanup_t * |
1517 ngx_http_cleanup_add(ngx_http_request_t *r, size_t size) | 1569 ngx_http_cleanup_add(ngx_http_request_t *r, size_t size) |
1518 { | 1570 { |
1519 ngx_http_cleanup_t *cln; | 1571 ngx_http_cleanup_t *cln; |
1520 | 1572 |
1555 ngx_uint_t i; | 1607 ngx_uint_t i; |
1556 ngx_conf_t pcf; | 1608 ngx_conf_t pcf; |
1557 ngx_http_module_t *module; | 1609 ngx_http_module_t *module; |
1558 ngx_http_conf_ctx_t *ctx, *http_ctx; | 1610 ngx_http_conf_ctx_t *ctx, *http_ctx; |
1559 ngx_http_core_srv_conf_t *cscf, **cscfp; | 1611 ngx_http_core_srv_conf_t *cscf, **cscfp; |
1612 ngx_http_core_loc_conf_t **clcfp; | |
1560 ngx_http_core_main_conf_t *cmcf; | 1613 ngx_http_core_main_conf_t *cmcf; |
1561 #if (NGX_PCRE) | |
1562 ngx_http_core_loc_conf_t **clcfp; | |
1563 #endif | |
1564 | 1614 |
1565 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)); | 1615 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)); |
1566 if (ctx == NULL) { | 1616 if (ctx == NULL) { |
1567 return NGX_CONF_ERROR; | 1617 return NGX_CONF_ERROR; |
1568 } | 1618 } |
1642 } | 1692 } |
1643 | 1693 |
1644 ngx_sort(cscf->locations.elts, (size_t) cscf->locations.nelts, | 1694 ngx_sort(cscf->locations.elts, (size_t) cscf->locations.nelts, |
1645 sizeof(ngx_http_core_loc_conf_t *), ngx_http_core_cmp_locations); | 1695 sizeof(ngx_http_core_loc_conf_t *), ngx_http_core_cmp_locations); |
1646 | 1696 |
1697 clcfp = cscf->locations.elts; | |
1698 | |
1647 #if (NGX_PCRE) | 1699 #if (NGX_PCRE) |
1648 | 1700 |
1649 cscf->regex_start = cscf->locations.nelts; | 1701 cscf->regex_start = cscf->locations.nelts; |
1650 clcfp = cscf->locations.elts; | |
1651 | 1702 |
1652 for (i = 0; i < cscf->locations.nelts; i++) { | 1703 for (i = 0; i < cscf->locations.nelts; i++) { |
1653 if (clcfp[i]->regex) { | 1704 if (clcfp[i]->regex) { |
1654 cscf->regex_start = i; | 1705 cscf->regex_start = i; |
1655 break; | 1706 break; |
1656 } | 1707 } |
1657 } | 1708 } |
1658 | 1709 |
1659 #endif | 1710 #endif |
1711 | |
1712 cscf->named_start = cscf->locations.nelts; | |
1713 | |
1714 for (i = 0; i < cscf->locations.nelts; i++) { | |
1715 if (clcfp[i]->named) { | |
1716 cscf->named_start = i; | |
1717 break; | |
1718 } | |
1719 } | |
1660 | 1720 |
1661 return rv; | 1721 return rv; |
1662 } | 1722 } |
1663 | 1723 |
1664 | 1724 |
1756 "invalid location modifier \"%V\"", &value[1]); | 1816 "invalid location modifier \"%V\"", &value[1]); |
1757 return NGX_CONF_ERROR; | 1817 return NGX_CONF_ERROR; |
1758 } | 1818 } |
1759 | 1819 |
1760 } else { | 1820 } else { |
1821 | |
1761 clcf->name = value[1]; | 1822 clcf->name = value[1]; |
1823 | |
1824 if (value[1].data[0] == '@') { | |
1825 clcf->named = 1; | |
1826 } | |
1762 } | 1827 } |
1763 | 1828 |
1764 pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index]; | 1829 pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index]; |
1765 | 1830 |
1766 if (pclcf->name.len == 0) { | 1831 if (pclcf->name.len == 0) { |
1778 | 1843 |
1779 if (pclcf->exact_match) { | 1844 if (pclcf->exact_match) { |
1780 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 1845 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
1781 "location \"%V\" could not be inside " | 1846 "location \"%V\" could not be inside " |
1782 "the exact location \"%V\"", | 1847 "the exact location \"%V\"", |
1848 &clcf->name, &pclcf->name); | |
1849 return NGX_CONF_ERROR; | |
1850 } | |
1851 | |
1852 if (pclcf->named) { | |
1853 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1854 "location \"%V\" could not be inside " | |
1855 "the named location \"%V\"", | |
1783 &clcf->name, &pclcf->name); | 1856 &clcf->name, &pclcf->name); |
1784 return NGX_CONF_ERROR; | 1857 return NGX_CONF_ERROR; |
1785 } | 1858 } |
1786 | 1859 |
1787 #if (NGX_PCRE) | 1860 #if (NGX_PCRE) |
1858 ngx_int_t rc; | 1931 ngx_int_t rc; |
1859 ngx_http_core_loc_conf_t *first, *second; | 1932 ngx_http_core_loc_conf_t *first, *second; |
1860 | 1933 |
1861 first = *(ngx_http_core_loc_conf_t **) one; | 1934 first = *(ngx_http_core_loc_conf_t **) one; |
1862 second = *(ngx_http_core_loc_conf_t **) two; | 1935 second = *(ngx_http_core_loc_conf_t **) two; |
1936 | |
1937 if (first->named && !second->named) { | |
1938 /* shift named locations to the end */ | |
1939 return 1; | |
1940 } | |
1941 | |
1942 if (!first->named && second->named) { | |
1943 /* shift named locations to the end */ | |
1944 return -1; | |
1945 } | |
1946 | |
1947 if (first->named && second->named) { | |
1948 return ngx_strcmp(first->name.data, second->name.data); | |
1949 } | |
1863 | 1950 |
1864 if (first->noname && !second->noname) { | 1951 if (first->noname && !second->noname) { |
1865 /* shift no named locations to the end */ | 1952 /* shift no named locations to the end */ |
1866 return 1; | 1953 return 1; |
1867 } | 1954 } |
2704 } | 2791 } |
2705 | 2792 |
2706 return NGX_CONF_ERROR; | 2793 return NGX_CONF_ERROR; |
2707 } | 2794 } |
2708 | 2795 |
2796 if (lcf->named && alias) { | |
2797 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
2798 "the \"alias\" directive may not be used " | |
2799 "inside named location"); | |
2800 | |
2801 return NGX_CONF_ERROR; | |
2802 } | |
2803 | |
2709 #if (NGX_PCRE) | 2804 #if (NGX_PCRE) |
2710 | 2805 |
2711 if (lcf->regex && alias) { | 2806 if (lcf->regex && alias) { |
2712 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 2807 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
2713 "the \"alias\" directive may not be used " | 2808 "the \"alias\" directive may not be used " |