comparison src/http/ngx_http_core_module.c @ 635:e67b227c8dbb default tip

Merge with current.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 25 Apr 2011 04:07:55 +0400
parents b4dcae568a2a
children
comparison
equal deleted inserted replaced
578:f3a9e57d2e17 635:e67b227c8dbb
131 { ngx_string("before"), NGX_HTTP_IMS_BEFORE }, 131 { ngx_string("before"), NGX_HTTP_IMS_BEFORE },
132 { ngx_null_string, 0 } 132 { ngx_null_string, 0 }
133 }; 133 };
134 134
135 135
136 static ngx_conf_enum_t ngx_http_core_keepalive_disable[] = {
137 { ngx_string("none"), NGX_HTTP_KEEPALIVE_DISABLE_NONE },
138 { ngx_string("msie6"), NGX_HTTP_KEEPALIVE_DISABLE_MSIE6 },
139 { ngx_string("safari"), NGX_HTTP_KEEPALIVE_DISABLE_SAFARI },
140 { ngx_null_string, 0 }
141 };
142
143
136 static ngx_path_init_t ngx_http_client_temp_path = { 144 static ngx_path_init_t ngx_http_client_temp_path = {
137 ngx_string(NGX_HTTP_CLIENT_TEMP_PATH), { 0, 0, 0 } 145 ngx_string(NGX_HTTP_CLIENT_TEMP_PATH), { 0, 0, 0 }
138 }; 146 };
139 147
140 148
492 ngx_conf_set_num_slot, 500 ngx_conf_set_num_slot,
493 NGX_HTTP_LOC_CONF_OFFSET, 501 NGX_HTTP_LOC_CONF_OFFSET,
494 offsetof(ngx_http_core_loc_conf_t, keepalive_requests), 502 offsetof(ngx_http_core_loc_conf_t, keepalive_requests),
495 NULL }, 503 NULL },
496 504
505 { ngx_string("keepalive_disable"),
506 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
507 ngx_conf_set_enum_slot,
508 NGX_HTTP_LOC_CONF_OFFSET,
509 offsetof(ngx_http_core_loc_conf_t, keepalive_disable),
510 &ngx_http_core_keepalive_disable },
511
497 { ngx_string("satisfy"), 512 { ngx_string("satisfy"),
498 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 513 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
499 ngx_conf_set_enum_slot, 514 ngx_conf_set_enum_slot,
500 NGX_HTTP_LOC_CONF_OFFSET, 515 NGX_HTTP_LOC_CONF_OFFSET,
501 offsetof(ngx_http_core_loc_conf_t, satisfy), 516 offsetof(ngx_http_core_loc_conf_t, satisfy),
596 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 611 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
597 ngx_conf_set_enum_slot, 612 ngx_conf_set_enum_slot,
598 NGX_HTTP_LOC_CONF_OFFSET, 613 NGX_HTTP_LOC_CONF_OFFSET,
599 offsetof(ngx_http_core_loc_conf_t, if_modified_since), 614 offsetof(ngx_http_core_loc_conf_t, if_modified_since),
600 &ngx_http_core_if_modified_since }, 615 &ngx_http_core_if_modified_since },
616
617 { ngx_string("chunked_transfer_encoding"),
618 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
619 ngx_conf_set_flag_slot,
620 NGX_HTTP_LOC_CONF_OFFSET,
621 offsetof(ngx_http_core_loc_conf_t, chunked_transfer_encoding),
622 NULL },
601 623
602 { ngx_string("error_page"), 624 { ngx_string("error_page"),
603 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF 625 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
604 |NGX_CONF_2MORE, 626 |NGX_CONF_2MORE,
605 ngx_http_core_error_page, 627 ngx_http_core_error_page,
765 r->connection->unexpected_eof = 0; 787 r->connection->unexpected_eof = 0;
766 788
767 if (!r->internal) { 789 if (!r->internal) {
768 switch (r->headers_in.connection_type) { 790 switch (r->headers_in.connection_type) {
769 case 0: 791 case 0:
770 if (r->http_version > NGX_HTTP_VERSION_10) { 792 r->keepalive = (r->http_version > NGX_HTTP_VERSION_10);
771 r->keepalive = 1;
772 } else {
773 r->keepalive = 0;
774 }
775 break; 793 break;
776 794
777 case NGX_HTTP_CONNECTION_CLOSE: 795 case NGX_HTTP_CONNECTION_CLOSE:
778 r->keepalive = 0; 796 r->keepalive = 0;
779 break; 797 break;
781 case NGX_HTTP_CONNECTION_KEEP_ALIVE: 799 case NGX_HTTP_CONNECTION_KEEP_ALIVE:
782 r->keepalive = 1; 800 r->keepalive = 1;
783 break; 801 break;
784 } 802 }
785 803
786 if (r->keepalive) { 804 r->lingering_close = (r->headers_in.content_length_n > 0);
787
788 if (r->headers_in.msie6) {
789 if (r->method == NGX_HTTP_POST) {
790 /*
791 * MSIE may wait for some time if an response for
792 * a POST request was sent over a keepalive connection
793 */
794 r->keepalive = 0;
795 }
796
797 } else if (r->headers_in.safari) {
798 /*
799 * Safari may send a POST request to a closed keepalive
800 * connection and stalls for some time
801 */
802 r->keepalive = 0;
803 }
804 }
805
806 if (r->headers_in.content_length_n > 0) {
807 r->lingering_close = 1;
808
809 } else {
810 r->lingering_close = 0;
811 }
812
813 r->phase_handler = 0; 805 r->phase_handler = 0;
814 806
815 } else { 807 } else {
816 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); 808 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
817 r->phase_handler = cmcf->phase_engine.server_rewrite_index; 809 r->phase_handler = cmcf->phase_engine.server_rewrite_index;
818 }
819
820 if (r->unparsed_uri.len) {
821 r->valid_unparsed_uri = 1;
822 } 810 }
823 811
824 r->valid_location = 1; 812 r->valid_location = 1;
825 #if (NGX_HTTP_GZIP) 813 #if (NGX_HTTP_GZIP)
826 r->gzip_tested = 0; 814 r->gzip_tested = 0;
860 { 848 {
861 ngx_int_t rc; 849 ngx_int_t rc;
862 850
863 /* 851 /*
864 * generic phase checker, 852 * generic phase checker,
865 * used by the post read, server rewrite, rewrite, and pre-access phases 853 * used by the post read and pre-access phases
866 */ 854 */
867 855
868 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 856 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
869 "generic phase: %ui", r->phase_handler); 857 "generic phase: %ui", r->phase_handler);
870 858
883 if (rc == NGX_AGAIN || rc == NGX_DONE) { 871 if (rc == NGX_AGAIN || rc == NGX_DONE) {
884 return NGX_OK; 872 return NGX_OK;
885 } 873 }
886 874
887 /* rc == NGX_ERROR || rc == NGX_HTTP_... */ 875 /* rc == NGX_ERROR || rc == NGX_HTTP_... */
876
877 ngx_http_finalize_request(r, rc);
878
879 return NGX_OK;
880 }
881
882
883 ngx_int_t
884 ngx_http_core_rewrite_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
885 {
886 ngx_int_t rc;
887
888 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
889 "rewrite phase: %ui", r->phase_handler);
890
891 rc = ph->handler(r);
892
893 if (rc == NGX_DECLINED) {
894 r->phase_handler++;
895 return NGX_AGAIN;
896 }
897
898 if (rc == NGX_DONE) {
899 return NGX_OK;
900 }
901
902 /* NGX_OK, NGX_AGAIN, NGX_ERROR, NGX_HTTP_... */
888 903
889 ngx_http_finalize_request(r, rc); 904 ngx_http_finalize_request(r, rc);
890 905
891 return NGX_OK; 906 return NGX_OK;
892 } 907 }
1091 1106
1092 ngx_int_t 1107 ngx_int_t
1093 ngx_http_core_post_access_phase(ngx_http_request_t *r, 1108 ngx_http_core_post_access_phase(ngx_http_request_t *r,
1094 ngx_http_phase_handler_t *ph) 1109 ngx_http_phase_handler_t *ph)
1095 { 1110 {
1111 ngx_int_t access_code;
1112
1096 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 1113 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1097 "post access phase: %ui", r->phase_handler); 1114 "post access phase: %ui", r->phase_handler);
1098 1115
1099 if (r->access_code) { 1116 access_code = r->access_code;
1100 1117
1101 if (r->access_code == NGX_HTTP_FORBIDDEN) { 1118 if (access_code) {
1119 if (access_code == NGX_HTTP_FORBIDDEN) {
1102 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 1120 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1103 "access forbidden by rule"); 1121 "access forbidden by rule");
1104 } 1122 }
1105 1123
1106 ngx_http_finalize_request(r, r->access_code); 1124 r->access_code = 0;
1125 ngx_http_finalize_request(r, access_code);
1107 return NGX_OK; 1126 return NGX_OK;
1108 } 1127 }
1109 1128
1110 r->phase_handler++; 1129 r->phase_handler++;
1111 return NGX_AGAIN; 1130 return NGX_AGAIN;
1143 /* suppress MSVC warning */ 1162 /* suppress MSVC warning */
1144 path.data = NULL; 1163 path.data = NULL;
1145 1164
1146 tf = clcf->try_files; 1165 tf = clcf->try_files;
1147 1166
1148 alias = clcf->alias ? clcf->name.len : 0; 1167 alias = clcf->alias;
1149 1168
1150 for ( ;; ) { 1169 for ( ;; ) {
1151 1170
1152 if (tf->lengths) { 1171 if (tf->lengths) {
1153 ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); 1172 ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
1204 path.len = e.pos - path.data; 1223 path.len = e.pos - path.data;
1205 1224
1206 *e.pos = '\0'; 1225 *e.pos = '\0';
1207 1226
1208 if (alias && ngx_strncmp(name, clcf->name.data, alias) == 0) { 1227 if (alias && ngx_strncmp(name, clcf->name.data, alias) == 0) {
1209 ngx_memcpy(name, name + alias, len - alias); 1228 ngx_memmove(name, name + alias, len - alias);
1210 path.len -= alias; 1229 path.len -= alias;
1211 } 1230 }
1212 } 1231 }
1213 1232
1214 test_dir = tf->test_dir; 1233 test_dir = tf->test_dir;
1215 1234
1216 tf++; 1235 tf++;
1217 1236
1218 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 1237 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1219 "try to use file: \"%s\" \"%s\"", name, path.data); 1238 "try to use %s: \"%s\" \"%s\"",
1239 test_dir ? "dir" : "file", name, path.data);
1220 1240
1221 if (tf->lengths == NULL && tf->name.len == 0) { 1241 if (tf->lengths == NULL && tf->name.len == 0) {
1222 1242
1223 if (tf->code) { 1243 if (tf->code) {
1224 ngx_http_finalize_request(r, tf->code); 1244 ngx_http_finalize_request(r, tf->code);
1272 path.data += root; 1292 path.data += root;
1273 1293
1274 if (!alias) { 1294 if (!alias) {
1275 r->uri = path; 1295 r->uri = path;
1276 1296
1297 #if (NGX_PCRE)
1298 } else if (clcf->regex) {
1299 if (!test_dir) {
1300 r->uri = path;
1301 r->add_uri_to_alias = 1;
1302 }
1303 #endif
1277 } else { 1304 } else {
1278 r->uri.len = alias + path.len; 1305 r->uri.len = alias + path.len;
1279 r->uri.data = ngx_pnalloc(r->pool, r->uri.len); 1306 r->uri.data = ngx_pnalloc(r->pool, r->uri.len);
1280 if (r->uri.data == NULL) { 1307 if (r->uri.data == NULL) {
1281 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 1308 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1332 return NGX_AGAIN; 1359 return NGX_AGAIN;
1333 } 1360 }
1334 1361
1335 /* no content handler was found */ 1362 /* no content handler was found */
1336 1363
1337 if (r->uri.data[r->uri.len - 1] == '/' && !r->zero_in_uri) { 1364 if (r->uri.data[r->uri.len - 1] == '/') {
1338 1365
1339 if (ngx_http_map_uri_to_path(r, &path, &root, 0) != NULL) { 1366 if (ngx_http_map_uri_to_path(r, &path, &root, 0) != NULL) {
1340 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 1367 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1341 "directory index of \"%s\" is forbidden", path.data); 1368 "directory index of \"%s\" is forbidden", path.data);
1342 } 1369 }
1395 if (r->keepalive) { 1422 if (r->keepalive) {
1396 if (clcf->keepalive_timeout == 0) { 1423 if (clcf->keepalive_timeout == 0) {
1397 r->keepalive = 0; 1424 r->keepalive = 0;
1398 1425
1399 } else if (r->connection->requests >= clcf->keepalive_requests) { 1426 } else if (r->connection->requests >= clcf->keepalive_requests) {
1427 r->keepalive = 0;
1428
1429 } else if (r->headers_in.msie6
1430 && r->method == NGX_HTTP_POST
1431 && (clcf->keepalive_disable
1432 & NGX_HTTP_KEEPALIVE_DISABLE_MSIE6))
1433 {
1434 /*
1435 * MSIE may wait for some time if an response for
1436 * a POST request was sent over a keepalive connection
1437 */
1438 r->keepalive = 0;
1439
1440 } else if (r->headers_in.safari
1441 && (clcf->keepalive_disable
1442 & NGX_HTTP_KEEPALIVE_DISABLE_SAFARI))
1443 {
1444 /*
1445 * Safari may send a POST request to a closed keepalive
1446 * connection and may stall for some time, see
1447 * https://bugs.webkit.org/show_bug.cgi?id=5760
1448 */
1400 r->keepalive = 0; 1449 r->keepalive = 0;
1401 } 1450 }
1402 } 1451 }
1403 1452
1404 if (!clcf->tcp_nopush) { 1453 if (!clcf->tcp_nopush) {
1554 continue; 1603 continue;
1555 } 1604 }
1556 1605
1557 if (len == (size_t) node->len) { 1606 if (len == (size_t) node->len) {
1558 1607
1559 r->loc_conf = (node->exact) ? node->exact->loc_conf: 1608 if (node->exact) {
1560 node->inclusive->loc_conf; 1609 r->loc_conf = node->exact->loc_conf;
1561 return NGX_OK; 1610 return NGX_OK;
1611
1612 } else {
1613 r->loc_conf = node->inclusive->loc_conf;
1614 return NGX_AGAIN;
1615 }
1562 } 1616 }
1563 1617
1564 /* len < node->len */ 1618 /* len < node->len */
1565 1619
1566 if (len + 1 == (size_t) node->len && node->auto_redirect) { 1620 if (len + 1 == (size_t) node->len && node->auto_redirect) {
1676 void 1730 void
1677 ngx_http_set_exten(ngx_http_request_t *r) 1731 ngx_http_set_exten(ngx_http_request_t *r)
1678 { 1732 {
1679 ngx_int_t i; 1733 ngx_int_t i;
1680 1734
1681 r->exten.len = 0; 1735 ngx_str_null(&r->exten);
1682 r->exten.data = NULL;
1683 1736
1684 for (i = r->uri.len - 1; i > 1; i--) { 1737 for (i = r->uri.len - 1; i > 1; i--) {
1685 if (r->uri.data[i] == '.' && r->uri.data[i - 1] != '/') { 1738 if (r->uri.data[i] == '.' && r->uri.data[i - 1] != '/') {
1686 1739
1687 r->exten.len = r->uri.len - i - 1; 1740 r->exten.len = r->uri.len - i - 1;
1693 return; 1746 return;
1694 } 1747 }
1695 } 1748 }
1696 1749
1697 return; 1750 return;
1751 }
1752
1753
1754 ngx_int_t
1755 ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
1756 ngx_str_t *ct, ngx_http_complex_value_t *cv)
1757 {
1758 ngx_int_t rc;
1759 ngx_str_t val;
1760 ngx_buf_t *b;
1761 ngx_chain_t out;
1762
1763 r->headers_out.status = status;
1764
1765 if (status == NGX_HTTP_NO_CONTENT) {
1766 r->header_only = 1;
1767 return ngx_http_send_header(r);
1768 }
1769
1770 if (ngx_http_complex_value(r, cv, &val) != NGX_OK) {
1771 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1772 }
1773
1774 if (status >= NGX_HTTP_MOVED_PERMANENTLY && status <= NGX_HTTP_SEE_OTHER) {
1775
1776 r->headers_out.location = ngx_list_push(&r->headers_out.headers);
1777 if (r->headers_out.location == NULL) {
1778 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1779 }
1780
1781 r->headers_out.location->hash = 1;
1782 ngx_str_set(&r->headers_out.location->key, "Location");
1783 r->headers_out.location->value = val;
1784
1785 return status;
1786 }
1787
1788 r->headers_out.content_length_n = val.len;
1789
1790 if (ct) {
1791 r->headers_out.content_type_len = ct->len;
1792 r->headers_out.content_type = *ct;
1793
1794 } else {
1795 if (ngx_http_set_content_type(r) != NGX_OK) {
1796 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1797 }
1798 }
1799
1800 if (r->method == NGX_HTTP_HEAD || (r != r->main && val.len == 0)) {
1801 return ngx_http_send_header(r);
1802 }
1803
1804 b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
1805 if (b == NULL) {
1806 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1807 }
1808
1809 b->pos = val.data;
1810 b->last = val.data + val.len;
1811 b->memory = val.len ? 1 : 0;
1812 b->last_buf = (r == r->main) ? 1 : 0;
1813 b->last_in_chain = 1;
1814
1815 out.buf = b;
1816 out.next = NULL;
1817
1818 rc = ngx_http_send_header(r);
1819
1820 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
1821 return rc;
1822 }
1823
1824 return ngx_http_output_filter(r, &out);
1698 } 1825 }
1699 1826
1700 1827
1701 ngx_int_t 1828 ngx_int_t
1702 ngx_http_send_header(ngx_http_request_t *r) 1829 ngx_http_send_header(ngx_http_request_t *r)
1740 size_t alias; 1867 size_t alias;
1741 ngx_http_core_loc_conf_t *clcf; 1868 ngx_http_core_loc_conf_t *clcf;
1742 1869
1743 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 1870 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1744 1871
1745 alias = clcf->alias ? clcf->name.len : 0; 1872 alias = clcf->alias;
1746 1873
1747 if (alias && !r->valid_location) { 1874 if (alias && !r->valid_location) {
1748 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, 1875 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1749 "\"alias\" could not be used in location \"%V\" " 1876 "\"alias\" could not be used in location \"%V\" "
1750 "where URI was rewritten", &clcf->name); 1877 "where URI was rewritten", &clcf->name);
1768 1895
1769 #if (NGX_PCRE) 1896 #if (NGX_PCRE)
1770 ngx_uint_t captures; 1897 ngx_uint_t captures;
1771 1898
1772 captures = alias && clcf->regex; 1899 captures = alias && clcf->regex;
1773 reserved += captures ? 1 : r->uri.len - alias + 1; 1900
1901 reserved += captures ? r->add_uri_to_alias ? r->uri.len + 1 : 1
1902 : r->uri.len - alias + 1;
1774 #else 1903 #else
1775 reserved += r->uri.len - alias + 1; 1904 reserved += r->uri.len - alias + 1;
1776 #endif 1905 #endif
1777 1906
1778 if (ngx_http_script_run(r, path, clcf->root_lengths->elts, reserved, 1907 if (ngx_http_script_run(r, path, clcf->root_lengths->elts, reserved,
1789 *root_length = path->len - reserved; 1918 *root_length = path->len - reserved;
1790 last = path->data + *root_length; 1919 last = path->data + *root_length;
1791 1920
1792 #if (NGX_PCRE) 1921 #if (NGX_PCRE)
1793 if (captures) { 1922 if (captures) {
1794 *last = '\0'; 1923 if (!r->add_uri_to_alias) {
1795 return last; 1924 *last = '\0';
1925 return last;
1926 }
1927
1928 alias = 0;
1796 } 1929 }
1797 #endif 1930 #endif
1798 } 1931 }
1799 1932
1800 last = ngx_cpystrn(last, r->uri.data + alias, r->uri.len - alias + 1); 1933 last = ngx_cpystrn(last, r->uri.data + alias, r->uri.len - alias + 1);
2032 ngx_int_t 2165 ngx_int_t
2033 ngx_http_subrequest(ngx_http_request_t *r, 2166 ngx_http_subrequest(ngx_http_request_t *r,
2034 ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr, 2167 ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,
2035 ngx_http_post_subrequest_t *ps, ngx_uint_t flags) 2168 ngx_http_post_subrequest_t *ps, ngx_uint_t flags)
2036 { 2169 {
2170 ngx_time_t *tp;
2037 ngx_connection_t *c; 2171 ngx_connection_t *c;
2038 ngx_http_request_t *sr; 2172 ngx_http_request_t *sr;
2039 ngx_http_core_srv_conf_t *cscf; 2173 ngx_http_core_srv_conf_t *cscf;
2040 ngx_http_postponed_request_t *pr, *p; 2174 ngx_http_postponed_request_t *pr, *p;
2041 2175
2096 } 2230 }
2097 2231
2098 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, 2232 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
2099 "http subrequest \"%V?%V\"", uri, &sr->args); 2233 "http subrequest \"%V?%V\"", uri, &sr->args);
2100 2234
2101 sr->zero_in_uri = (flags & NGX_HTTP_ZERO_IN_URI) != 0;
2102 sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0; 2235 sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0;
2103 sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0; 2236 sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0;
2104 2237
2105 sr->unparsed_uri = r->unparsed_uri; 2238 sr->unparsed_uri = r->unparsed_uri;
2106 sr->method_name = ngx_http_core_get_method; 2239 sr->method_name = ngx_http_core_get_method;
2145 sr->expect_tested = 1; 2278 sr->expect_tested = 1;
2146 sr->main_filter_need_in_memory = r->main_filter_need_in_memory; 2279 sr->main_filter_need_in_memory = r->main_filter_need_in_memory;
2147 2280
2148 sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1; 2281 sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
2149 2282
2283 tp = ngx_timeofday();
2284 r->start_sec = tp->sec;
2285 r->start_msec = tp->msec;
2286
2150 r->main->subrequests++; 2287 r->main->subrequests++;
2151 r->main->count++; 2288 r->main->count++;
2152 2289
2153 *psr = sr; 2290 *psr = sr;
2154 2291
2178 2315
2179 if (args) { 2316 if (args) {
2180 r->args = *args; 2317 r->args = *args;
2181 2318
2182 } else { 2319 } else {
2183 r->args.len = 0; 2320 ngx_str_null(&r->args);
2184 r->args.data = NULL;
2185 } 2321 }
2186 2322
2187 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 2323 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2188 "internal redirect: \"%V?%V\"", uri, &r->args); 2324 "internal redirect: \"%V?%V\"", uri, &r->args);
2189 2325
2200 #if (NGX_HTTP_CACHE) 2336 #if (NGX_HTTP_CACHE)
2201 r->cache = NULL; 2337 r->cache = NULL;
2202 #endif 2338 #endif
2203 2339
2204 r->internal = 1; 2340 r->internal = 1;
2341 r->add_uri_to_alias = 0;
2205 r->main->count++; 2342 r->main->count++;
2206 2343
2207 ngx_http_handler(r); 2344 ngx_http_handler(r);
2208 2345
2209 return NGX_DONE; 2346 return NGX_DONE;
2303 char *rv; 2440 char *rv;
2304 void *mconf; 2441 void *mconf;
2305 ngx_uint_t i; 2442 ngx_uint_t i;
2306 ngx_conf_t pcf; 2443 ngx_conf_t pcf;
2307 ngx_http_module_t *module; 2444 ngx_http_module_t *module;
2445 struct sockaddr_in *sin;
2308 ngx_http_conf_ctx_t *ctx, *http_ctx; 2446 ngx_http_conf_ctx_t *ctx, *http_ctx;
2447 ngx_http_listen_opt_t lsopt;
2309 ngx_http_core_srv_conf_t *cscf, **cscfp; 2448 ngx_http_core_srv_conf_t *cscf, **cscfp;
2310 ngx_http_core_main_conf_t *cmcf; 2449 ngx_http_core_main_conf_t *cmcf;
2311 2450
2312 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)); 2451 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
2313 if (ctx == NULL) { 2452 if (ctx == NULL) {
2381 cf->cmd_type = NGX_HTTP_SRV_CONF; 2520 cf->cmd_type = NGX_HTTP_SRV_CONF;
2382 2521
2383 rv = ngx_conf_parse(cf, NULL); 2522 rv = ngx_conf_parse(cf, NULL);
2384 2523
2385 *cf = pcf; 2524 *cf = pcf;
2525
2526 if (rv == NGX_CONF_OK && !cscf->listen) {
2527 ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t));
2528
2529 sin = &lsopt.u.sockaddr_in;
2530
2531 sin->sin_family = AF_INET;
2532 #if (NGX_WIN32)
2533 sin->sin_port = htons(80);
2534 #else
2535 sin->sin_port = htons((getuid() == 0) ? 80 : 8000);
2536 #endif
2537 sin->sin_addr.s_addr = INADDR_ANY;
2538
2539 lsopt.socklen = sizeof(struct sockaddr_in);
2540
2541 lsopt.backlog = NGX_LISTEN_BACKLOG;
2542 lsopt.rcvbuf = -1;
2543 lsopt.sndbuf = -1;
2544 #if (NGX_HAVE_SETFIB)
2545 lsopt.setfib = -1;
2546 #endif
2547 lsopt.wildcard = 1;
2548
2549 (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.addr,
2550 NGX_SOCKADDR_STRLEN, 1);
2551
2552 if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) {
2553 return NGX_CONF_ERROR;
2554 }
2555 }
2386 2556
2387 return rv; 2557 return rv;
2388 } 2558 }
2389 2559
2390 2560
2822 ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) 2992 ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
2823 { 2993 {
2824 ngx_http_core_srv_conf_t *prev = parent; 2994 ngx_http_core_srv_conf_t *prev = parent;
2825 ngx_http_core_srv_conf_t *conf = child; 2995 ngx_http_core_srv_conf_t *conf = child;
2826 2996
2827 struct sockaddr_in *sin; 2997 ngx_str_t name;
2828 ngx_http_listen_opt_t lsopt;
2829 ngx_http_server_name_t *sn; 2998 ngx_http_server_name_t *sn;
2830 2999
2831 /* TODO: it does not merge, it inits only */ 3000 /* TODO: it does not merge, it inits only */
2832 3001
2833 ngx_conf_merge_size_value(conf->connection_pool_size, 3002 ngx_conf_merge_size_value(conf->connection_pool_size,
2855 ngx_conf_merge_value(conf->merge_slashes, prev->merge_slashes, 1); 3024 ngx_conf_merge_value(conf->merge_slashes, prev->merge_slashes, 1);
2856 3025
2857 ngx_conf_merge_value(conf->underscores_in_headers, 3026 ngx_conf_merge_value(conf->underscores_in_headers,
2858 prev->underscores_in_headers, 0); 3027 prev->underscores_in_headers, 0);
2859 3028
2860 if (!conf->listen) { 3029 if (conf->server_names.nelts == 0) {
2861 ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t)); 3030 /* the array has 4 empty preallocated elements, so push can not fail */
2862
2863 sin = &lsopt.u.sockaddr_in;
2864
2865 sin->sin_family = AF_INET;
2866 #if (NGX_WIN32)
2867 sin->sin_port = htons(80);
2868 #else
2869 sin->sin_port = htons((getuid() == 0) ? 80 : 8000);
2870 #endif
2871 sin->sin_addr.s_addr = INADDR_ANY;
2872
2873 lsopt.socklen = sizeof(struct sockaddr_in);
2874
2875 lsopt.backlog = NGX_LISTEN_BACKLOG;
2876 lsopt.rcvbuf = -1;
2877 lsopt.sndbuf = -1;
2878 lsopt.wildcard = 1;
2879
2880 (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.addr,
2881 NGX_SOCKADDR_STRLEN, 1);
2882
2883 if (ngx_http_add_listen(cf, conf, &lsopt) == NGX_OK) {
2884 return NGX_CONF_OK;
2885 }
2886 }
2887
2888 if (conf->server_name.data == NULL) {
2889 conf->server_name = cf->cycle->hostname;
2890
2891 sn = ngx_array_push(&conf->server_names); 3031 sn = ngx_array_push(&conf->server_names);
2892 if (sn == NULL) {
2893 return NGX_CONF_ERROR;
2894 }
2895
2896 #if (NGX_PCRE) 3032 #if (NGX_PCRE)
2897 sn->regex = NULL; 3033 sn->regex = NULL;
2898 #endif 3034 #endif
2899 sn->server = conf; 3035 sn->server = conf;
2900 sn->name.len = conf->server_name.len; 3036 ngx_str_set(&sn->name, "");
2901 sn->name.data = conf->server_name.data; 3037 }
3038
3039 sn = conf->server_names.elts;
3040 name = sn[0].name;
3041
3042 #if (NGX_PCRE)
3043 if (sn->regex) {
3044 name.len++;
3045 name.data--;
3046 } else
3047 #endif
3048
3049 if (name.data[0] == '.') {
3050 name.len--;
3051 name.data++;
3052 }
3053
3054 conf->server_name.len = name.len;
3055 conf->server_name.data = ngx_pstrdup(cf->pool, &name);
3056 if (conf->server_name.data == NULL) {
3057 return NGX_CONF_ERROR;
2902 } 3058 }
2903 3059
2904 return NGX_CONF_OK; 3060 return NGX_CONF_OK;
2905 } 3061 }
2906 3062
2935 */ 3091 */
2936 3092
2937 clcf->client_max_body_size = NGX_CONF_UNSET; 3093 clcf->client_max_body_size = NGX_CONF_UNSET;
2938 clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE; 3094 clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
2939 clcf->client_body_timeout = NGX_CONF_UNSET_MSEC; 3095 clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
3096 clcf->keepalive_disable = NGX_CONF_UNSET_UINT;
2940 clcf->satisfy = NGX_CONF_UNSET_UINT; 3097 clcf->satisfy = NGX_CONF_UNSET_UINT;
2941 clcf->if_modified_since = NGX_CONF_UNSET_UINT; 3098 clcf->if_modified_since = NGX_CONF_UNSET_UINT;
2942 clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT; 3099 clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT;
2943 clcf->client_body_in_single_buffer = NGX_CONF_UNSET; 3100 clcf->client_body_in_single_buffer = NGX_CONF_UNSET;
2944 clcf->internal = NGX_CONF_UNSET; 3101 clcf->internal = NGX_CONF_UNSET;
2970 clcf->msie_refresh = NGX_CONF_UNSET; 3127 clcf->msie_refresh = NGX_CONF_UNSET;
2971 clcf->log_not_found = NGX_CONF_UNSET; 3128 clcf->log_not_found = NGX_CONF_UNSET;
2972 clcf->log_subrequest = NGX_CONF_UNSET; 3129 clcf->log_subrequest = NGX_CONF_UNSET;
2973 clcf->recursive_error_pages = NGX_CONF_UNSET; 3130 clcf->recursive_error_pages = NGX_CONF_UNSET;
2974 clcf->server_tokens = NGX_CONF_UNSET; 3131 clcf->server_tokens = NGX_CONF_UNSET;
3132 clcf->chunked_transfer_encoding = NGX_CONF_UNSET;
2975 clcf->types_hash_max_size = NGX_CONF_UNSET_UINT; 3133 clcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
2976 clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT; 3134 clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
2977 3135
2978 clcf->open_file_cache = NGX_CONF_UNSET_PTR; 3136 clcf->open_file_cache = NGX_CONF_UNSET_PTR;
2979 clcf->open_file_cache_valid = NGX_CONF_UNSET; 3137 clcf->open_file_cache_valid = NGX_CONF_UNSET;
2984 #if (NGX_HTTP_GZIP) 3142 #if (NGX_HTTP_GZIP)
2985 clcf->gzip_vary = NGX_CONF_UNSET; 3143 clcf->gzip_vary = NGX_CONF_UNSET;
2986 clcf->gzip_http_version = NGX_CONF_UNSET_UINT; 3144 clcf->gzip_http_version = NGX_CONF_UNSET_UINT;
2987 #if (NGX_PCRE) 3145 #if (NGX_PCRE)
2988 clcf->gzip_disable = NGX_CONF_UNSET_PTR; 3146 clcf->gzip_disable = NGX_CONF_UNSET_PTR;
3147 #endif
2989 clcf->gzip_disable_msie6 = 3; 3148 clcf->gzip_disable_msie6 = 3;
3149 #if (NGX_HTTP_DEGRADATION)
3150 clcf->gzip_disable_degradation = 3;
2990 #endif 3151 #endif
2991 #endif 3152 #endif
2992 3153
2993 return clcf; 3154 return clcf;
2994 } 3155 }
3022 conf->root = prev->root; 3183 conf->root = prev->root;
3023 conf->root_lengths = prev->root_lengths; 3184 conf->root_lengths = prev->root_lengths;
3024 conf->root_values = prev->root_values; 3185 conf->root_values = prev->root_values;
3025 3186
3026 if (prev->root.data == NULL) { 3187 if (prev->root.data == NULL) {
3027 conf->root.len = sizeof("html") - 1; 3188 ngx_str_set(&conf->root, "html");
3028 conf->root.data = (u_char *) "html";
3029 3189
3030 if (ngx_conf_full_name(cf->cycle, &conf->root, 0) != NGX_OK) { 3190 if (ngx_conf_full_name(cf->cycle, &conf->root, 0) != NGX_OK) {
3031 return NGX_CONF_ERROR; 3191 return NGX_CONF_ERROR;
3032 } 3192 }
3033 } 3193 }
3132 prev->client_body_buffer_size, 3292 prev->client_body_buffer_size,
3133 (size_t) 2 * ngx_pagesize); 3293 (size_t) 2 * ngx_pagesize);
3134 ngx_conf_merge_msec_value(conf->client_body_timeout, 3294 ngx_conf_merge_msec_value(conf->client_body_timeout,
3135 prev->client_body_timeout, 60000); 3295 prev->client_body_timeout, 60000);
3136 3296
3297 ngx_conf_merge_uint_value(conf->keepalive_disable, prev->keepalive_disable,
3298 NGX_HTTP_KEEPALIVE_DISABLE_MSIE6
3299 |NGX_HTTP_KEEPALIVE_DISABLE_SAFARI);
3137 ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy, 3300 ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy,
3138 NGX_HTTP_SATISFY_ALL); 3301 NGX_HTTP_SATISFY_ALL);
3139 ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since, 3302 ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since,
3140 NGX_HTTP_IMS_EXACT); 3303 NGX_HTTP_IMS_EXACT);
3141 ngx_conf_merge_uint_value(conf->client_body_in_file_only, 3304 ngx_conf_merge_uint_value(conf->client_body_in_file_only,
3204 } 3367 }
3205 3368
3206 ngx_conf_merge_value(conf->reset_timedout_connection, 3369 ngx_conf_merge_value(conf->reset_timedout_connection,
3207 prev->reset_timedout_connection, 0); 3370 prev->reset_timedout_connection, 0);
3208 ngx_conf_merge_value(conf->server_name_in_redirect, 3371 ngx_conf_merge_value(conf->server_name_in_redirect,
3209 prev->server_name_in_redirect, 1); 3372 prev->server_name_in_redirect, 0);
3210 ngx_conf_merge_value(conf->port_in_redirect, prev->port_in_redirect, 1); 3373 ngx_conf_merge_value(conf->port_in_redirect, prev->port_in_redirect, 1);
3211 ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1); 3374 ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1);
3212 ngx_conf_merge_value(conf->msie_refresh, prev->msie_refresh, 0); 3375 ngx_conf_merge_value(conf->msie_refresh, prev->msie_refresh, 0);
3213 ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1); 3376 ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1);
3214 ngx_conf_merge_value(conf->log_subrequest, prev->log_subrequest, 0); 3377 ngx_conf_merge_value(conf->log_subrequest, prev->log_subrequest, 0);
3215 ngx_conf_merge_value(conf->recursive_error_pages, 3378 ngx_conf_merge_value(conf->recursive_error_pages,
3216 prev->recursive_error_pages, 0); 3379 prev->recursive_error_pages, 0);
3217 ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1); 3380 ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1);
3381 ngx_conf_merge_value(conf->chunked_transfer_encoding,
3382 prev->chunked_transfer_encoding, 1);
3218 3383
3219 ngx_conf_merge_ptr_value(conf->open_file_cache, 3384 ngx_conf_merge_ptr_value(conf->open_file_cache,
3220 prev->open_file_cache, NULL); 3385 prev->open_file_cache, NULL);
3221 3386
3222 ngx_conf_merge_sec_value(conf->open_file_cache_valid, 3387 ngx_conf_merge_sec_value(conf->open_file_cache_valid,
3245 if (conf->gzip_disable_msie6 == 3) { 3410 if (conf->gzip_disable_msie6 == 3) {
3246 conf->gzip_disable_msie6 = 3411 conf->gzip_disable_msie6 =
3247 (prev->gzip_disable_msie6 == 3) ? 0 : prev->gzip_disable_msie6; 3412 (prev->gzip_disable_msie6 == 3) ? 0 : prev->gzip_disable_msie6;
3248 } 3413 }
3249 3414
3415 #if (NGX_HTTP_DEGRADATION)
3416
3417 if (conf->gzip_disable_degradation == 3) {
3418 conf->gzip_disable_degradation =
3419 (prev->gzip_disable_degradation == 3) ?
3420 0 : prev->gzip_disable_degradation;
3421 }
3422
3423 #endif
3250 #endif 3424 #endif
3251 3425
3252 return NGX_CONF_OK; 3426 return NGX_CONF_OK;
3253 } 3427 }
3254 3428
3289 3463
3290 lsopt.socklen = u.socklen; 3464 lsopt.socklen = u.socklen;
3291 lsopt.backlog = NGX_LISTEN_BACKLOG; 3465 lsopt.backlog = NGX_LISTEN_BACKLOG;
3292 lsopt.rcvbuf = -1; 3466 lsopt.rcvbuf = -1;
3293 lsopt.sndbuf = -1; 3467 lsopt.sndbuf = -1;
3468 #if (NGX_HAVE_SETFIB)
3469 lsopt.setfib = -1;
3470 #endif
3294 lsopt.wildcard = u.wildcard; 3471 lsopt.wildcard = u.wildcard;
3295 3472
3296 (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.addr, 3473 (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.addr,
3297 NGX_SOCKADDR_STRLEN, 1); 3474 NGX_SOCKADDR_STRLEN, 1);
3298 3475
3309 lsopt.set = 1; 3486 lsopt.set = 1;
3310 lsopt.bind = 1; 3487 lsopt.bind = 1;
3311 continue; 3488 continue;
3312 } 3489 }
3313 3490
3491 #if (NGX_HAVE_SETFIB)
3492 if (ngx_strncmp(value[n].data, "setfib=", 7) == 0) {
3493 lsopt.setfib = ngx_atoi(value[n].data + 7, value[n].len - 7);
3494
3495 if (lsopt.setfib == NGX_ERROR) {
3496 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3497 "invalid setfib \"%V\"", &value[n]);
3498 return NGX_CONF_ERROR;
3499 }
3500
3501 continue;
3502 }
3503 #endif
3314 if (ngx_strncmp(value[n].data, "backlog=", 8) == 0) { 3504 if (ngx_strncmp(value[n].data, "backlog=", 8) == 0) {
3315 lsopt.backlog = ngx_atoi(value[n].data + 8, value[n].len - 8); 3505 lsopt.backlog = ngx_atoi(value[n].data + 8, value[n].len - 8);
3316 lsopt.set = 1; 3506 lsopt.set = 1;
3317 lsopt.bind = 1; 3507 lsopt.bind = 1;
3318 3508
3425 #endif 3615 #endif
3426 } 3616 }
3427 3617
3428 if (ngx_strcmp(value[n].data, "ssl") == 0) { 3618 if (ngx_strcmp(value[n].data, "ssl") == 0) {
3429 #if (NGX_HTTP_SSL) 3619 #if (NGX_HTTP_SSL)
3430 lsopt.set = 1;
3431 lsopt.ssl = 1; 3620 lsopt.ssl = 1;
3432 continue; 3621 continue;
3433 #else 3622 #else
3434 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 3623 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3435 "the \"ssl\" parameter requires " 3624 "the \"ssl\" parameter requires "
3455 ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 3644 ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3456 { 3645 {
3457 ngx_http_core_srv_conf_t *cscf = conf; 3646 ngx_http_core_srv_conf_t *cscf = conf;
3458 3647
3459 u_char ch; 3648 u_char ch;
3460 ngx_str_t *value, name; 3649 ngx_str_t *value;
3461 ngx_uint_t i; 3650 ngx_uint_t i;
3462 ngx_http_server_name_t *sn; 3651 ngx_http_server_name_t *sn;
3463 3652
3464 value = cf->args->elts; 3653 value = cf->args->elts;
3465
3466 ch = value[1].data[0];
3467
3468 if (cscf->server_name.data == NULL) {
3469 if (value[1].len) {
3470 name = value[1];
3471
3472 if (ch == '.') {
3473 name.len--;
3474 name.data++;
3475 }
3476
3477 cscf->server_name.len = name.len;
3478 cscf->server_name.data = ngx_pstrdup(cf->pool, &name);
3479 if (cscf->server_name.data == NULL) {
3480 return NGX_CONF_ERROR;
3481 }
3482
3483 } else {
3484 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3485 "the first server name must not be empty");
3486 return NGX_CONF_ERROR;
3487 }
3488 }
3489 3654
3490 for (i = 1; i < cf->args->nelts; i++) { 3655 for (i = 1; i < cf->args->nelts; i++) {
3491 3656
3492 ch = value[i].data[0]; 3657 ch = value[i].data[0];
3493 3658
3519 3684
3520 #if (NGX_PCRE) 3685 #if (NGX_PCRE)
3521 sn->regex = NULL; 3686 sn->regex = NULL;
3522 #endif 3687 #endif
3523 sn->server = cscf; 3688 sn->server = cscf;
3524 sn->name = value[i]; 3689
3690 if (ngx_strcasecmp(value[i].data, (u_char *) "$hostname") == 0) {
3691 sn->name = cf->cycle->hostname;
3692
3693 } else {
3694 sn->name = value[i];
3695 }
3525 3696
3526 if (value[i].data[0] != '~') { 3697 if (value[i].data[0] != '~') {
3527 ngx_strlow(sn->name.data, sn->name.data, sn->name.len); 3698 ngx_strlow(sn->name.data, sn->name.data, sn->name.len);
3528 continue; 3699 continue;
3529 } 3700 }
3581 ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 3752 ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3582 { 3753 {
3583 ngx_http_core_loc_conf_t *clcf = conf; 3754 ngx_http_core_loc_conf_t *clcf = conf;
3584 3755
3585 ngx_str_t *value; 3756 ngx_str_t *value;
3586 ngx_uint_t alias, n; 3757 ngx_int_t alias;
3758 ngx_uint_t n;
3587 ngx_http_script_compile_t sc; 3759 ngx_http_script_compile_t sc;
3588 3760
3589 alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0; 3761 alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0;
3590 3762
3591 if (clcf->root.data) { 3763 if (clcf->root.data) {
3592 3764
3593 /* the (ngx_uint_t) cast is required by gcc 2.7.2.3 */ 3765 if ((clcf->alias != 0) == alias) {
3594
3595 if ((ngx_uint_t) clcf->alias == alias) {
3596 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 3766 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3597 "\"%V\" directive is duplicate", 3767 "\"%V\" directive is duplicate",
3598 &cmd->name); 3768 &cmd->name);
3599 } else { 3769 } else {
3600 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 3770 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3636 &cmd->name); 3806 &cmd->name);
3637 3807
3638 return NGX_CONF_ERROR; 3808 return NGX_CONF_ERROR;
3639 } 3809 }
3640 3810
3641 clcf->alias = alias; 3811 clcf->alias = alias ? clcf->name.len : 0;
3642 clcf->root = value[1]; 3812 clcf->root = value[1];
3643 3813
3644 if (!alias && clcf->root.data[clcf->root.len - 1] == '/') { 3814 if (!alias && clcf->root.data[clcf->root.len - 1] == '/') {
3645 clcf->root.len--; 3815 clcf->root.len--;
3646 } 3816 }
3652 } 3822 }
3653 3823
3654 n = ngx_http_script_variables_count(&clcf->root); 3824 n = ngx_http_script_variables_count(&clcf->root);
3655 3825
3656 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); 3826 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
3827 sc.variables = n;
3828
3829 #if (NGX_PCRE)
3830 if (alias && clcf->regex) {
3831 n = 1;
3832 }
3833 #endif
3657 3834
3658 if (n) { 3835 if (n) {
3659 sc.cf = cf; 3836 sc.cf = cf;
3660 sc.source = &clcf->root; 3837 sc.source = &clcf->root;
3661 sc.lengths = &clcf->root_lengths; 3838 sc.lengths = &clcf->root_lengths;
3662 sc.values = &clcf->root_values; 3839 sc.values = &clcf->root_values;
3663 sc.variables = n;
3664 sc.complete_lengths = 1; 3840 sc.complete_lengths = 1;
3665 sc.complete_values = 1; 3841 sc.complete_values = 1;
3666 3842
3667 if (ngx_http_script_compile(&sc) != NGX_OK) { 3843 if (ngx_http_script_compile(&sc) != NGX_OK) {
3668 return NGX_CONF_ERROR; 3844 return NGX_CONF_ERROR;
3685 { (u_char *) "OPTIONS", (uint32_t) ~NGX_HTTP_OPTIONS }, 3861 { (u_char *) "OPTIONS", (uint32_t) ~NGX_HTTP_OPTIONS },
3686 { (u_char *) "PROPFIND" , (uint32_t) ~NGX_HTTP_PROPFIND }, 3862 { (u_char *) "PROPFIND" , (uint32_t) ~NGX_HTTP_PROPFIND },
3687 { (u_char *) "PROPPATCH", (uint32_t) ~NGX_HTTP_PROPPATCH }, 3863 { (u_char *) "PROPPATCH", (uint32_t) ~NGX_HTTP_PROPPATCH },
3688 { (u_char *) "LOCK", (uint32_t) ~NGX_HTTP_LOCK }, 3864 { (u_char *) "LOCK", (uint32_t) ~NGX_HTTP_LOCK },
3689 { (u_char *) "UNLOCK", (uint32_t) ~NGX_HTTP_UNLOCK }, 3865 { (u_char *) "UNLOCK", (uint32_t) ~NGX_HTTP_UNLOCK },
3866 { (u_char *) "PATCH", (uint32_t) ~NGX_HTTP_PATCH },
3690 { NULL, 0 } 3867 { NULL, 0 }
3691 }; 3868 };
3692 3869
3693 3870
3694 static char * 3871 static char *
3771 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; 3948 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
3772 pclcf->limit_except_loc_conf = ctx->loc_conf; 3949 pclcf->limit_except_loc_conf = ctx->loc_conf;
3773 clcf->loc_conf = ctx->loc_conf; 3950 clcf->loc_conf = ctx->loc_conf;
3774 clcf->name = pclcf->name; 3951 clcf->name = pclcf->name;
3775 clcf->noname = 1; 3952 clcf->noname = 1;
3953 clcf->lmt_excpt = 1;
3776 3954
3777 if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) { 3955 if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
3778 return NGX_CONF_ERROR; 3956 return NGX_CONF_ERROR;
3779 } 3957 }
3780 3958
3879 4057
3880 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { 4058 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
3881 return NGX_CONF_ERROR; 4059 return NGX_CONF_ERROR;
3882 } 4060 }
3883 4061
3884 args.len = 0; 4062 ngx_str_null(&args);
3885 args.data = NULL;
3886 4063
3887 if (cv.lengths == NULL && uri.data[0] == '/') { 4064 if (cv.lengths == NULL && uri.data[0] == '/') {
3888 p = (u_char *) ngx_strchr(uri.data, '?'); 4065 p = (u_char *) ngx_strchr(uri.data, '?');
3889 4066
3890 if (p) { 4067 if (p) {
3915 "value \"%V\" must be between 300 and 599", 4092 "value \"%V\" must be between 300 and 599",
3916 &value[i]); 4093 &value[i]);
3917 return NGX_CONF_ERROR; 4094 return NGX_CONF_ERROR;
3918 } 4095 }
3919 4096
3920 if (overwrite >= 0) { 4097 err->overwrite = overwrite;
3921 err->overwrite = overwrite; 4098
3922 4099 if (overwrite == -1) {
3923 } else {
3924 switch (err->status) { 4100 switch (err->status) {
3925 case NGX_HTTP_TO_HTTPS: 4101 case NGX_HTTP_TO_HTTPS:
3926 case NGX_HTTPS_CERT_ERROR: 4102 case NGX_HTTPS_CERT_ERROR:
3927 case NGX_HTTPS_NO_CERT: 4103 case NGX_HTTPS_NO_CERT:
3928 err->overwrite = NGX_HTTP_BAD_REQUEST; 4104 err->overwrite = NGX_HTTP_BAD_REQUEST;
3929 break;
3930
3931 default: 4105 default:
3932 err->overwrite = err->status;
3933 break; 4106 break;
3934 } 4107 }
3935 } 4108 }
3936 4109
3937 err->value = cv; 4110 err->value = cv;
4247 rc.err.len = NGX_MAX_CONF_ERRSTR; 4420 rc.err.len = NGX_MAX_CONF_ERRSTR;
4248 rc.err.data = errstr; 4421 rc.err.data = errstr;
4249 4422
4250 for (i = 1; i < cf->args->nelts; i++) { 4423 for (i = 1; i < cf->args->nelts; i++) {
4251 4424
4252 if (ngx_strcmp(value[1].data, "msie6") == 0) { 4425 if (ngx_strcmp(value[i].data, "msie6") == 0) {
4253 clcf->gzip_disable_msie6 = 1; 4426 clcf->gzip_disable_msie6 = 1;
4254 continue; 4427 continue;
4255 } 4428 }
4429
4430 #if (NGX_HTTP_DEGRADATION)
4431
4432 if (ngx_strcmp(value[i].data, "degradation") == 0) {
4433 clcf->gzip_disable_degradation = 1;
4434 continue;
4435 }
4436
4437 #endif
4256 4438
4257 re = ngx_array_push(clcf->gzip_disable); 4439 re = ngx_array_push(clcf->gzip_disable);
4258 if (re == NULL) { 4440 if (re == NULL) {
4259 return NGX_CONF_ERROR; 4441 return NGX_CONF_ERROR;
4260 } 4442 }
4261 4443
4262 rc.pattern = value[1]; 4444 rc.pattern = value[i];
4263 rc.options = NGX_REGEX_CASELESS; 4445 rc.options = NGX_REGEX_CASELESS;
4264 4446
4265 if (ngx_regex_compile(&rc) != NGX_OK) { 4447 if (ngx_regex_compile(&rc) != NGX_OK) {
4266 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err); 4448 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
4267 return NGX_CONF_ERROR; 4449 return NGX_CONF_ERROR;
4272 } 4454 }
4273 4455
4274 return NGX_CONF_OK; 4456 return NGX_CONF_OK;
4275 4457
4276 #else 4458 #else
4277 ngx_str_t *value; 4459 ngx_str_t *value;
4460 ngx_uint_t i;
4278 4461
4279 value = cf->args->elts; 4462 value = cf->args->elts;
4280 4463
4281 if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "msie6") == 0) { 4464 for (i = 1; i < cf->args->nelts; i++) {
4282 clcf->gzip_disable_msie6 = 1; 4465 if (ngx_strcmp(value[i].data, "msie6") == 0) {
4283 return NGX_CONF_OK; 4466 clcf->gzip_disable_msie6 = 1;
4284 } 4467 continue;
4285 4468 }
4286 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 4469
4287 "without PCRE library \"gzip_disable\" supports " 4470 #if (NGX_HTTP_DEGRADATION)
4288 "builtin \"msie6\" mask only"); 4471
4289 4472 if (ngx_strcmp(value[i].data, "degradation") == 0) {
4290 return NGX_CONF_ERROR; 4473 clcf->gzip_disable_degradation = 1;
4474 continue;
4475 }
4476
4477 #endif
4478
4479 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4480 "without PCRE library \"gzip_disable\" supports "
4481 "builtin \"msie6\" and \"degradation\" mask only");
4482
4483 return NGX_CONF_ERROR;
4484 }
4485
4486 return NGX_CONF_OK;
4487
4291 #endif 4488 #endif
4292 } 4489 }
4293 4490
4294 #endif 4491 #endif
4295 4492