Mercurial > hg > nginx-vendor-1-0
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 |