Mercurial > hg > nginx-vendor-1-0
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 |