comparison src/http/ngx_http_file_cache.c @ 656:9d21dad0b5a1 NGINX_1_1_12

nginx 1.1.12 *) Change: a "proxy_pass" directive without URI part now uses changed URI after redirection with the "error_page" directive; Thanks to Lanshun Zhou. *) Feature: the "proxy/fastcgi/scgi/uwsgi_cache_lock", "proxy/fastcgi/scgi/uwsgi_cache_lock_timeout" directives. *) Feature: the "pcre_jit" directive. *) Feature: the "if" SSI command supports captures in regular expressions. *) Bugfix: the "if" SSI command did not work inside the "block" command. *) Bugfix: the "limit_conn_log_level" and "limit_req_log_level" directives might not work. *) Bugfix: the "limit_rate" directive did not allow to use full throughput, even if limit value was very high. *) Bugfix: the "sendfile_max_chunk" directive did not work, if the "limit_rate" directive was used. *) Bugfix: a "proxy_pass" directive without URI part always used original request URI if variables were used. *) Bugfix: a "proxy_pass" directive without URI part might use original request after redirection with the "try_files" directive; Thanks to Lanshun Zhou. *) Bugfix: in the ngx_http_scgi_module. *) Bugfix: in the ngx_http_mp4_module. *) Bugfix: nginx could not be built on Solaris; the bug had appeared in 1.1.9.
author Igor Sysoev <http://sysoev.ru>
date Mon, 26 Dec 2011 00:00:00 +0400
parents 753f505670e0
children d0f7a625f27c
comparison
equal deleted inserted replaced
655:189afff6503f 656:9d21dad0b5a1
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 #include <ngx_http.h> 9 #include <ngx_http.h>
10 #include <ngx_md5.h> 10 #include <ngx_md5.h>
11 11
12 12
13 static ngx_int_t ngx_http_file_cache_lock(ngx_http_request_t *r,
14 ngx_http_cache_t *c);
15 static void ngx_http_file_cache_lock_wait_handler(ngx_event_t *ev);
13 static ngx_int_t ngx_http_file_cache_read(ngx_http_request_t *r, 16 static ngx_int_t ngx_http_file_cache_read(ngx_http_request_t *r,
14 ngx_http_cache_t *c); 17 ngx_http_cache_t *c);
15 static ssize_t ngx_http_file_cache_aio_read(ngx_http_request_t *r, 18 static ssize_t ngx_http_file_cache_aio_read(ngx_http_request_t *r,
16 ngx_http_cache_t *c); 19 ngx_http_cache_t *c);
17 #if (NGX_HAVE_FILE_AIO) 20 #if (NGX_HAVE_FILE_AIO)
179 cln = ngx_pool_cleanup_add(r->pool, 0); 182 cln = ngx_pool_cleanup_add(r->pool, 0);
180 if (cln == NULL) { 183 if (cln == NULL) {
181 return NGX_ERROR; 184 return NGX_ERROR;
182 } 185 }
183 186
187 cln->handler = ngx_http_file_cache_cleanup;
188 cln->data = c;
189
184 if (ngx_http_file_cache_exists(cache, c) == NGX_ERROR) { 190 if (ngx_http_file_cache_exists(cache, c) == NGX_ERROR) {
185 return NGX_ERROR; 191 return NGX_ERROR;
186 } 192 }
187
188 cln->handler = ngx_http_file_cache_cleanup;
189 cln->data = c;
190 193
191 if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) { 194 if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) {
192 return NGX_ERROR; 195 return NGX_ERROR;
193 } 196 }
194 197
242 ngx_http_file_cache_t *cache; 245 ngx_http_file_cache_t *cache;
243 ngx_http_core_loc_conf_t *clcf; 246 ngx_http_core_loc_conf_t *clcf;
244 247
245 c = r->cache; 248 c = r->cache;
246 249
250 if (c->waiting) {
251 return NGX_AGAIN;
252 }
253
247 if (c->buf) { 254 if (c->buf) {
248 return ngx_http_file_cache_read(r, c); 255 return ngx_http_file_cache_read(r, c);
249 } 256 }
250 257
251 cache = c->file_cache; 258 cache = c->file_cache;
252 259
253 cln = ngx_pool_cleanup_add(r->pool, 0); 260 if (c->node == NULL) {
254 if (cln == NULL) { 261 cln = ngx_pool_cleanup_add(r->pool, 0);
255 return NGX_ERROR; 262 if (cln == NULL) {
263 return NGX_ERROR;
264 }
265
266 cln->handler = ngx_http_file_cache_cleanup;
267 cln->data = c;
256 } 268 }
257 269
258 rc = ngx_http_file_cache_exists(cache, c); 270 rc = ngx_http_file_cache_exists(cache, c);
259 271
260 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 272 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
261 "http file cache exists: %i e:%d", rc, c->exists); 273 "http file cache exists: %i e:%d", rc, c->exists);
262 274
263 if (rc == NGX_ERROR) { 275 if (rc == NGX_ERROR) {
264 return rc; 276 return rc;
265 } 277 }
266
267 cln->handler = ngx_http_file_cache_cleanup;
268 cln->data = c;
269 278
270 if (rc == NGX_AGAIN) { 279 if (rc == NGX_AGAIN) {
271 return NGX_HTTP_CACHE_SCARCE; 280 return NGX_HTTP_CACHE_SCARCE;
272 } 281 }
273 282
304 if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) { 313 if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) {
305 return NGX_ERROR; 314 return NGX_ERROR;
306 } 315 }
307 316
308 if (!test) { 317 if (!test) {
309 return NGX_DECLINED; 318 goto done;
310 } 319 }
311 320
312 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 321 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
313 322
314 ngx_memzero(&of, sizeof(ngx_open_file_info_t)); 323 ngx_memzero(&of, sizeof(ngx_open_file_info_t));
328 case 0: 337 case 0:
329 return NGX_ERROR; 338 return NGX_ERROR;
330 339
331 case NGX_ENOENT: 340 case NGX_ENOENT:
332 case NGX_ENOTDIR: 341 case NGX_ENOTDIR:
333 return rv; 342 goto done;
334 343
335 default: 344 default:
336 ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err, 345 ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
337 ngx_open_file_n " \"%s\" failed", c->file.name.data); 346 ngx_open_file_n " \"%s\" failed", c->file.name.data);
338 return NGX_ERROR; 347 return NGX_ERROR;
352 if (c->buf == NULL) { 361 if (c->buf == NULL) {
353 return NGX_ERROR; 362 return NGX_ERROR;
354 } 363 }
355 364
356 return ngx_http_file_cache_read(r, c); 365 return ngx_http_file_cache_read(r, c);
366
367 done:
368
369 if (rv == NGX_DECLINED) {
370 return ngx_http_file_cache_lock(r, c);
371 }
372
373 return rv;
374 }
375
376
377 static ngx_int_t
378 ngx_http_file_cache_lock(ngx_http_request_t *r, ngx_http_cache_t *c)
379 {
380 ngx_msec_t now, timer;
381 ngx_http_file_cache_t *cache;
382
383 if (!c->lock) {
384 return NGX_DECLINED;
385 }
386
387 cache = c->file_cache;
388
389 ngx_shmtx_lock(&cache->shpool->mutex);
390
391 if (!c->node->updating) {
392 c->node->updating = 1;
393 c->updating = 1;
394 }
395
396 ngx_shmtx_unlock(&cache->shpool->mutex);
397
398 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
399 "http file cache lock u:%d wt:%M",
400 c->updating, c->wait_time);
401
402 if (c->updating) {
403 return NGX_DECLINED;
404 }
405
406 c->waiting = 1;
407
408 now = ngx_current_msec;
409
410 if (c->wait_time == 0) {
411 c->wait_time = now + c->lock_timeout;
412
413 c->wait_event.handler = ngx_http_file_cache_lock_wait_handler;
414 c->wait_event.data = r;
415 c->wait_event.log = r->connection->log;
416 }
417
418 timer = c->wait_time - now;
419
420 ngx_add_timer(&c->wait_event, (timer > 500) ? 500 : timer);
421
422 r->main->blocked++;
423
424 return NGX_AGAIN;
425 }
426
427
428 static void
429 ngx_http_file_cache_lock_wait_handler(ngx_event_t *ev)
430 {
431 ngx_uint_t wait;
432 ngx_msec_t timer;
433 ngx_http_cache_t *c;
434 ngx_http_request_t *r;
435 ngx_http_file_cache_t *cache;
436
437 r = ev->data;
438 c = r->cache;
439
440 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ev->log, 0,
441 "http file cache wait handler wt:%M cur:%M",
442 c->wait_time, ngx_current_msec);
443
444 timer = c->wait_time - ngx_current_msec;
445
446 if ((ngx_msec_int_t) timer <= 0) {
447 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0,
448 "http file cache lock timeout");
449 c->lock = 0;
450 goto wakeup;
451 }
452
453 cache = c->file_cache;
454 wait = 0;
455
456 ngx_shmtx_lock(&cache->shpool->mutex);
457
458 if (c->node->updating) {
459 wait = 1;
460 }
461
462 ngx_shmtx_unlock(&cache->shpool->mutex);
463
464 if (wait) {
465 ngx_add_timer(ev, (timer > 500) ? 500 : timer);
466 return;
467 }
468
469 wakeup:
470
471 c->waiting = 0;
472 r->main->blocked--;
473 r->connection->write->handler(r->connection->write);
357 } 474 }
358 475
359 476
360 static ngx_int_t 477 static ngx_int_t
361 ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c) 478 ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
516 ngx_int_t rc; 633 ngx_int_t rc;
517 ngx_http_file_cache_node_t *fcn; 634 ngx_http_file_cache_node_t *fcn;
518 635
519 ngx_shmtx_lock(&cache->shpool->mutex); 636 ngx_shmtx_lock(&cache->shpool->mutex);
520 637
521 fcn = ngx_http_file_cache_lookup(cache, c->key); 638 fcn = c->node;
639
640 if (fcn == NULL) {
641 fcn = ngx_http_file_cache_lookup(cache, c->key);
642 }
522 643
523 if (fcn) { 644 if (fcn) {
524 ngx_queue_remove(&fcn->queue); 645 ngx_queue_remove(&fcn->queue);
525 646
526 fcn->uses++; 647 if (c->node == NULL) {
527 fcn->count++; 648 fcn->uses++;
649 fcn->count++;
650 }
528 651
529 if (fcn->error) { 652 if (fcn->error) {
530 653
531 if (fcn->valid_sec < ngx_time()) { 654 if (fcn->valid_sec < ngx_time()) {
532 goto renew; 655 goto renew;
619 u_char *p; 742 u_char *p;
620 ngx_http_cache_t *c; 743 ngx_http_cache_t *c;
621 744
622 c = r->cache; 745 c = r->cache;
623 746
747 if (c->file.name.len) {
748 return NGX_OK;
749 }
750
624 c->file.name.len = path->name.len + 1 + path->len 751 c->file.name.len = path->name.len + 1 + path->len
625 + 2 * NGX_HTTP_CACHE_KEY_LEN; 752 + 2 * NGX_HTTP_CACHE_KEY_LEN;
626 753
627 c->file.name.data = ngx_pnalloc(r->pool, c->file.name.len + 1); 754 c->file.name.data = ngx_pnalloc(r->pool, c->file.name.len + 1);
628 if (c->file.name.data == NULL) { 755 if (c->file.name.data == NULL) {
954 ngx_log_error(NGX_LOG_CRIT, c->file.log, ngx_errno, 1081 ngx_log_error(NGX_LOG_CRIT, c->file.log, ngx_errno,
955 ngx_delete_file_n " \"%s\" failed", 1082 ngx_delete_file_n " \"%s\" failed",
956 tf->file.name.data); 1083 tf->file.name.data);
957 } 1084 }
958 } 1085 }
1086 }
1087
1088 if (c->wait_event.timer_set) {
1089 ngx_del_timer(&c->wait_event);
959 } 1090 }
960 } 1091 }
961 1092
962 1093
963 static void 1094 static void