comparison src/http/modules/ngx_http_index_module.c @ 332:3a91bfeffaba NGINX_0_6_10

nginx 0.6.10 *) Feature: the "open_file_cache", "open_file_cache_retest", and "open_file_cache_errors" directives. *) Bugfix: socket leak; bug appeared in 0.6.7. *) Bugfix: a charset set by the "charset" directive was not appended to the "Content-Type" header set by $r->send_http_header(). *) Bugfix: a segmentation fault might occur in worker process if /dev/poll method was used.
author Igor Sysoev <http://sysoev.ru>
date Mon, 03 Sep 2007 00:00:00 +0400
parents c5c2b2883984
children eae74a780a84
comparison
equal deleted inserted replaced
331:b69d5e83bf82 332:3a91bfeffaba
36 36
37 #define NGX_HTTP_DEFAULT_INDEX "index.html" 37 #define NGX_HTTP_DEFAULT_INDEX "index.html"
38 38
39 39
40 static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r, 40 static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
41 ngx_http_index_ctx_t *ctx); 41 ngx_http_core_loc_conf_t *clcf, ngx_http_index_ctx_t *ctx);
42 static ngx_int_t ngx_http_index_error(ngx_http_request_t *r, 42 static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
43 ngx_http_index_ctx_t *ctx, ngx_err_t err); 43 ngx_http_index_ctx_t *ctx, ngx_err_t err);
44 44
45 static ngx_int_t ngx_http_index_init(ngx_conf_t *cf); 45 static ngx_int_t ngx_http_index_init(ngx_conf_t *cf);
46 static void *ngx_http_index_create_loc_conf(ngx_conf_t *cf); 46 static void *ngx_http_index_create_loc_conf(ngx_conf_t *cf);
56 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, 56 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
57 ngx_http_index_set_index, 57 ngx_http_index_set_index,
58 NGX_HTTP_LOC_CONF_OFFSET, 58 NGX_HTTP_LOC_CONF_OFFSET,
59 0, 59 0,
60 NULL }, 60 NULL },
61
62 #if (NGX_HTTP_CACHE)
63
64 { ngx_string("index_cache"),
65 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE3,
66 ngx_http_set_cache_slot,
67 NGX_HTTP_LOC_CONF_OFFSET,
68 offsetof(ngx_http_index_loc_conf_t, index_cache),
69 NULL },
70
71 #endif
72 61
73 ngx_null_command 62 ngx_null_command
74 }; 63 };
75 64
76 65
118 static ngx_int_t 107 static ngx_int_t
119 ngx_http_index_handler(ngx_http_request_t *r) 108 ngx_http_index_handler(ngx_http_request_t *r)
120 { 109 {
121 u_char *last; 110 u_char *last;
122 size_t len; 111 size_t len;
123 ngx_fd_t fd;
124 ngx_int_t rc; 112 ngx_int_t rc;
125 ngx_err_t err; 113 ngx_str_t path, uri;
126 ngx_str_t uri;
127 ngx_log_t *log; 114 ngx_log_t *log;
128 ngx_uint_t i; 115 ngx_uint_t i;
129 ngx_http_index_t *index; 116 ngx_http_index_t *index;
130 ngx_http_index_ctx_t *ctx; 117 ngx_http_index_ctx_t *ctx;
131 ngx_pool_cleanup_t *cln; 118 ngx_open_file_info_t of;
132 ngx_pool_cleanup_file_t *clnf;
133 ngx_http_script_code_pt code; 119 ngx_http_script_code_pt code;
134 ngx_http_script_engine_t e; 120 ngx_http_script_engine_t e;
135 ngx_http_core_loc_conf_t *clcf; 121 ngx_http_core_loc_conf_t *clcf;
136 ngx_http_index_loc_conf_t *ilcf; 122 ngx_http_index_loc_conf_t *ilcf;
137 ngx_http_script_len_code_pt lcode; 123 ngx_http_script_len_code_pt lcode;
149 return NGX_DECLINED; 135 return NGX_DECLINED;
150 } 136 }
151 137
152 log = r->connection->log; 138 log = r->connection->log;
153 139
140 ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module);
141 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
142
154 /* 143 /*
155 * we use context because the handler supports an async file opening, 144 * we use context because the handler supports an async file opening,
156 * and may be called several times 145 * and may be called several times
157 */ 146 */
158 147
159 ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module);
160
161 ctx = ngx_http_get_module_ctx(r, ngx_http_index_module); 148 ctx = ngx_http_get_module_ctx(r, ngx_http_index_module);
162 if (ctx == NULL) { 149 if (ctx == NULL) {
163 150
164 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_index_ctx_t)); 151 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_index_ctx_t));
165 if (ctx == NULL) { 152 if (ctx == NULL) {
212 } 199 }
213 200
214 ctx->index.data = last; 201 ctx->index.data = last;
215 } 202 }
216 203
204 path.data = ctx->path.data;
205
217 if (index[i].values == NULL) { 206 if (index[i].values == NULL) {
218 207
219 /* index[i].name.len includes the terminating '\0' */ 208 /* index[i].name.len includes the terminating '\0' */
220 209
221 ngx_memcpy(ctx->index.data, index[i].name.data, index[i].name.len); 210 ngx_memcpy(ctx->index.data, index[i].name.data, index[i].name.len);
211
212 path.len = (ctx->index.data + index[i].name.len - 1) - path.data;
222 213
223 } else { 214 } else {
224 e.ip = index[i].values->elts; 215 e.ip = index[i].values->elts;
225 e.pos = ctx->index.data; 216 e.pos = ctx->index.data;
226 217
232 if (*ctx->index.data == '/') { 223 if (*ctx->index.data == '/') {
233 ctx->index.len--; 224 ctx->index.len--;
234 return ngx_http_internal_redirect(r, &ctx->index, &r->args); 225 return ngx_http_internal_redirect(r, &ctx->index, &r->args);
235 } 226 }
236 227
228 path.len = e.pos - path.data;
229
237 *e.pos++ = '\0'; 230 *e.pos++ = '\0';
238 } 231 }
239 232
240 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, 233 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
241 "open index \"%s\"", ctx->path.data); 234 "open index \"%V\"", &path);
242 235
243 cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_pool_cleanup_file_t)); 236 of.test_dir = 0;
244 if (cln == NULL) { 237 of.retest = clcf->open_file_cache_retest;
245 return NGX_HTTP_INTERNAL_SERVER_ERROR; 238 of.errors = clcf->open_file_cache_errors;
246 } 239 of.events = clcf->open_file_cache_events;
247 240
248 fd = ngx_open_file(ctx->path.data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0); 241 rc = ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool);
249 242
250 if (fd == (ngx_fd_t) NGX_AGAIN) { 243 #if 0
244 if (rc == NGX_AGAIN) {
251 ctx->current = i; 245 ctx->current = i;
252 return NGX_AGAIN; 246 return NGX_AGAIN;
253 } 247 }
254 248 #endif
255 if (fd == NGX_INVALID_FILE) { 249
256 err = ngx_errno; 250 if (rc == NGX_ERROR) {
257 251
258 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, err, 252 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, of.err,
259 ngx_open_file_n " \"%s\" failed", ctx->path.data); 253 ngx_open_file_n " \"%s\" failed", ctx->path.data);
260 254
261 if (err == NGX_ENOTDIR) { 255 if (of.err == 0) {
262 return ngx_http_index_error(r, ctx, err); 256 return NGX_HTTP_INTERNAL_SERVER_ERROR;
263 257 }
264 } else if (err == NGX_EACCES) { 258
265 return ngx_http_index_error(r, ctx, err); 259 if (of.err == NGX_ENOTDIR) {
260 return ngx_http_index_error(r, ctx, of.err);
261
262 } else if (of.err == NGX_EACCES) {
263 return ngx_http_index_error(r, ctx, of.err);
266 } 264 }
267 265
268 if (!ctx->tested) { 266 if (!ctx->tested) {
269 rc = ngx_http_index_test_dir(r, ctx); 267 rc = ngx_http_index_test_dir(r, clcf, ctx);
270 268
271 if (rc != NGX_OK) { 269 if (rc != NGX_OK) {
272 return rc; 270 return rc;
273 } 271 }
274 272
275 ctx->tested = 1; 273 ctx->tested = 1;
276 } 274 }
277 275
278 if (err == NGX_ENOENT) { 276 if (of.err == NGX_ENOENT) {
279 continue; 277 continue;
280 } 278 }
281 279
282 ngx_log_error(NGX_LOG_ERR, log, err, 280 ngx_log_error(NGX_LOG_ERR, log, of.err,
283 ngx_open_file_n " \"%s\" failed", ctx->path.data); 281 ngx_open_file_n " \"%s\" failed", ctx->path.data);
284 282
285 return NGX_HTTP_INTERNAL_SERVER_ERROR; 283 return NGX_HTTP_INTERNAL_SERVER_ERROR;
286 } 284 }
287
288 cln->handler = ngx_pool_cleanup_file;
289 clnf = cln->data;
290
291 clnf->fd = fd;
292 clnf->name = ctx->path.data;
293 clnf->log = r->pool->log;
294
295 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
296 285
297 uri.len = r->uri.len + ctx->index.len - 1; 286 uri.len = r->uri.len + ctx->index.len - 1;
298 287
299 if (!clcf->alias) { 288 if (!clcf->alias) {
300 uri.data = ctx->path.data + ctx->root; 289 uri.data = ctx->path.data + ctx->root;
315 return NGX_DECLINED; 304 return NGX_DECLINED;
316 } 305 }
317 306
318 307
319 static ngx_int_t 308 static ngx_int_t
320 ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_index_ctx_t *ctx) 309 ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_core_loc_conf_t *clcf,
321 { 310 ngx_http_index_ctx_t *ctx)
322 u_char c; 311 {
323 ngx_uint_t i; 312 u_char c;
324 ngx_err_t err; 313 ngx_str_t path;
325 ngx_file_info_t fi; 314 ngx_uint_t i;
315 ngx_open_file_info_t of;
326 316
327 c = *(ctx->index.data - 1); 317 c = *(ctx->index.data - 1);
328 i = (c == '/') ? 1 : 0; 318 i = (c == '/') ? 1 : 0;
329 *(ctx->index.data - i) = '\0'; 319 *(ctx->index.data - i) = '\0';
330 320
321 path.len = (ctx->index.data - i) - ctx->path.data;
322 path.data = ctx->path.data;
323
331 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 324 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
332 "http index check dir: \"%s\"", ctx->path.data); 325 "http index check dir: \"%V\"", &path);
333 326
334 if (ngx_file_info(ctx->path.data, &fi) == -1) { 327 of.test_dir = 1;
335 328 of.retest = clcf->open_file_cache_retest;
336 err = ngx_errno; 329 of.errors = clcf->open_file_cache_errors;
337 330
338 if (err == NGX_ENOENT) { 331 if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
339 *(ctx->index.data - i) = c; 332 != NGX_OK)
340 return ngx_http_index_error(r, ctx, err); 333 {
341 } 334 if (of.err) {
342 335
343 ngx_log_error(NGX_LOG_CRIT, r->connection->log, err, 336 if (of.err == NGX_ENOENT) {
344 ngx_file_info_n " \"%s\" failed", ctx->path.data); 337 *(ctx->index.data - i) = c;
338 return ngx_http_index_error(r, ctx, of.err);
339 }
340
341 ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
342 ngx_open_file_n " \"%s\" failed", path.data);
343 }
345 344
346 return NGX_HTTP_INTERNAL_SERVER_ERROR; 345 return NGX_HTTP_INTERNAL_SERVER_ERROR;
347 } 346 }
348 347
349 *(ctx->index.data - i) = c; 348 *(ctx->index.data - i) = c;
350 349
351 if (ngx_is_dir(&fi)) { 350 if (of.is_dir) {
352 return NGX_OK; 351 return NGX_OK;
353 } 352 }
354 353
355 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, 354 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
356 "\"%s\" is not a directory", ctx->path.data); 355 "\"%s\" is not a directory", path.data);
357 356
358 return NGX_HTTP_INTERNAL_SERVER_ERROR; 357 return NGX_HTTP_INTERNAL_SERVER_ERROR;
359 } 358 }
360 359
361 360