comparison src/http/ngx_http_file_cache.c @ 632:65fd8be45530 NGINX_1_0_6

nginx 1.0.6 *) Feature: cache loader run time decrease. *) Feature: loading time decrease of configuration with large number of HTTPS sites. *) Feature: now nginx supports ECDHE key exchange ciphers. Thanks to Adrian Kotelba. *) Feature: the "lingering_close" directive. *) Feature: now shared zones and caches use POSIX semaphores on Solaris. Thanks to Den Ivanov. *) Bugfix: nginx could not be built on Linux 3.0. *) Bugfix: a segmentation fault might occur in a worker process if "fastcgi/scgi/uwsgi_param" directives were used with values starting with "HTTP_"; the bug had appeared in 0.8.40. *) Bugfix: in closing connection for pipelined requests. *) Bugfix: nginx did not disable gzipping if client sent "gzip;q=0" in "Accept-Encoding" request header line. *) Bugfix: in timeout in unbuffered proxied mode. *) Bugfix: memory leaks when a "proxy_pass" directive contains variables and proxies to an HTTPS backend. *) Bugfix: in parameter validaiton of a "proxy_pass" directive with variables. Thanks to Lanshun Zhou. *) Bugfix: SSL did not work on QNX. *) Bugfix: SSL modules could not be built by gcc 4.6 without --with-debug option.
author Igor Sysoev <http://sysoev.ru>
date Fri, 29 Jul 2011 00:00:00 +0400
parents ad6fee8052d7
children 692f4d4d7f10
comparison
equal deleted inserted replaced
631:9b978fa3cd33 632:65fd8be45530
29 static time_t ngx_http_file_cache_forced_expire(ngx_http_file_cache_t *cache); 29 static time_t ngx_http_file_cache_forced_expire(ngx_http_file_cache_t *cache);
30 static time_t ngx_http_file_cache_expire(ngx_http_file_cache_t *cache); 30 static time_t ngx_http_file_cache_expire(ngx_http_file_cache_t *cache);
31 static void ngx_http_file_cache_delete(ngx_http_file_cache_t *cache, 31 static void ngx_http_file_cache_delete(ngx_http_file_cache_t *cache,
32 ngx_queue_t *q, u_char *name); 32 ngx_queue_t *q, u_char *name);
33 static ngx_int_t 33 static ngx_int_t
34 ngx_http_file_cache_manager_sleep(ngx_http_file_cache_t *cache); 34 ngx_http_file_cache_loader_sleep(ngx_http_file_cache_t *cache);
35 static ngx_int_t ngx_http_file_cache_noop(ngx_tree_ctx_t *ctx, 35 static ngx_int_t ngx_http_file_cache_noop(ngx_tree_ctx_t *ctx,
36 ngx_str_t *path); 36 ngx_str_t *path);
37 static ngx_int_t ngx_http_file_cache_manage_file(ngx_tree_ctx_t *ctx, 37 static ngx_int_t ngx_http_file_cache_manage_file(ngx_tree_ctx_t *ctx,
38 ngx_str_t *path); 38 ngx_str_t *path);
39 static ngx_int_t ngx_http_file_cache_add_file(ngx_tree_ctx_t *ctx, 39 static ngx_int_t ngx_http_file_cache_add_file(ngx_tree_ctx_t *ctx,
374 } 374 }
375 375
376 if ((size_t) n < c->header_start) { 376 if ((size_t) n < c->header_start) {
377 ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0, 377 ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
378 "cache file \"%s\" is too small", c->file.name.data); 378 "cache file \"%s\" is too small", c->file.name.data);
379 return NGX_ERROR; 379 return NGX_DECLINED;
380 } 380 }
381 381
382 h = (ngx_http_file_cache_header_t *) c->buf->pos; 382 h = (ngx_http_file_cache_header_t *) c->buf->pos;
383 383
384 if (h->crc32 != c->crc32) { 384 if (h->crc32 != c->crc32) {
407 if (!c->node->exists) { 407 if (!c->node->exists) {
408 c->node->uses = 1; 408 c->node->uses = 1;
409 c->node->body_start = c->body_start; 409 c->node->body_start = c->body_start;
410 c->node->exists = 1; 410 c->node->exists = 1;
411 c->node->uniq = c->uniq; 411 c->node->uniq = c->uniq;
412 c->node->fs_size = c->fs_size;
412 413
413 cache->sh->size += c->fs_size; 414 cache->sh->size += c->fs_size;
414 } 415 }
415 416
416 ngx_shmtx_unlock(&cache->shpool->mutex); 417 ngx_shmtx_unlock(&cache->shpool->mutex);
528 rc = NGX_OK; 529 rc = NGX_OK;
529 530
530 goto done; 531 goto done;
531 } 532 }
532 533
533 if (fcn->exists) { 534 if (fcn->exists || fcn->uses >= c->min_uses) {
534 535
535 c->exists = fcn->exists; 536 c->exists = fcn->exists;
536 c->body_start = fcn->body_start; 537 if (fcn->body_start) {
538 c->body_start = fcn->body_start;
539 }
537 540
538 rc = NGX_OK; 541 rc = NGX_OK;
539 542
540 goto done; 543 goto done;
541 } 544 }
542 545
543 if (fcn->uses >= c->min_uses) { 546 rc = NGX_AGAIN;
544
545 c->exists = fcn->exists;
546 c->body_start = fcn->body_start;
547
548 rc = NGX_OK;
549
550 } else {
551 rc = NGX_AGAIN;
552 }
553 547
554 goto done; 548 goto done;
555 } 549 }
556 550
557 fcn = ngx_slab_alloc_locked(cache->shpool, 551 fcn = ngx_slab_alloc_locked(cache->shpool,
856 ngx_http_cache_t *c; 850 ngx_http_cache_t *c;
857 851
858 c = r->cache; 852 c = r->cache;
859 853
860 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 854 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
861 "http file cache send: %s", c->file.name.data); 855 "http file cache send: %s", c->file.name.data);
862 856
863 /* we need to allocate all before the header would be sent */ 857 /* we need to allocate all before the header would be sent */
864 858
865 b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); 859 b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
866 if (b == NULL) { 860 if (b == NULL) {
1212 1206
1213 if (wait > 0) { 1207 if (wait > 0) {
1214 return wait; 1208 return wait;
1215 } 1209 }
1216 1210
1217 if (ngx_http_file_cache_manager_sleep(cache) != NGX_OK) { 1211 if (ngx_quit || ngx_terminate) {
1218 return next; 1212 return next;
1219 } 1213 }
1220 } 1214 }
1221 } 1215 }
1222 1216
1266 cache->bsize); 1260 cache->bsize);
1267 } 1261 }
1268 1262
1269 1263
1270 static ngx_int_t 1264 static ngx_int_t
1271 ngx_http_file_cache_manager_sleep(ngx_http_file_cache_t *cache) 1265 ngx_http_file_cache_loader_sleep(ngx_http_file_cache_t *cache)
1272 { 1266 {
1273 ngx_msec_t elapsed; 1267 ngx_msec_t elapsed;
1274 1268
1275 if (cache->files++ > 100) { 1269 if (cache->files++ > 100) {
1276 1270
1318 1312
1319 if (ngx_http_file_cache_add_file(ctx, path) != NGX_OK) { 1313 if (ngx_http_file_cache_add_file(ctx, path) != NGX_OK) {
1320 (void) ngx_http_file_cache_delete_file(ctx, path); 1314 (void) ngx_http_file_cache_delete_file(ctx, path);
1321 } 1315 }
1322 1316
1323 return ngx_http_file_cache_manager_sleep(cache); 1317 return ngx_http_file_cache_loader_sleep(cache);
1324 } 1318 }
1325 1319
1326 1320
1327 static ngx_int_t 1321 static ngx_int_t
1328 ngx_http_file_cache_add_file(ngx_tree_ctx_t *ctx, ngx_str_t *name) 1322 ngx_http_file_cache_add_file(ngx_tree_ctx_t *ctx, ngx_str_t *name)
1329 { 1323 {
1330 u_char *p; 1324 u_char *p;
1331 ngx_fd_t fd; 1325 ngx_int_t n;
1332 ngx_int_t n; 1326 ngx_uint_t i;
1333 ngx_uint_t i; 1327 ngx_http_cache_t c;
1334 ngx_file_info_t fi; 1328 ngx_http_file_cache_t *cache;
1335 ngx_http_cache_t c;
1336 ngx_http_file_cache_t *cache;
1337 ngx_http_file_cache_header_t h;
1338 1329
1339 if (name->len < 2 * NGX_HTTP_CACHE_KEY_LEN) { 1330 if (name->len < 2 * NGX_HTTP_CACHE_KEY_LEN) {
1340 return NGX_ERROR; 1331 return NGX_ERROR;
1341 } 1332 }
1342 1333
1343 ngx_memzero(&c, sizeof(ngx_http_cache_t)); 1334 if (ctx->size < (off_t) sizeof(ngx_http_file_cache_header_t)) {
1344
1345 fd = ngx_open_file(name->data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
1346
1347 if (fd == NGX_INVALID_FILE) {
1348 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
1349 ngx_open_file_n " \"%s\" failed", name->data);
1350 return NGX_ERROR;
1351 }
1352
1353 c.file.fd = fd;
1354 c.file.name = *name;
1355 c.file.log = ctx->log;
1356
1357 n = ngx_read_file(&c.file, (u_char *) &h,
1358 sizeof(ngx_http_file_cache_header_t), 0);
1359 if (n == NGX_ERROR) {
1360 return NGX_ERROR;
1361 }
1362
1363 if ((size_t) n < sizeof(ngx_http_file_cache_header_t)) {
1364 ngx_log_error(NGX_LOG_CRIT, ctx->log, 0, 1335 ngx_log_error(NGX_LOG_CRIT, ctx->log, 0,
1365 "cache file \"%s\" is too small", name->data); 1336 "cache file \"%s\" is too small", name->data);
1366 return NGX_ERROR; 1337 return NGX_ERROR;
1367 } 1338 }
1368 1339
1340 ngx_memzero(&c, sizeof(ngx_http_cache_t));
1369 cache = ctx->data; 1341 cache = ctx->data;
1370 1342
1371 if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) { 1343 c.length = ctx->size;
1372 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, 1344 c.fs_size = (ctx->fs_size + cache->bsize - 1) / cache->bsize;
1373 ngx_fd_info_n " \"%s\" failed", name->data);
1374
1375 } else {
1376 c.uniq = ngx_file_uniq(&fi);
1377 c.valid_sec = h.valid_sec;
1378 c.valid_msec = h.valid_msec;
1379 c.body_start = h.body_start;
1380 c.length = ngx_file_size(&fi);
1381 c.fs_size = (ngx_file_fs_size(&fi) + cache->bsize - 1) / cache->bsize;
1382 }
1383
1384 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
1385 ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
1386 ngx_close_file_n " \"%s\" failed", name->data);
1387 }
1388
1389 if (c.body_start == 0) {
1390 return NGX_ERROR;
1391 }
1392 1345
1393 p = &name->data[name->len - 2 * NGX_HTTP_CACHE_KEY_LEN]; 1346 p = &name->data[name->len - 2 * NGX_HTTP_CACHE_KEY_LEN];
1394 1347
1395 for (i = 0; i < NGX_HTTP_CACHE_KEY_LEN; i++) { 1348 for (i = 0; i < NGX_HTTP_CACHE_KEY_LEN; i++) {
1396 n = ngx_hextoi(p, 2); 1349 n = ngx_hextoi(p, 2);
1433 1386
1434 ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node); 1387 ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node);
1435 1388
1436 fcn->uses = 1; 1389 fcn->uses = 1;
1437 fcn->count = 0; 1390 fcn->count = 0;
1438 fcn->valid_msec = c->valid_msec; 1391 fcn->valid_msec = 0;
1439 fcn->error = 0; 1392 fcn->error = 0;
1440 fcn->exists = 1; 1393 fcn->exists = 1;
1441 fcn->updating = 0; 1394 fcn->updating = 0;
1442 fcn->deleting = 0; 1395 fcn->deleting = 0;
1443 fcn->uniq = c->uniq; 1396 fcn->uniq = 0;
1444 fcn->valid_sec = c->valid_sec; 1397 fcn->valid_sec = 0;
1445 fcn->body_start = c->body_start; 1398 fcn->body_start = 0;
1446 fcn->fs_size = c->fs_size; 1399 fcn->fs_size = c->fs_size;
1447 1400
1448 cache->sh->size += c->fs_size; 1401 cache->sh->size += c->fs_size;
1449 1402
1450 } else { 1403 } else {
1650 } 1603 }
1651 1604
1652 cache->path->manager = ngx_http_file_cache_manager; 1605 cache->path->manager = ngx_http_file_cache_manager;
1653 cache->path->loader = ngx_http_file_cache_loader; 1606 cache->path->loader = ngx_http_file_cache_loader;
1654 cache->path->data = cache; 1607 cache->path->data = cache;
1608 cache->path->conf_file = cf->conf_file->file.name.data;
1609 cache->path->line = cf->conf_file->line;
1655 1610
1656 if (ngx_add_path(cf, &cache->path) != NGX_OK) { 1611 if (ngx_add_path(cf, &cache->path) != NGX_OK) {
1657 return NGX_CONF_ERROR; 1612 return NGX_CONF_ERROR;
1658 } 1613 }
1659 1614