Mercurial > hg > nginx-mail
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 |