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));