Mercurial > hg > nginx-vendor-0-6
comparison src/http/modules/ngx_http_index_module.c @ 106:45f7329b4bd0 NGINX_0_3_0
nginx 0.3.0
*) Change: the 10-days live time limit of worker process was
eliminated. The limit was introduced because of millisecond timers
overflow.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Fri, 07 Oct 2005 00:00:00 +0400 |
parents | 71c46860eb55 |
children | 408f195b3482 |
comparison
equal
deleted
inserted
replaced
105:531d62c2a28d | 106:45f7329b4bd0 |
---|---|
22 } ngx_http_index_loc_conf_t; | 22 } ngx_http_index_loc_conf_t; |
23 | 23 |
24 | 24 |
25 typedef struct { | 25 typedef struct { |
26 ngx_uint_t current; | 26 ngx_uint_t current; |
27 size_t allocated; | 27 |
28 | 28 ngx_str_t path; |
29 u_char *path; | |
30 ngx_str_t uri; | |
31 ngx_str_t index; | 29 ngx_str_t index; |
32 | 30 |
33 ngx_uint_t tested; /* unsigned tested:1 */ | 31 ngx_uint_t tested; /* unsigned tested:1 */ |
34 } ngx_http_index_ctx_t; | 32 } ngx_http_index_ctx_t; |
35 | 33 |
36 | 34 |
37 #define NGX_HTTP_DEFAULT_INDEX "index.html" | 35 #define NGX_HTTP_DEFAULT_INDEX "index.html" |
38 | 36 |
39 | 37 |
40 static ngx_int_t ngx_http_index_alloc(ngx_http_request_t *r, size_t size, | |
41 ngx_http_index_ctx_t *ctx, ngx_http_core_loc_conf_t *clcf); | |
42 static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r, | 38 static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r, |
43 ngx_http_index_ctx_t *ctx); | 39 ngx_http_index_ctx_t *ctx); |
44 static ngx_int_t ngx_http_index_error(ngx_http_request_t *r, | 40 static ngx_int_t ngx_http_index_error(ngx_http_request_t *r, |
45 ngx_http_index_ctx_t *ctx, ngx_err_t err); | 41 ngx_http_index_ctx_t *ctx, ngx_err_t err); |
46 | 42 |
118 */ | 114 */ |
119 | 115 |
120 static ngx_int_t | 116 static ngx_int_t |
121 ngx_http_index_handler(ngx_http_request_t *r) | 117 ngx_http_index_handler(ngx_http_request_t *r) |
122 { | 118 { |
123 u_char *name; | 119 u_char *last; |
124 size_t len; | 120 size_t len; |
125 ngx_fd_t fd; | 121 ngx_fd_t fd; |
126 ngx_int_t rc; | 122 ngx_int_t rc; |
127 ngx_err_t err; | 123 ngx_err_t err; |
124 ngx_str_t uri; | |
128 ngx_log_t *log; | 125 ngx_log_t *log; |
129 ngx_uint_t i; | 126 ngx_uint_t i; |
130 ngx_http_index_t *index; | 127 ngx_http_index_t *index; |
131 ngx_http_index_ctx_t *ctx; | 128 ngx_http_index_ctx_t *ctx; |
132 ngx_pool_cleanup_file_t *cln; | 129 ngx_pool_cleanup_file_t *cln; |
150 /* | 147 /* |
151 * we use context because the handler supports an async file opening, | 148 * we use context because the handler supports an async file opening, |
152 * and may be called several times | 149 * and may be called several times |
153 */ | 150 */ |
154 | 151 |
155 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
156 ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module); | 152 ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module); |
157 | 153 |
158 ctx = ngx_http_get_module_ctx(r, ngx_http_index_module); | 154 ctx = ngx_http_get_module_ctx(r, ngx_http_index_module); |
159 if (ctx == NULL) { | 155 if (ctx == NULL) { |
160 | 156 |
182 ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); | 178 ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); |
183 | 179 |
184 e.ip = index[i].lengths->elts; | 180 e.ip = index[i].lengths->elts; |
185 e.request = r; | 181 e.request = r; |
186 | 182 |
187 len = 1; | 183 /* 1 byte for terminating '\0' and 4 bytes is preallocation */ |
184 | |
185 len = 1 + 4; | |
188 | 186 |
189 while (*(uintptr_t *) e.ip) { | 187 while (*(uintptr_t *) e.ip) { |
190 lcode = *(ngx_http_script_len_code_pt *) e.ip; | 188 lcode = *(ngx_http_script_len_code_pt *) e.ip; |
191 len += lcode(&e); | 189 len += lcode(&e); |
192 } | 190 } |
193 | 191 |
194 ctx->index.len = len; | 192 ctx->index.len = len; |
195 } | 193 } |
196 | 194 |
197 if (len > ctx->allocated) { | 195 if (len > ctx->path.len) { |
198 if (ngx_http_index_alloc(r, len, ctx, clcf) != NGX_OK) { | 196 |
199 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 197 last = ngx_http_map_uri_to_path(r, &ctx->path, len); |
200 } | 198 if (last == NULL) { |
199 return NGX_ERROR; | |
200 } | |
201 | |
202 ctx->index.data = last; | |
201 } | 203 } |
202 | 204 |
203 if (index[i].values == NULL) { | 205 if (index[i].values == NULL) { |
204 ngx_memcpy(ctx->index.data, index[i].name.data, ctx->index.len); | 206 |
207 /* index[i].name.len includes the terminating '\0' */ | |
208 | |
209 ngx_memcpy(ctx->index.data, index[i].name.data, index[i].name.len); | |
205 | 210 |
206 } else { | 211 } else { |
207 e.ip = index[i].values->elts; | 212 e.ip = index[i].values->elts; |
208 e.pos = ctx->index.data; | 213 e.pos = ctx->index.data; |
209 | 214 |
218 } | 223 } |
219 | 224 |
220 *e.pos++ = '\0'; | 225 *e.pos++ = '\0'; |
221 } | 226 } |
222 | 227 |
223 name = ctx->path; | |
224 | |
225 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, | 228 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, |
226 "open index \"%s\"", name); | 229 "open index \"%s\"", ctx->path.data); |
227 | 230 |
228 fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN); | 231 fd = ngx_open_file(ctx->path.data, NGX_FILE_RDONLY, NGX_FILE_OPEN); |
229 | 232 |
230 if (fd == (ngx_fd_t) NGX_AGAIN) { | 233 if (fd == (ngx_fd_t) NGX_AGAIN) { |
231 ctx->current = i; | 234 ctx->current = i; |
232 return NGX_AGAIN; | 235 return NGX_AGAIN; |
233 } | 236 } |
234 | 237 |
235 if (fd == NGX_INVALID_FILE) { | 238 if (fd == NGX_INVALID_FILE) { |
236 err = ngx_errno; | 239 err = ngx_errno; |
237 | 240 |
238 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, err, | 241 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, err, |
239 ngx_open_file_n " \"%s\" failed", name); | 242 ngx_open_file_n " \"%s\" failed", ctx->path.data); |
240 | 243 |
241 if (err == NGX_ENOTDIR) { | 244 if (err == NGX_ENOTDIR) { |
242 return ngx_http_index_error(r, ctx, err); | 245 return ngx_http_index_error(r, ctx, err); |
243 | 246 |
244 } else if (err == NGX_EACCES) { | 247 } else if (err == NGX_EACCES) { |
258 if (err == NGX_ENOENT) { | 261 if (err == NGX_ENOENT) { |
259 continue; | 262 continue; |
260 } | 263 } |
261 | 264 |
262 ngx_log_error(NGX_LOG_ERR, log, err, | 265 ngx_log_error(NGX_LOG_ERR, log, err, |
263 ngx_open_file_n " \"%s\" failed", name); | 266 ngx_open_file_n " \"%s\" failed", ctx->path.data); |
264 | 267 |
265 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 268 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
266 } | 269 } |
267 | 270 |
268 | 271 |
270 if (cln == NULL) { | 273 if (cln == NULL) { |
271 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 274 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
272 } | 275 } |
273 | 276 |
274 cln->fd = fd; | 277 cln->fd = fd; |
275 cln->name = name; | 278 cln->name = ctx->path.data; |
276 cln->log = r->pool->log; | 279 cln->log = r->pool->log; |
277 | 280 |
278 if (ngx_pool_cleanup_add(r->pool, ngx_pool_cleanup_file, cln) == NULL) { | 281 if (ngx_pool_cleanup_add(r->pool, ngx_pool_cleanup_file, cln) == NULL) { |
279 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 282 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
280 } | 283 } |
281 | 284 |
282 | 285 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
283 if (clcf->alias) { | 286 |
284 name = ngx_cpymem(ctx->uri.data, r->uri.data, r->uri.len); | 287 uri.len = r->uri.len + ctx->index.len - 1; |
285 ngx_memcpy(name, ctx->index.data, ctx->index.len - 1); | 288 |
286 } | 289 if (!clcf->alias) { |
287 | 290 uri.data = ctx->path.data + clcf->root.len; |
288 ctx->uri.len = r->uri.len + ctx->index.len - 1; | 291 |
289 | 292 } else { |
290 return ngx_http_internal_redirect(r, &ctx->uri, &r->args); | 293 uri.data = ngx_palloc(r->pool, uri.len); |
294 if (uri.data == NULL) { | |
295 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
296 } | |
297 | |
298 last = ngx_cpymem(uri.data, r->uri.data, r->uri.len); | |
299 ngx_memcpy(last, ctx->index.data, ctx->index.len - 1); | |
300 } | |
301 | |
302 return ngx_http_internal_redirect(r, &uri, &r->args); | |
291 } | 303 } |
292 | 304 |
293 return NGX_DECLINED; | 305 return NGX_DECLINED; |
294 } | |
295 | |
296 | |
297 static ngx_int_t | |
298 ngx_http_index_alloc(ngx_http_request_t *r, size_t size, | |
299 ngx_http_index_ctx_t *ctx, ngx_http_core_loc_conf_t *clcf) | |
300 { | |
301 ctx->allocated = size; | |
302 | |
303 if (!clcf->alias) { | |
304 ctx->path = ngx_palloc(r->pool, clcf->root.len + r->uri.len + size); | |
305 if (ctx->path == NULL) { | |
306 return NGX_ERROR; | |
307 } | |
308 | |
309 ctx->uri.data = ngx_cpymem(ctx->path, clcf->root.data, clcf->root.len); | |
310 | |
311 ctx->index.data = ngx_cpymem(ctx->uri.data, r->uri.data, r->uri.len); | |
312 | |
313 } else { | |
314 ctx->path = ngx_palloc(r->pool, | |
315 clcf->root.len + r->uri.len - clcf->name.len + size); | |
316 if (ctx->path == NULL) { | |
317 return NGX_ERROR; | |
318 } | |
319 | |
320 ctx->uri.data = ngx_palloc(r->pool, r->uri.len + size); | |
321 if (ctx->uri.data == NULL) { | |
322 return NGX_ERROR; | |
323 } | |
324 | |
325 ngx_memcpy(ctx->path, clcf->root.data, clcf->root.len); | |
326 | |
327 ctx->index.data = ngx_cpymem(ctx->path + clcf->root.len, | |
328 r->uri.data + clcf->name.len, | |
329 r->uri.len - clcf->name.len); | |
330 } | |
331 | |
332 return NGX_OK; | |
333 } | 306 } |
334 | 307 |
335 | 308 |
336 static ngx_int_t | 309 static ngx_int_t |
337 ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_index_ctx_t *ctx) | 310 ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_index_ctx_t *ctx) |
340 ngx_file_info_t fi; | 313 ngx_file_info_t fi; |
341 | 314 |
342 *(ctx->index.data - 1) = '\0'; | 315 *(ctx->index.data - 1) = '\0'; |
343 | 316 |
344 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 317 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
345 "http index check dir: \"%s\"", ctx->path); | 318 "http index check dir: \"%s\"", ctx->path.data); |
346 | 319 |
347 if (ngx_file_info(ctx->path, &fi) == -1) { | 320 if (ngx_file_info(ctx->path.data, &fi) == -1) { |
348 | 321 |
349 err = ngx_errno; | 322 err = ngx_errno; |
350 | 323 |
351 if (err == NGX_ENOENT) { | 324 if (err == NGX_ENOENT) { |
352 *(ctx->index.data - 1) = '/'; | 325 *(ctx->index.data - 1) = '/'; |
353 return ngx_http_index_error(r, ctx, err); | 326 return ngx_http_index_error(r, ctx, err); |
354 } | 327 } |
355 | 328 |
356 ngx_log_error(NGX_LOG_CRIT, r->connection->log, err, | 329 ngx_log_error(NGX_LOG_CRIT, r->connection->log, err, |
357 ngx_file_info_n " \"%s\" failed", ctx->path); | 330 ngx_file_info_n " \"%s\" failed", ctx->path.data); |
358 | 331 |
359 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 332 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
360 } | 333 } |
361 | 334 |
362 *(ctx->index.data - 1) = '/'; | 335 *(ctx->index.data - 1) = '/'; |
364 if (ngx_is_dir(&fi)) { | 337 if (ngx_is_dir(&fi)) { |
365 return NGX_OK; | 338 return NGX_OK; |
366 } | 339 } |
367 | 340 |
368 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | 341 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, |
369 "\"%s\" is not a directory", ctx->path); | 342 "\"%s\" is not a directory", ctx->path.data); |
370 | 343 |
371 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 344 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
372 } | 345 } |
373 | 346 |
374 | 347 |
376 ngx_http_index_error(ngx_http_request_t *r, ngx_http_index_ctx_t *ctx, | 349 ngx_http_index_error(ngx_http_request_t *r, ngx_http_index_ctx_t *ctx, |
377 ngx_err_t err) | 350 ngx_err_t err) |
378 { | 351 { |
379 if (err == NGX_EACCES) { | 352 if (err == NGX_EACCES) { |
380 ngx_log_error(NGX_LOG_ERR, r->connection->log, err, | 353 ngx_log_error(NGX_LOG_ERR, r->connection->log, err, |
381 "\"%s\" is forbidden", ctx->path); | 354 "\"%s\" is forbidden", ctx->path.data); |
382 | 355 |
383 return NGX_HTTP_FORBIDDEN; | 356 return NGX_HTTP_FORBIDDEN; |
384 } | 357 } |
385 | 358 |
386 ngx_log_error(NGX_LOG_ERR, r->connection->log, err, | 359 ngx_log_error(NGX_LOG_ERR, r->connection->log, err, |
387 "\"%s\" is not found", ctx->path); | 360 "\"%s\" is not found", ctx->path.data); |
388 | 361 |
389 return NGX_HTTP_NOT_FOUND; | 362 return NGX_HTTP_NOT_FOUND; |
390 } | 363 } |
391 | 364 |
392 | 365 |
492 index->values = NULL; | 465 index->values = NULL; |
493 | 466 |
494 n = ngx_http_script_variables_count(&value[i]); | 467 n = ngx_http_script_variables_count(&value[i]); |
495 | 468 |
496 if (n == 0) { | 469 if (n == 0) { |
497 index->name.len++; | |
498 | |
499 if (ilcf->max_index_len != 0 | 470 if (ilcf->max_index_len != 0 |
500 && ilcf->max_index_len < index->name.len) | 471 && ilcf->max_index_len < index->name.len) |
501 { | 472 { |
502 ilcf->max_index_len = index->name.len; | 473 ilcf->max_index_len = index->name.len; |
503 } | 474 } |
475 | |
476 /* include the terminating '\0' to the length to use ngx_memcpy() */ | |
477 index->name.len++; | |
504 | 478 |
505 continue; | 479 continue; |
506 } | 480 } |
507 | 481 |
508 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); | 482 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); |