Mercurial > hg > nginx-quic
comparison src/http/ngx_http_core_module.c @ 7071:cce6936ed2f4
Precontent phase.
The phase is added instead of the try_files phase. Unlike the old phase, the
new one supports registering multiple handlers. The try_files implementation is
moved to a separate ngx_http_try_files_module, which now registers a precontent
phase handler.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Thu, 20 Jul 2017 15:51:11 +0300 |
parents | 1b068a4e82d8 |
children | 46ebff8c6396 |
comparison
equal
deleted
inserted
replaced
7070:f583559aadc7 | 7071:cce6936ed2f4 |
---|---|
58 static char *ngx_http_core_set_aio(ngx_conf_t *cf, ngx_command_t *cmd, | 58 static char *ngx_http_core_set_aio(ngx_conf_t *cf, ngx_command_t *cmd, |
59 void *conf); | 59 void *conf); |
60 static char *ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd, | 60 static char *ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd, |
61 void *conf); | 61 void *conf); |
62 static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, | 62 static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, |
63 void *conf); | |
64 static char *ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, | |
65 void *conf); | 63 void *conf); |
66 static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, | 64 static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, |
67 void *conf); | 65 void *conf); |
68 static char *ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, | 66 static char *ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, |
69 void *conf); | 67 void *conf); |
647 ngx_http_core_error_page, | 645 ngx_http_core_error_page, |
648 NGX_HTTP_LOC_CONF_OFFSET, | 646 NGX_HTTP_LOC_CONF_OFFSET, |
649 0, | 647 0, |
650 NULL }, | 648 NULL }, |
651 | 649 |
652 { ngx_string("try_files"), | |
653 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE, | |
654 ngx_http_core_try_files, | |
655 NGX_HTTP_LOC_CONF_OFFSET, | |
656 0, | |
657 NULL }, | |
658 | |
659 { ngx_string("post_action"), | 650 { ngx_string("post_action"), |
660 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF | 651 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF |
661 |NGX_CONF_TAKE1, | 652 |NGX_CONF_TAKE1, |
662 ngx_conf_set_str_slot, | 653 ngx_conf_set_str_slot, |
663 NGX_HTTP_LOC_CONF_OFFSET, | 654 NGX_HTTP_LOC_CONF_OFFSET, |
1157 return NGX_AGAIN; | 1148 return NGX_AGAIN; |
1158 } | 1149 } |
1159 | 1150 |
1160 | 1151 |
1161 ngx_int_t | 1152 ngx_int_t |
1162 ngx_http_core_try_files_phase(ngx_http_request_t *r, | |
1163 ngx_http_phase_handler_t *ph) | |
1164 { | |
1165 size_t len, root, alias, reserve, allocated; | |
1166 u_char *p, *name; | |
1167 ngx_str_t path, args; | |
1168 ngx_uint_t test_dir; | |
1169 ngx_http_try_file_t *tf; | |
1170 ngx_open_file_info_t of; | |
1171 ngx_http_script_code_pt code; | |
1172 ngx_http_script_engine_t e; | |
1173 ngx_http_core_loc_conf_t *clcf; | |
1174 ngx_http_script_len_code_pt lcode; | |
1175 | |
1176 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1177 "try files phase: %ui", r->phase_handler); | |
1178 | |
1179 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
1180 | |
1181 if (clcf->try_files == NULL) { | |
1182 r->phase_handler++; | |
1183 return NGX_AGAIN; | |
1184 } | |
1185 | |
1186 allocated = 0; | |
1187 root = 0; | |
1188 name = NULL; | |
1189 /* suppress MSVC warning */ | |
1190 path.data = NULL; | |
1191 | |
1192 tf = clcf->try_files; | |
1193 | |
1194 alias = clcf->alias; | |
1195 | |
1196 for ( ;; ) { | |
1197 | |
1198 if (tf->lengths) { | |
1199 ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); | |
1200 | |
1201 e.ip = tf->lengths->elts; | |
1202 e.request = r; | |
1203 | |
1204 /* 1 is for terminating '\0' as in static names */ | |
1205 len = 1; | |
1206 | |
1207 while (*(uintptr_t *) e.ip) { | |
1208 lcode = *(ngx_http_script_len_code_pt *) e.ip; | |
1209 len += lcode(&e); | |
1210 } | |
1211 | |
1212 } else { | |
1213 len = tf->name.len; | |
1214 } | |
1215 | |
1216 if (!alias) { | |
1217 reserve = len > r->uri.len ? len - r->uri.len : 0; | |
1218 | |
1219 } else if (alias == NGX_MAX_SIZE_T_VALUE) { | |
1220 reserve = len; | |
1221 | |
1222 } else { | |
1223 reserve = len > r->uri.len - alias ? len - (r->uri.len - alias) : 0; | |
1224 } | |
1225 | |
1226 if (reserve > allocated || !allocated) { | |
1227 | |
1228 /* 16 bytes are preallocation */ | |
1229 allocated = reserve + 16; | |
1230 | |
1231 if (ngx_http_map_uri_to_path(r, &path, &root, allocated) == NULL) { | |
1232 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1233 return NGX_OK; | |
1234 } | |
1235 | |
1236 name = path.data + root; | |
1237 } | |
1238 | |
1239 if (tf->values == NULL) { | |
1240 | |
1241 /* tf->name.len includes the terminating '\0' */ | |
1242 | |
1243 ngx_memcpy(name, tf->name.data, tf->name.len); | |
1244 | |
1245 path.len = (name + tf->name.len - 1) - path.data; | |
1246 | |
1247 } else { | |
1248 e.ip = tf->values->elts; | |
1249 e.pos = name; | |
1250 e.flushed = 1; | |
1251 | |
1252 while (*(uintptr_t *) e.ip) { | |
1253 code = *(ngx_http_script_code_pt *) e.ip; | |
1254 code((ngx_http_script_engine_t *) &e); | |
1255 } | |
1256 | |
1257 path.len = e.pos - path.data; | |
1258 | |
1259 *e.pos = '\0'; | |
1260 | |
1261 if (alias && alias != NGX_MAX_SIZE_T_VALUE | |
1262 && ngx_strncmp(name, r->uri.data, alias) == 0) | |
1263 { | |
1264 ngx_memmove(name, name + alias, len - alias); | |
1265 path.len -= alias; | |
1266 } | |
1267 } | |
1268 | |
1269 test_dir = tf->test_dir; | |
1270 | |
1271 tf++; | |
1272 | |
1273 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1274 "trying to use %s: \"%s\" \"%s\"", | |
1275 test_dir ? "dir" : "file", name, path.data); | |
1276 | |
1277 if (tf->lengths == NULL && tf->name.len == 0) { | |
1278 | |
1279 if (tf->code) { | |
1280 ngx_http_finalize_request(r, tf->code); | |
1281 return NGX_OK; | |
1282 } | |
1283 | |
1284 path.len -= root; | |
1285 path.data += root; | |
1286 | |
1287 if (path.data[0] == '@') { | |
1288 (void) ngx_http_named_location(r, &path); | |
1289 | |
1290 } else { | |
1291 ngx_http_split_args(r, &path, &args); | |
1292 | |
1293 (void) ngx_http_internal_redirect(r, &path, &args); | |
1294 } | |
1295 | |
1296 ngx_http_finalize_request(r, NGX_DONE); | |
1297 return NGX_OK; | |
1298 } | |
1299 | |
1300 ngx_memzero(&of, sizeof(ngx_open_file_info_t)); | |
1301 | |
1302 of.read_ahead = clcf->read_ahead; | |
1303 of.directio = clcf->directio; | |
1304 of.valid = clcf->open_file_cache_valid; | |
1305 of.min_uses = clcf->open_file_cache_min_uses; | |
1306 of.test_only = 1; | |
1307 of.errors = clcf->open_file_cache_errors; | |
1308 of.events = clcf->open_file_cache_events; | |
1309 | |
1310 if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) { | |
1311 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1312 return NGX_OK; | |
1313 } | |
1314 | |
1315 if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) | |
1316 != NGX_OK) | |
1317 { | |
1318 if (of.err == 0) { | |
1319 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1320 return NGX_OK; | |
1321 } | |
1322 | |
1323 if (of.err != NGX_ENOENT | |
1324 && of.err != NGX_ENOTDIR | |
1325 && of.err != NGX_ENAMETOOLONG) | |
1326 { | |
1327 ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err, | |
1328 "%s \"%s\" failed", of.failed, path.data); | |
1329 } | |
1330 | |
1331 continue; | |
1332 } | |
1333 | |
1334 if (of.is_dir != test_dir) { | |
1335 continue; | |
1336 } | |
1337 | |
1338 path.len -= root; | |
1339 path.data += root; | |
1340 | |
1341 if (!alias) { | |
1342 r->uri = path; | |
1343 | |
1344 } else if (alias == NGX_MAX_SIZE_T_VALUE) { | |
1345 if (!test_dir) { | |
1346 r->uri = path; | |
1347 r->add_uri_to_alias = 1; | |
1348 } | |
1349 | |
1350 } else { | |
1351 name = r->uri.data; | |
1352 | |
1353 r->uri.len = alias + path.len; | |
1354 r->uri.data = ngx_pnalloc(r->pool, r->uri.len); | |
1355 if (r->uri.data == NULL) { | |
1356 r->uri.len = 0; | |
1357 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1358 return NGX_OK; | |
1359 } | |
1360 | |
1361 p = ngx_copy(r->uri.data, name, alias); | |
1362 ngx_memcpy(p, path.data, path.len); | |
1363 } | |
1364 | |
1365 ngx_http_set_exten(r); | |
1366 | |
1367 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1368 "try file uri: \"%V\"", &r->uri); | |
1369 | |
1370 r->phase_handler++; | |
1371 return NGX_AGAIN; | |
1372 } | |
1373 | |
1374 /* not reached */ | |
1375 } | |
1376 | |
1377 | |
1378 ngx_int_t | |
1379 ngx_http_core_content_phase(ngx_http_request_t *r, | 1153 ngx_http_core_content_phase(ngx_http_request_t *r, |
1380 ngx_http_phase_handler_t *ph) | 1154 ngx_http_phase_handler_t *ph) |
1381 { | 1155 { |
1382 size_t root; | 1156 size_t root; |
1383 ngx_int_t rc; | 1157 ngx_int_t rc; |
3559 * clcf->post_action = { 0, NULL }; | 3333 * clcf->post_action = { 0, NULL }; |
3560 * clcf->types = NULL; | 3334 * clcf->types = NULL; |
3561 * clcf->default_type = { 0, NULL }; | 3335 * clcf->default_type = { 0, NULL }; |
3562 * clcf->error_log = NULL; | 3336 * clcf->error_log = NULL; |
3563 * clcf->error_pages = NULL; | 3337 * clcf->error_pages = NULL; |
3564 * clcf->try_files = NULL; | |
3565 * clcf->client_body_path = NULL; | 3338 * clcf->client_body_path = NULL; |
3566 * clcf->regex = NULL; | 3339 * clcf->regex = NULL; |
3567 * clcf->exact_match = 0; | 3340 * clcf->exact_match = 0; |
3568 * clcf->auto_redirect = 0; | 3341 * clcf->auto_redirect = 0; |
3569 * clcf->alias = 0; | 3342 * clcf->alias = 0; |
4883 return NGX_CONF_OK; | 4656 return NGX_CONF_OK; |
4884 } | 4657 } |
4885 | 4658 |
4886 | 4659 |
4887 static char * | 4660 static char * |
4888 ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
4889 { | |
4890 ngx_http_core_loc_conf_t *clcf = conf; | |
4891 | |
4892 ngx_str_t *value; | |
4893 ngx_int_t code; | |
4894 ngx_uint_t i, n; | |
4895 ngx_http_try_file_t *tf; | |
4896 ngx_http_script_compile_t sc; | |
4897 ngx_http_core_main_conf_t *cmcf; | |
4898 | |
4899 if (clcf->try_files) { | |
4900 return "is duplicate"; | |
4901 } | |
4902 | |
4903 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | |
4904 | |
4905 cmcf->try_files = 1; | |
4906 | |
4907 tf = ngx_pcalloc(cf->pool, cf->args->nelts * sizeof(ngx_http_try_file_t)); | |
4908 if (tf == NULL) { | |
4909 return NGX_CONF_ERROR; | |
4910 } | |
4911 | |
4912 clcf->try_files = tf; | |
4913 | |
4914 value = cf->args->elts; | |
4915 | |
4916 for (i = 0; i < cf->args->nelts - 1; i++) { | |
4917 | |
4918 tf[i].name = value[i + 1]; | |
4919 | |
4920 if (tf[i].name.len > 0 | |
4921 && tf[i].name.data[tf[i].name.len - 1] == '/' | |
4922 && i + 2 < cf->args->nelts) | |
4923 { | |
4924 tf[i].test_dir = 1; | |
4925 tf[i].name.len--; | |
4926 tf[i].name.data[tf[i].name.len] = '\0'; | |
4927 } | |
4928 | |
4929 n = ngx_http_script_variables_count(&tf[i].name); | |
4930 | |
4931 if (n) { | |
4932 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); | |
4933 | |
4934 sc.cf = cf; | |
4935 sc.source = &tf[i].name; | |
4936 sc.lengths = &tf[i].lengths; | |
4937 sc.values = &tf[i].values; | |
4938 sc.variables = n; | |
4939 sc.complete_lengths = 1; | |
4940 sc.complete_values = 1; | |
4941 | |
4942 if (ngx_http_script_compile(&sc) != NGX_OK) { | |
4943 return NGX_CONF_ERROR; | |
4944 } | |
4945 | |
4946 } else { | |
4947 /* add trailing '\0' to length */ | |
4948 tf[i].name.len++; | |
4949 } | |
4950 } | |
4951 | |
4952 if (tf[i - 1].name.data[0] == '=') { | |
4953 | |
4954 code = ngx_atoi(tf[i - 1].name.data + 1, tf[i - 1].name.len - 2); | |
4955 | |
4956 if (code == NGX_ERROR || code > 999) { | |
4957 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
4958 "invalid code \"%*s\"", | |
4959 tf[i - 1].name.len - 1, tf[i - 1].name.data); | |
4960 return NGX_CONF_ERROR; | |
4961 } | |
4962 | |
4963 tf[i].code = code; | |
4964 } | |
4965 | |
4966 return NGX_CONF_OK; | |
4967 } | |
4968 | |
4969 | |
4970 static char * | |
4971 ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 4661 ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
4972 { | 4662 { |
4973 ngx_http_core_loc_conf_t *clcf = conf; | 4663 ngx_http_core_loc_conf_t *clcf = conf; |
4974 | 4664 |
4975 time_t inactive; | 4665 time_t inactive; |