comparison src/http/ngx_http_core_module.c @ 2407:16d1236bc298

try_files
author Igor Sysoev <igor@sysoev.ru>
date Mon, 15 Dec 2008 10:56:48 +0000
parents dca164c4a868
children 4876c3966fbd
comparison
equal deleted inserted replaced
2406:008777fa59e0 2407:16d1236bc298
55 static char *ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, 55 static char *ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd,
56 void *conf); 56 void *conf);
57 static char *ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd, 57 static char *ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd,
58 void *conf); 58 void *conf);
59 static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, 59 static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
60 void *conf);
61 static char *ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd,
60 void *conf); 62 void *conf);
61 static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, 63 static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
62 void *conf); 64 void *conf);
63 static char *ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, 65 static char *ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd,
64 void *conf); 66 void *conf);
537 ngx_http_core_error_page, 539 ngx_http_core_error_page,
538 NGX_HTTP_LOC_CONF_OFFSET, 540 NGX_HTTP_LOC_CONF_OFFSET,
539 0, 541 0,
540 NULL }, 542 NULL },
541 543
544 { ngx_string("try_files"),
545 NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,
546 ngx_http_core_try_files,
547 NGX_HTTP_LOC_CONF_OFFSET,
548 0,
549 NULL },
550
542 { ngx_string("post_action"), 551 { ngx_string("post_action"),
543 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF 552 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
544 |NGX_CONF_TAKE1, 553 |NGX_CONF_TAKE1,
545 ngx_conf_set_str_slot, 554 ngx_conf_set_str_slot,
546 NGX_HTTP_LOC_CONF_OFFSET, 555 NGX_HTTP_LOC_CONF_OFFSET,
1030 return NGX_AGAIN; 1039 return NGX_AGAIN;
1031 } 1040 }
1032 1041
1033 1042
1034 ngx_int_t 1043 ngx_int_t
1044 ngx_http_core_try_files_phase(ngx_http_request_t *r,
1045 ngx_http_phase_handler_t *ph)
1046 {
1047 size_t len, root, alias;
1048 ssize_t reserve, allocated;
1049 u_char *p, *name;
1050 ngx_str_t path;
1051 ngx_http_try_file_t *tf;
1052 ngx_open_file_info_t of;
1053 ngx_http_script_code_pt code;
1054 ngx_http_script_engine_t e;
1055 ngx_http_core_loc_conf_t *clcf;
1056 ngx_http_script_len_code_pt lcode;
1057
1058 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1059 "try files phase: %ui", r->phase_handler);
1060
1061 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1062
1063 if (clcf->try_files == NULL) {
1064 r->phase_handler++;
1065 return NGX_AGAIN;
1066 }
1067
1068 allocated = 0;
1069 root = 0;
1070 name = NULL;
1071 path.len = 0;
1072 path.data = NULL;
1073
1074 tf = clcf->try_files;
1075
1076 alias = clcf->alias ? clcf->name.len : 0;
1077
1078 for ( ;; ) {
1079
1080 if (tf->lengths) {
1081 ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
1082
1083 e.ip = tf->lengths->elts;
1084 e.request = r;
1085 e.flushed = 1;
1086
1087 /* 1 is for terminating '\0' as in static names */
1088 len = 1;
1089
1090 while (*(uintptr_t *) e.ip) {
1091 lcode = *(ngx_http_script_len_code_pt *) e.ip;
1092 len += lcode(&e);
1093 }
1094
1095 } else {
1096 len = tf->name.len;
1097 }
1098
1099 reserve = len - r->uri.len;
1100
1101 /* 16 bytes are preallocation */
1102 reserve = reserve < 16 ? 16 : reserve + 16;
1103
1104 reserve += alias;
1105
1106 if (reserve > allocated) {
1107
1108 /* we just need to allocate path and to copy a root */
1109
1110 if (ngx_http_map_uri_to_path(r, &path, &root, reserve) == NULL) {
1111 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1112 return NGX_OK;
1113 }
1114
1115 name = path.data + root;
1116 allocated = path.len - root - (r->uri.len - alias);
1117 }
1118
1119 if (tf->values == NULL) {
1120
1121 /* tf->name.len includes the terminating '\0' */
1122
1123 ngx_memcpy(name, tf->name.data, tf->name.len);
1124
1125 path.len = (name + tf->name.len - 1) - path.data;
1126
1127 } else {
1128 e.ip = tf->values->elts;
1129 e.pos = name;
1130
1131 while (*(uintptr_t *) e.ip) {
1132 code = *(ngx_http_script_code_pt *) e.ip;
1133 code((ngx_http_script_engine_t *) &e);
1134 }
1135
1136 path.len = e.pos - path.data;
1137
1138 *e.pos++ = '\0';
1139
1140 if (alias && ngx_strncmp(name, clcf->name.data, alias) == 0) {
1141 ngx_memcpy(name, name + alias, len - alias);
1142 path.len -= alias;
1143 }
1144 }
1145
1146 tf++;
1147
1148 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1149 "try to use file: \"%s\"", name);
1150
1151 if (tf->lengths == NULL && tf->name.len == 0) {
1152
1153 path.len -= root;
1154 path.data += root;
1155
1156 if (path.data[0] == '@') {
1157 (void) ngx_http_named_location(r, &path);
1158
1159 } else {
1160 (void) ngx_http_internal_redirect(r, &path, NULL);
1161 }
1162
1163 return NGX_OK;
1164 }
1165
1166 ngx_memzero(&of, sizeof(ngx_open_file_info_t));
1167
1168 of.directio = clcf->directio;
1169 of.valid = clcf->open_file_cache_valid;
1170 of.min_uses = clcf->open_file_cache_min_uses;
1171 of.errors = clcf->open_file_cache_errors;
1172 of.events = clcf->open_file_cache_events;
1173
1174 if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
1175 != NGX_OK)
1176 {
1177 if (of.err != NGX_ENOENT && of.err != NGX_ENOTDIR) {
1178 ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
1179 ngx_open_file_n " \"%s\" failed", path.data);
1180 }
1181
1182 continue;
1183 }
1184
1185 path.len -= root;
1186 path.data += root;
1187
1188 if (!alias) {
1189 r->uri = path;
1190
1191 } else {
1192 r->uri.len = alias + path.len;
1193 r->uri.data = ngx_pnalloc(r->pool, r->uri.len);
1194 if (r->uri.data == NULL) {
1195 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1196 return NGX_OK;
1197 }
1198
1199 p = ngx_copy(r->uri.data, clcf->name.data, alias);
1200 ngx_memcpy(p, name, path.len);
1201 }
1202
1203 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1204 "try file uri: \"%V\"", &r->uri);
1205
1206 r->phase_handler++;
1207 return NGX_AGAIN;
1208 }
1209
1210 /* not reached */
1211 }
1212
1213
1214 ngx_int_t
1035 ngx_http_core_content_phase(ngx_http_request_t *r, 1215 ngx_http_core_content_phase(ngx_http_request_t *r,
1036 ngx_http_phase_handler_t *ph) 1216 ngx_http_phase_handler_t *ph)
1037 { 1217 {
1038 size_t root; 1218 size_t root;
1039 ngx_int_t rc; 1219 ngx_int_t rc;
2708 * lcf->post_action = { 0, NULL }; 2888 * lcf->post_action = { 0, NULL };
2709 * lcf->types = NULL; 2889 * lcf->types = NULL;
2710 * lcf->default_type = { 0, NULL }; 2890 * lcf->default_type = { 0, NULL };
2711 * lcf->err_log = NULL; 2891 * lcf->err_log = NULL;
2712 * lcf->error_pages = NULL; 2892 * lcf->error_pages = NULL;
2893 * lcf->try_files = NULL;
2713 * lcf->client_body_path = NULL; 2894 * lcf->client_body_path = NULL;
2714 * lcf->regex = NULL; 2895 * lcf->regex = NULL;
2715 * lcf->exact_match = 0; 2896 * lcf->exact_match = 0;
2716 * lcf->auto_redirect = 0; 2897 * lcf->auto_redirect = 0;
2717 * lcf->alias = 0; 2898 * lcf->alias = 0;
3683 return NGX_CONF_OK; 3864 return NGX_CONF_OK;
3684 } 3865 }
3685 3866
3686 3867
3687 static char * 3868 static char *
3869 ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3870 {
3871 ngx_http_core_loc_conf_t *clcf = conf;
3872
3873 ngx_str_t *value;
3874 ngx_uint_t i, n;
3875 ngx_http_try_file_t *tf;
3876 ngx_http_script_compile_t sc;
3877 ngx_http_core_main_conf_t *cmcf;
3878
3879 if (clcf->try_files) {
3880 return "is duplicate";
3881 }
3882
3883 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
3884
3885 cmcf->try_files = 1;
3886
3887 tf = ngx_pcalloc(cf->pool, cf->args->nelts * sizeof(ngx_http_try_file_t));
3888 if (tf == NULL) {
3889 return NGX_CONF_ERROR;
3890 }
3891
3892 clcf->try_files = tf;
3893
3894 value = cf->args->elts;
3895
3896 for (i = 0; i < cf->args->nelts - 1; i++) {
3897
3898 tf[i].name = value[i + 1];
3899
3900 n = ngx_http_script_variables_count(&tf[i].name);
3901
3902 if (n) {
3903 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
3904
3905 sc.cf = cf;
3906 sc.source = &tf[i].name;
3907 sc.lengths = &tf[i].lengths;
3908 sc.values = &tf[i].values;
3909 sc.variables = n;
3910 sc.complete_lengths = 1;
3911 sc.complete_values = 1;
3912
3913 if (ngx_http_script_compile(&sc) != NGX_OK) {
3914 return NGX_CONF_ERROR;
3915 }
3916
3917 } else {
3918 /* add trailing '\0' to length */
3919 tf[i].name.len++;
3920 }
3921 }
3922
3923 return NGX_CONF_OK;
3924 }
3925
3926
3927 static char *
3688 ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 3928 ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3689 { 3929 {
3690 ngx_http_core_loc_conf_t *lcf = conf; 3930 ngx_http_core_loc_conf_t *lcf = conf;
3691 3931
3692 time_t inactive; 3932 time_t inactive;