comparison src/http/ngx_http_core_module.c @ 378:820f6378fc00 NGINX_0_7_1

nginx 0.7.1 *) Change: now locations are searched in a tree. *) Change: the "optimize_server_names" directive was canceled due to the "server_name_in_redirect" directive introduction. *) Change: some long deprecated directives are not supported anymore. *) Change: the "none" parameter in the "ssl_session_cache" directive; now this is default parameter. Thanks to Rob Mueller. *) Bugfix: worker processes might not catch reconfiguration and log rotation signals. *) Bugfix: nginx could not be built on latest Fedora 9 Linux. Thanks to Roxis.
author Igor Sysoev <http://sysoev.ru>
date Mon, 26 May 2008 00:00:00 +0400
parents edf1cb6c328e
children bc21d9cd9c54
comparison
equal deleted inserted replaced
377:5d98007adb5f 378:820f6378fc00
15 u_char *name; 15 u_char *name;
16 uint32_t method; 16 uint32_t method;
17 } ngx_http_method_name_t; 17 } ngx_http_method_name_t;
18 18
19 19
20 #define NGX_HTTP_LOCATION_EXACT 1
21 #define NGX_HTTP_LOCATION_AUTO_REDIRECT 2
22 #define NGX_HTTP_LOCATION_NOREGEX 3
23 #define NGX_HTTP_LOCATION_REGEX 4
24
25
26 #define NGX_HTTP_REQUEST_BODY_FILE_OFF 0 20 #define NGX_HTTP_REQUEST_BODY_FILE_OFF 0
27 #define NGX_HTTP_REQUEST_BODY_FILE_ON 1 21 #define NGX_HTTP_REQUEST_BODY_FILE_ON 1
28 #define NGX_HTTP_REQUEST_BODY_FILE_CLEAN 2 22 #define NGX_HTTP_REQUEST_BODY_FILE_CLEAN 2
29 23
30 24
31 static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r, 25 static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r);
32 ngx_array_t *locations, ngx_uint_t regex_start, size_t len); 26 static ngx_int_t ngx_http_core_find_static_location(ngx_http_request_t *r,
27 ngx_http_location_tree_node_t *node);
33 28
34 static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf); 29 static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
35 static void *ngx_http_core_create_main_conf(ngx_conf_t *cf); 30 static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
36 static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf); 31 static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf);
37 static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf); 32 static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf);
43 38
44 static char *ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, 39 static char *ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd,
45 void *dummy); 40 void *dummy);
46 static char *ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, 41 static char *ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd,
47 void *dummy); 42 void *dummy);
48 static ngx_int_t ngx_http_core_cmp_locations(const void *first,
49 const void *second);
50 43
51 static char *ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, 44 static char *ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd,
52 void *conf); 45 void *conf);
53 static char *ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, 46 static char *ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy,
54 void *conf); 47 void *conf);
84 { ngx_http_core_lowat_check }; 77 { ngx_http_core_lowat_check };
85 78
86 static ngx_conf_post_handler_pt ngx_http_core_pool_size_p = 79 static ngx_conf_post_handler_pt ngx_http_core_pool_size_p =
87 ngx_http_core_pool_size; 80 ngx_http_core_pool_size;
88 81
89 static ngx_conf_deprecated_t ngx_conf_deprecated_optimize_host_names = { 82 static ngx_conf_deprecated_t ngx_conf_deprecated_optimize_server_names = {
90 ngx_conf_deprecated, "optimize_host_names", "optimize_server_names" 83 ngx_conf_deprecated, "optimize_server_names", "server_name_in_redirect"
91 }; 84 };
92 85
93 static ngx_conf_deprecated_t ngx_conf_deprecated_open_file_cache_retest = { 86 static ngx_conf_deprecated_t ngx_conf_deprecated_open_file_cache_retest = {
94 ngx_conf_deprecated, "open_file_cache_retest", "open_file_cache_valid" 87 ngx_conf_deprecated, "open_file_cache_retest", "open_file_cache_valid"
95 }; 88 };
217 NULL }, 210 NULL },
218 211
219 { ngx_string("optimize_server_names"), 212 { ngx_string("optimize_server_names"),
220 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, 213 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
221 ngx_conf_set_flag_slot, 214 ngx_conf_set_flag_slot,
222 NGX_HTTP_SRV_CONF_OFFSET, 215 NGX_HTTP_LOC_CONF_OFFSET,
223 offsetof(ngx_http_core_srv_conf_t, optimize_server_names), 216 offsetof(ngx_http_core_loc_conf_t, server_name_in_redirect),
224 NULL }, 217 &ngx_conf_deprecated_optimize_server_names },
225
226 { ngx_string("optimize_host_names"),
227 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
228 ngx_conf_set_flag_slot,
229 NGX_HTTP_SRV_CONF_OFFSET,
230 offsetof(ngx_http_core_srv_conf_t, optimize_server_names),
231 &ngx_conf_deprecated_optimize_host_names },
232 218
233 { ngx_string("ignore_invalid_headers"), 219 { ngx_string("ignore_invalid_headers"),
234 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, 220 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
235 ngx_conf_set_flag_slot, 221 ngx_conf_set_flag_slot,
236 NGX_HTTP_SRV_CONF_OFFSET, 222 NGX_HTTP_SRV_CONF_OFFSET,
785 { 771 {
786 u_char *p; 772 u_char *p;
787 size_t len; 773 size_t len;
788 ngx_int_t rc; 774 ngx_int_t rc;
789 ngx_http_core_loc_conf_t *clcf; 775 ngx_http_core_loc_conf_t *clcf;
790 ngx_http_core_srv_conf_t *cscf;
791 776
792 r->content_handler = NULL; 777 r->content_handler = NULL;
793 r->uri_changed = 0; 778 r->uri_changed = 0;
794 779
795 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); 780 rc = ngx_http_core_find_location(r);
796
797 rc = ngx_http_core_find_location(r, &cscf->locations, cscf->regex_start, 0);
798 781
799 if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) { 782 if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
800 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 783 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
801 return NGX_OK; 784 return NGX_OK;
802 } 785 }
830 813
831 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE); 814 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
832 return NGX_OK; 815 return NGX_OK;
833 } 816 }
834 817
835 818 if (rc == NGX_DONE) {
836 if (rc == NGX_HTTP_LOCATION_AUTO_REDIRECT) {
837 r->headers_out.location = ngx_list_push(&r->headers_out.headers); 819 r->headers_out.location = ngx_list_push(&r->headers_out.headers);
838 if (r->headers_out.location == NULL) { 820 if (r->headers_out.location == NULL) {
839 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 821 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
840 return NGX_OK; 822 return NGX_OK;
841 } 823 }
1110 } 1092 }
1111 } 1093 }
1112 1094
1113 1095
1114 static ngx_int_t 1096 static ngx_int_t
1115 ngx_http_core_find_location(ngx_http_request_t *r, 1097 ngx_http_core_find_location(ngx_http_request_t *r)
1116 ngx_array_t *locations, ngx_uint_t regex_start, size_t len) 1098 {
1117 { 1099 ngx_int_t rc;
1118 ngx_int_t n, rc; 1100 ngx_http_core_loc_conf_t *pclcf;
1119 ngx_uint_t i, found; 1101
1102 pclcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1103
1104 rc = ngx_http_core_find_static_location(r, pclcf->static_locations);
1105
1106 if (rc == NGX_AGAIN) {
1107 /* look up nested locations */
1108 rc = ngx_http_core_find_location(r);
1109 }
1110
1111 if (rc == NGX_OK || rc == NGX_DONE) {
1112 return rc;
1113 }
1114
1115 /* rc == NGX_DECLINED or rc == NGX_AGAIN in nested location */
1116
1117 #if (NGX_PCRE)
1118 {
1119 ngx_int_t n;
1120 ngx_http_core_loc_conf_t *clcf, **clcfp; 1120 ngx_http_core_loc_conf_t *clcf, **clcfp;
1121 #if (NGX_PCRE) 1121
1122 ngx_uint_t noregex; 1122 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1123 #endif 1123
1124 1124 if (clcf->noregex == 0 && pclcf->regex_locations) {
1125 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 1125
1126 "find location for \"%V\"", &r->uri); 1126 for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) {
1127 1127
1128 found = 0; 1128 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1129 #if (NGX_PCRE) 1129 "test location: ~ \"%V\"", &(*clcfp)->name);
1130 noregex = 0; 1130
1131 #endif 1131 n = ngx_regex_exec((*clcfp)->regex, &r->uri, NULL, 0);
1132 1132
1133 clcfp = locations->elts; 1133 if (n == NGX_REGEX_NO_MATCHED) {
1134 for (i = 0; i < locations->nelts; i++) {
1135
1136 if (clcfp[i]->noname
1137 #if (NGX_PCRE)
1138 || clcfp[i]->regex
1139 #endif
1140 || clcfp[i]->named)
1141 {
1142 break;
1143 }
1144
1145 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1146 "find location: %s\"%V\"",
1147 clcfp[i]->exact_match ? "= " : "", &clcfp[i]->name);
1148
1149 if (clcfp[i]->auto_redirect
1150 && r->uri.len == clcfp[i]->name.len - 1
1151 && ngx_strncmp(r->uri.data, clcfp[i]->name.data,
1152 clcfp[i]->name.len - 1)
1153 == 0)
1154 {
1155 /* the locations are lexicographically sorted */
1156
1157 r->loc_conf = clcfp[i]->loc_conf;
1158
1159 return NGX_HTTP_LOCATION_AUTO_REDIRECT;
1160 }
1161
1162 if (r->uri.len < clcfp[i]->name.len) {
1163 continue;
1164 }
1165
1166 n = ngx_strncmp(r->uri.data, clcfp[i]->name.data, clcfp[i]->name.len);
1167
1168 if (n < 0) {
1169 /* the locations are lexicographically sorted */
1170 break;
1171 }
1172
1173 if (n == 0) {
1174 if (clcfp[i]->exact_match) {
1175
1176 if (r->uri.len == clcfp[i]->name.len) {
1177 r->loc_conf = clcfp[i]->loc_conf;
1178 return NGX_HTTP_LOCATION_EXACT;
1179 }
1180
1181 continue; 1134 continue;
1182 } 1135 }
1183 1136
1184 if (len > clcfp[i]->name.len) { 1137 if (n < 0) {
1185 /* the previous match is longer */ 1138 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1186 break; 1139 ngx_regex_exec_n
1140 " failed: %d on \"%V\" using \"%V\"",
1141 n, &r->uri, &(*clcfp)->name);
1142 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1187 } 1143 }
1188 1144
1189 found = 1; 1145 /* match */
1190 1146
1191 r->loc_conf = clcfp[i]->loc_conf; 1147 r->loc_conf = (*clcfp)->loc_conf;
1192 #if (NGX_PCRE) 1148
1193 noregex = clcfp[i]->noregex; 1149 /* look up nested locations */
1150
1151 return ngx_http_core_find_location(r);
1152 }
1153 }
1154 }
1194 #endif 1155 #endif
1195 } 1156
1196 } 1157 return rc;
1197 1158 }
1198 if (found) { 1159
1199 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 1160
1200 1161 /*
1201 if (clcf->locations) { 1162 * NGX_OK - exact match
1202 rc = ngx_http_core_find_location(r, clcf->locations, 1163 * NGX_DONE - auto redirect
1203 clcf->regex_start, len); 1164 * NGX_AGAIN - inclusive match
1204 1165 * NGX_DECLINED - no match
1205 if (rc != NGX_OK) { 1166 */
1206 return rc; 1167
1168 static ngx_int_t
1169 ngx_http_core_find_static_location(ngx_http_request_t *r,
1170 ngx_http_location_tree_node_t *node)
1171 {
1172 u_char *uri;
1173 size_t len, n;
1174 ngx_int_t rc, rv;
1175
1176 len = r->uri.len;
1177 uri = r->uri.data;
1178
1179 rv = NGX_DECLINED;
1180
1181 for ( ;; ) {
1182
1183 if (node == NULL) {
1184 return rv;
1185 }
1186
1187 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1188 "test location: \"%*s\"", node->len, node->name);
1189
1190 n = (len <= (size_t) node->len) ? len : node->len;
1191
1192 rc = ngx_memcmp(uri, node->name, n);
1193
1194 if (rc != 0) {
1195 node = (rc < 0) ? node->left : node->right;
1196
1197 continue;
1198 }
1199
1200 if (len > (size_t) node->len) {
1201
1202 if (node->inclusive) {
1203
1204 r->loc_conf = node->inclusive->loc_conf;
1205 rv = NGX_AGAIN;
1206
1207 node = node->tree;
1208 uri += n;
1209 len -= n;
1210
1211 continue;
1207 } 1212 }
1208 } 1213
1209 } 1214 /* exact only */
1210 1215
1211 #if (NGX_PCRE) 1216 node = node->right;
1212 1217
1213 if (noregex) {
1214 return NGX_HTTP_LOCATION_NOREGEX;
1215 }
1216
1217 /* regex matches */
1218
1219 for (i = regex_start; i < locations->nelts; i++) {
1220
1221 if (!clcfp[i]->regex) {
1222 break;
1223 }
1224
1225 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1226 "find location: ~ \"%V\"", &clcfp[i]->name);
1227
1228 n = ngx_regex_exec(clcfp[i]->regex, &r->uri, NULL, 0);
1229
1230 if (n == NGX_REGEX_NO_MATCHED) {
1231 continue; 1218 continue;
1232 } 1219 }
1233 1220
1234 if (n < 0) { 1221 if (len == (size_t) node->len) {
1235 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, 1222
1236 ngx_regex_exec_n 1223 r->loc_conf = (node->exact) ? node->exact->loc_conf:
1237 " failed: %d on \"%V\" using \"%V\"", 1224 node->inclusive->loc_conf;
1238 n, &r->uri, &clcfp[i]->name); 1225 return NGX_OK;
1239 return NGX_HTTP_INTERNAL_SERVER_ERROR; 1226 }
1240 } 1227
1241 1228 /* len < node->len */
1242 /* match */ 1229
1243 1230 if (len + 1 == (size_t) node->len && node->auto_redirect) {
1244 r->loc_conf = clcfp[i]->loc_conf; 1231
1245 1232 r->loc_conf = (node->exact) ? node->exact->loc_conf:
1246 return NGX_HTTP_LOCATION_REGEX; 1233 node->inclusive->loc_conf;
1247 } 1234 rv = NGX_DONE;
1248 1235 }
1249 #endif /* NGX_PCRE */ 1236
1250 1237 node = node->left;
1251 return NGX_OK; 1238 }
1252 } 1239 }
1253 1240
1254 1241
1255 ngx_int_t 1242 ngx_int_t
1256 ngx_http_set_content_type(ngx_http_request_t *r) 1243 ngx_http_set_content_type(ngx_http_request_t *r)
1894 1881
1895 1882
1896 ngx_int_t 1883 ngx_int_t
1897 ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name) 1884 ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
1898 { 1885 {
1899 ngx_uint_t i;
1900 ngx_http_core_srv_conf_t *cscf; 1886 ngx_http_core_srv_conf_t *cscf;
1901 ngx_http_core_loc_conf_t **clcfp; 1887 ngx_http_core_loc_conf_t **clcfp;
1902 ngx_http_core_main_conf_t *cmcf; 1888 ngx_http_core_main_conf_t *cmcf;
1903 1889
1904 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); 1890 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
1905 1891
1906 clcfp = cscf->locations.elts; 1892 for (clcfp = cscf->named_locations; *clcfp; clcfp++) {
1907 1893
1908 for (i = cscf->named_start; i < cscf->locations.nelts; i++) { 1894 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1909 1895 "test location: \"%V\"", &(*clcfp)->name);
1910 if (name->len != clcfp[i]->name.len 1896
1911 || ngx_strncmp(name->data, clcfp[i]->name.data, name->len) != 0) 1897 if (name->len != (*clcfp)->name.len
1898 || ngx_strncmp(name->data, (*clcfp)->name.data, name->len) != 0)
1912 { 1899 {
1913 continue; 1900 continue;
1914 } 1901 }
1915 1902
1916 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 1903 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1917 "named location: %V \"%V?%V\"", name, &r->uri, &r->args); 1904 "using location: %V \"%V?%V\"", name, &r->uri, &r->args);
1918 1905
1919 r->internal = 1; 1906 r->internal = 1;
1920 r->content_handler = NULL; 1907 r->content_handler = NULL;
1921 r->loc_conf = clcfp[i]->loc_conf; 1908 r->loc_conf = (*clcfp)->loc_conf;
1922 1909
1923 ngx_http_update_location_config(r); 1910 ngx_http_update_location_config(r);
1924 1911
1925 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); 1912 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
1926 1913
1933 1920
1934 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 1921 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1935 "could not find named location \"%V\"", name); 1922 "could not find named location \"%V\"", name);
1936 1923
1937 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 1924 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1925
1938 return NGX_DONE; 1926 return NGX_DONE;
1939 } 1927 }
1940 1928
1941 1929
1942 ngx_http_cleanup_t * 1930 ngx_http_cleanup_t *
1981 ngx_uint_t i; 1969 ngx_uint_t i;
1982 ngx_conf_t pcf; 1970 ngx_conf_t pcf;
1983 ngx_http_module_t *module; 1971 ngx_http_module_t *module;
1984 ngx_http_conf_ctx_t *ctx, *http_ctx; 1972 ngx_http_conf_ctx_t *ctx, *http_ctx;
1985 ngx_http_core_srv_conf_t *cscf, **cscfp; 1973 ngx_http_core_srv_conf_t *cscf, **cscfp;
1986 ngx_http_core_loc_conf_t **clcfp;
1987 ngx_http_core_main_conf_t *cmcf; 1974 ngx_http_core_main_conf_t *cmcf;
1988 1975
1989 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)); 1976 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
1990 if (ctx == NULL) { 1977 if (ctx == NULL) {
1991 return NGX_CONF_ERROR; 1978 return NGX_CONF_ERROR;
2058 cf->cmd_type = NGX_HTTP_SRV_CONF; 2045 cf->cmd_type = NGX_HTTP_SRV_CONF;
2059 2046
2060 rv = ngx_conf_parse(cf, NULL); 2047 rv = ngx_conf_parse(cf, NULL);
2061 2048
2062 *cf = pcf; 2049 *cf = pcf;
2063
2064 if (rv != NGX_CONF_OK) {
2065 return rv;
2066 }
2067
2068 ngx_sort(cscf->locations.elts, (size_t) cscf->locations.nelts,
2069 sizeof(ngx_http_core_loc_conf_t *), ngx_http_core_cmp_locations);
2070
2071 clcfp = cscf->locations.elts;
2072
2073 #if (NGX_PCRE)
2074
2075 cscf->regex_start = cscf->locations.nelts;
2076
2077 for (i = 0; i < cscf->locations.nelts; i++) {
2078 if (clcfp[i]->regex) {
2079 cscf->regex_start = i;
2080 break;
2081 }
2082 }
2083
2084 #endif
2085
2086 cscf->named_start = cscf->locations.nelts;
2087
2088 for (i = 0; i < cscf->locations.nelts; i++) {
2089 if (clcfp[i]->named) {
2090 cscf->named_start = i;
2091 break;
2092 }
2093 }
2094 2050
2095 return rv; 2051 return rv;
2096 } 2052 }
2097 2053
2098 2054
2103 ngx_uint_t i; 2059 ngx_uint_t i;
2104 ngx_str_t *value; 2060 ngx_str_t *value;
2105 ngx_conf_t save; 2061 ngx_conf_t save;
2106 ngx_http_module_t *module; 2062 ngx_http_module_t *module;
2107 ngx_http_conf_ctx_t *ctx, *pctx; 2063 ngx_http_conf_ctx_t *ctx, *pctx;
2108 ngx_http_core_srv_conf_t *cscf; 2064 ngx_http_core_loc_conf_t *clcf, *pclcf;
2109 ngx_http_core_loc_conf_t *clcf, *pclcf, **clcfp;
2110 2065
2111 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)); 2066 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
2112 if (ctx == NULL) { 2067 if (ctx == NULL) {
2113 return NGX_CONF_ERROR; 2068 return NGX_CONF_ERROR;
2114 } 2069 }
2199 } 2154 }
2200 } 2155 }
2201 2156
2202 pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index]; 2157 pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];
2203 2158
2204 if (pclcf->name.len == 0) { 2159 if (pclcf->name.len) {
2205 cscf = ctx->srv_conf[ngx_http_core_module.ctx_index]; 2160
2206 2161 /* nested location */
2207 clcfp = ngx_array_push(&cscf->locations); 2162
2208 if (clcfp == NULL) {
2209 return NGX_CONF_ERROR;
2210 }
2211
2212 } else {
2213 #if 0 2163 #if 0
2214 clcf->prev_location = pclcf; 2164 clcf->prev_location = pclcf;
2215 #endif 2165 #endif
2216 2166
2217 if (pclcf->exact_match) { 2167 if (pclcf->exact_match) {
2225 if (pclcf->named) { 2175 if (pclcf->named) {
2226 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 2176 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2227 "location \"%V\" could not be inside " 2177 "location \"%V\" could not be inside "
2228 "the named location \"%V\"", 2178 "the named location \"%V\"",
2229 &clcf->name, &pclcf->name); 2179 &clcf->name, &pclcf->name);
2180 return NGX_CONF_ERROR;
2181 }
2182
2183 if (clcf->named) {
2184 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2185 "named location \"%V\" must be "
2186 "on server level only",
2187 &clcf->name);
2230 return NGX_CONF_ERROR; 2188 return NGX_CONF_ERROR;
2231 } 2189 }
2232 2190
2233 #if (NGX_PCRE) 2191 #if (NGX_PCRE)
2234 if (clcf->regex == NULL 2192 if (clcf->regex == NULL
2242 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 2200 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2243 "location \"%V\" is outside location \"%V\"", 2201 "location \"%V\" is outside location \"%V\"",
2244 &clcf->name, &pclcf->name); 2202 &clcf->name, &pclcf->name);
2245 return NGX_CONF_ERROR; 2203 return NGX_CONF_ERROR;
2246 } 2204 }
2247 2205 }
2248 if (pclcf->locations == NULL) { 2206
2249 pclcf->locations = ngx_array_create(cf->pool, 2, sizeof(void *)); 2207 if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
2250 2208 return NGX_CONF_ERROR;
2251 if (pclcf->locations == NULL) { 2209 }
2252 return NGX_CONF_ERROR;
2253 }
2254 }
2255
2256 clcfp = ngx_array_push(pclcf->locations);
2257 if (clcfp == NULL) {
2258 return NGX_CONF_ERROR;
2259 }
2260 }
2261
2262 *clcfp = clcf;
2263 2210
2264 save = *cf; 2211 save = *cf;
2265 cf->ctx = ctx; 2212 cf->ctx = ctx;
2266 cf->cmd_type = NGX_HTTP_LOC_CONF; 2213 cf->cmd_type = NGX_HTTP_LOC_CONF;
2267 2214
2268 rv = ngx_conf_parse(cf, NULL); 2215 rv = ngx_conf_parse(cf, NULL);
2269 2216
2270 *cf = save; 2217 *cf = save;
2271 2218
2272 if (rv != NGX_CONF_OK) {
2273 return rv;
2274 }
2275
2276 if (clcf->locations == NULL) {
2277 return rv;
2278 }
2279
2280 ngx_sort(clcf->locations->elts, (size_t) clcf->locations->nelts,
2281 sizeof(ngx_http_core_loc_conf_t *), ngx_http_core_cmp_locations);
2282
2283 #if (NGX_PCRE)
2284
2285 clcf->regex_start = clcf->locations->nelts;
2286 clcfp = clcf->locations->elts;
2287
2288 for (i = 0; i < clcf->locations->nelts; i++) {
2289 if (clcfp[i]->regex) {
2290 clcf->regex_start = i;
2291 break;
2292 }
2293 }
2294
2295 #endif
2296
2297 return rv; 2219 return rv;
2298 }
2299
2300
2301 static ngx_int_t
2302 ngx_http_core_cmp_locations(const void *one, const void *two)
2303 {
2304 ngx_int_t rc;
2305 ngx_http_core_loc_conf_t *first, *second;
2306
2307 first = *(ngx_http_core_loc_conf_t **) one;
2308 second = *(ngx_http_core_loc_conf_t **) two;
2309
2310 if (first->named && !second->named) {
2311 /* shift named locations to the end */
2312 return 1;
2313 }
2314
2315 if (!first->named && second->named) {
2316 /* shift named locations to the end */
2317 return -1;
2318 }
2319
2320 if (first->named && second->named) {
2321 return ngx_strcmp(first->name.data, second->name.data);
2322 }
2323
2324 if (first->noname && !second->noname) {
2325 /* shift no named locations to the end */
2326 return 1;
2327 }
2328
2329 if (!first->noname && second->noname) {
2330 /* shift no named locations to the end */
2331 return -1;
2332 }
2333
2334 if (first->noname || second->noname) {
2335 /* do not sort no named locations */
2336 return 0;
2337 }
2338
2339 #if (NGX_PCRE)
2340
2341 if (first->regex && !second->regex) {
2342 /* shift the regex matches to the end */
2343 return 1;
2344 }
2345
2346 if (!first->regex && second->regex) {
2347 /* shift the regex matches to the end */
2348 return -1;
2349 }
2350
2351 if (first->regex || second->regex) {
2352 /* do not sort the regex matches */
2353 return 0;
2354 }
2355
2356 #endif
2357
2358 rc = ngx_strcmp(first->name.data, second->name.data);
2359
2360 if (rc == 0 && second->exact_match) {
2361 /* an exact match must be before the same inclusive one */
2362 return 1;
2363 }
2364
2365 return rc;
2366 } 2220 }
2367 2221
2368 2222
2369 static char * 2223 static char *
2370 ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 2224 ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2539 * set by ngx_pcalloc(): 2393 * set by ngx_pcalloc():
2540 * 2394 *
2541 * conf->client_large_buffers.num = 0; 2395 * conf->client_large_buffers.num = 0;
2542 */ 2396 */
2543 2397
2544 if (ngx_array_init(&cscf->locations, cf->pool, 4, sizeof(void *))
2545 == NGX_ERROR)
2546 {
2547 return NGX_CONF_ERROR;
2548 }
2549
2550 if (ngx_array_init(&cscf->listen, cf->pool, 4, sizeof(ngx_http_listen_t)) 2398 if (ngx_array_init(&cscf->listen, cf->pool, 4, sizeof(ngx_http_listen_t))
2551 == NGX_ERROR) 2399 == NGX_ERROR)
2552 { 2400 {
2553 return NGX_CONF_ERROR; 2401 return NGX_CONF_ERROR;
2554 } 2402 }
2562 2410
2563 cscf->connection_pool_size = NGX_CONF_UNSET_SIZE; 2411 cscf->connection_pool_size = NGX_CONF_UNSET_SIZE;
2564 cscf->request_pool_size = NGX_CONF_UNSET_SIZE; 2412 cscf->request_pool_size = NGX_CONF_UNSET_SIZE;
2565 cscf->client_header_timeout = NGX_CONF_UNSET_MSEC; 2413 cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
2566 cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE; 2414 cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
2567 cscf->optimize_server_names = NGX_CONF_UNSET;
2568 cscf->ignore_invalid_headers = NGX_CONF_UNSET; 2415 cscf->ignore_invalid_headers = NGX_CONF_UNSET;
2569 cscf->merge_slashes = NGX_CONF_UNSET; 2416 cscf->merge_slashes = NGX_CONF_UNSET;
2570 2417
2571 return cscf; 2418 return cscf;
2572 } 2419 }
2637 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 2484 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2638 "the \"large_client_header_buffers\" size must be " 2485 "the \"large_client_header_buffers\" size must be "
2639 "equal to or bigger than \"connection_pool_size\""); 2486 "equal to or bigger than \"connection_pool_size\"");
2640 return NGX_CONF_ERROR; 2487 return NGX_CONF_ERROR;
2641 } 2488 }
2642
2643 ngx_conf_merge_value(conf->optimize_server_names,
2644 prev->optimize_server_names, 1);
2645 2489
2646 ngx_conf_merge_value(conf->ignore_invalid_headers, 2490 ngx_conf_merge_value(conf->ignore_invalid_headers,
2647 prev->ignore_invalid_headers, 1); 2491 prev->ignore_invalid_headers, 1);
2648 2492
2649 ngx_conf_merge_value(conf->merge_slashes, prev->merge_slashes, 1); 2493 ngx_conf_merge_value(conf->merge_slashes, prev->merge_slashes, 1);
3343 3187
3344 3188
3345 static char * 3189 static char *
3346 ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 3190 ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3347 { 3191 {
3348 ngx_http_core_loc_conf_t *clcf = conf; 3192 ngx_http_core_loc_conf_t *pclcf = conf;
3349 3193
3350 char *rv; 3194 char *rv;
3351 void *mconf; 3195 void *mconf;
3352 ngx_str_t *value; 3196 ngx_str_t *value;
3353 ngx_uint_t i; 3197 ngx_uint_t i;
3354 ngx_conf_t save; 3198 ngx_conf_t save;
3355 ngx_http_module_t *module; 3199 ngx_http_module_t *module;
3356 ngx_http_conf_ctx_t *ctx, *pctx; 3200 ngx_http_conf_ctx_t *ctx, *pctx;
3357 ngx_http_method_name_t *name; 3201 ngx_http_method_name_t *name;
3358 ngx_http_core_loc_conf_t *lcf, **clcfp; 3202 ngx_http_core_loc_conf_t *clcf;
3359 3203
3360 if (clcf->limit_except) { 3204 if (pclcf->limit_except) {
3361 return "duplicate"; 3205 return "duplicate";
3362 } 3206 }
3363 3207
3364 clcf->limit_except = 0xffffffff; 3208 pclcf->limit_except = 0xffffffff;
3365 3209
3366 value = cf->args->elts; 3210 value = cf->args->elts;
3367 3211
3368 for (i = 1; i < cf->args->nelts; i++) { 3212 for (i = 1; i < cf->args->nelts; i++) {
3369 for (name = ngx_methods_names; name->name; name++) { 3213 for (name = ngx_methods_names; name->name; name++) {
3370 3214
3371 if (ngx_strcasecmp(value[i].data, name->name) == 0) { 3215 if (ngx_strcasecmp(value[i].data, name->name) == 0) {
3372 clcf->limit_except &= name->method; 3216 pclcf->limit_except &= name->method;
3373 goto next; 3217 goto next;
3374 } 3218 }
3375 } 3219 }
3376 3220
3377 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 3221 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3380 3224
3381 next: 3225 next:
3382 continue; 3226 continue;
3383 } 3227 }
3384 3228
3385 if (!(clcf->limit_except & NGX_HTTP_GET)) { 3229 if (!(pclcf->limit_except & NGX_HTTP_GET)) {
3386 clcf->limit_except &= (uint32_t) ~NGX_HTTP_HEAD; 3230 pclcf->limit_except &= (uint32_t) ~NGX_HTTP_HEAD;
3387 } 3231 }
3388 3232
3389 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)); 3233 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
3390 if (ctx == NULL) { 3234 if (ctx == NULL) {
3391 return NGX_CONF_ERROR; 3235 return NGX_CONF_ERROR;
3417 ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf; 3261 ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
3418 } 3262 }
3419 } 3263 }
3420 3264
3421 3265
3422 lcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; 3266 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
3423 clcf->limit_except_loc_conf = ctx->loc_conf; 3267 pclcf->limit_except_loc_conf = ctx->loc_conf;
3424 lcf->loc_conf = ctx->loc_conf; 3268 clcf->loc_conf = ctx->loc_conf;
3425 lcf->name = clcf->name; 3269 clcf->name = pclcf->name;
3426 lcf->noname = 1; 3270 clcf->noname = 1;
3427 3271
3428 if (clcf->locations == NULL) { 3272 if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
3429 clcf->locations = ngx_array_create(cf->pool, 2, sizeof(void *));
3430 if (clcf->locations == NULL) {
3431 return NGX_CONF_ERROR;
3432 }
3433 }
3434
3435 clcfp = ngx_array_push(clcf->locations);
3436 if (clcfp == NULL) {
3437 return NGX_CONF_ERROR; 3273 return NGX_CONF_ERROR;
3438 } 3274 }
3439
3440 *clcfp = lcf;
3441
3442 3275
3443 save = *cf; 3276 save = *cf;
3444 cf->ctx = ctx; 3277 cf->ctx = ctx;
3445 cf->cmd_type = NGX_HTTP_LMT_CONF; 3278 cf->cmd_type = NGX_HTTP_LMT_CONF;
3446 3279