Mercurial > hg > nginx-ranges
comparison src/http/ngx_http_upstream.c @ 539:5f4de8cf0d9d
Merge with current.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Tue, 15 Sep 2009 03:43:40 +0400 |
parents | 0161f3197817 |
children | 4c5d2c627a6c |
comparison
equal
deleted
inserted
replaced
522:40fd8d7b82f9 | 539:5f4de8cf0d9d |
---|---|
16 ngx_http_upstream_t *u); | 16 ngx_http_upstream_t *u); |
17 static ngx_int_t ngx_http_upstream_cache_status(ngx_http_request_t *r, | 17 static ngx_int_t ngx_http_upstream_cache_status(ngx_http_request_t *r, |
18 ngx_http_variable_value_t *v, uintptr_t data); | 18 ngx_http_variable_value_t *v, uintptr_t data); |
19 #endif | 19 #endif |
20 | 20 |
21 static void ngx_http_upstream_init_request(ngx_http_request_t *r); | |
21 static void ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx); | 22 static void ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx); |
22 static void ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r); | 23 static void ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r); |
23 static void ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r); | 24 static void ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r); |
24 static void ngx_http_upstream_check_broken_connection(ngx_http_request_t *r, | 25 static void ngx_http_upstream_check_broken_connection(ngx_http_request_t *r, |
25 ngx_event_t *ev); | 26 ngx_event_t *ev); |
159 { ngx_string("Last-Modified"), | 160 { ngx_string("Last-Modified"), |
160 ngx_http_upstream_process_header_line, | 161 ngx_http_upstream_process_header_line, |
161 offsetof(ngx_http_upstream_headers_in_t, last_modified), | 162 offsetof(ngx_http_upstream_headers_in_t, last_modified), |
162 ngx_http_upstream_copy_last_modified, 0, 0 }, | 163 ngx_http_upstream_copy_last_modified, 0, 0 }, |
163 | 164 |
165 { ngx_string("ETag"), | |
166 ngx_http_upstream_process_header_line, | |
167 offsetof(ngx_http_upstream_headers_in_t, etag), | |
168 ngx_http_upstream_copy_header_line, | |
169 offsetof(ngx_http_headers_out_t, etag), 0 }, | |
170 | |
164 { ngx_string("Server"), | 171 { ngx_string("Server"), |
165 ngx_http_upstream_process_header_line, | 172 ngx_http_upstream_process_header_line, |
166 offsetof(ngx_http_upstream_headers_in_t, server), | 173 offsetof(ngx_http_upstream_headers_in_t, server), |
167 ngx_http_upstream_copy_header_line, | 174 ngx_http_upstream_copy_header_line, |
168 offsetof(ngx_http_headers_out_t, server), 0 }, | 175 offsetof(ngx_http_headers_out_t, server), 0 }, |
354 ngx_http_upstream_t *u; | 361 ngx_http_upstream_t *u; |
355 | 362 |
356 u = r->upstream; | 363 u = r->upstream; |
357 | 364 |
358 if (u && u->cleanup) { | 365 if (u && u->cleanup) { |
366 r->main->count++; | |
359 ngx_http_upstream_cleanup(r); | 367 ngx_http_upstream_cleanup(r); |
360 *u->cleanup = NULL; | 368 *u->cleanup = NULL; |
361 } | 369 } |
362 | 370 |
363 u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)); | 371 u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)); |
371 u->peer.log_error = NGX_ERROR_ERR; | 379 u->peer.log_error = NGX_ERROR_ERR; |
372 #if (NGX_THREADS) | 380 #if (NGX_THREADS) |
373 u->peer.lock = &r->connection->lock; | 381 u->peer.lock = &r->connection->lock; |
374 #endif | 382 #endif |
375 | 383 |
384 #if (NGX_HTTP_CACHE) | |
385 r->cache = NULL; | |
386 #endif | |
387 | |
376 return NGX_OK; | 388 return NGX_OK; |
377 } | 389 } |
378 | 390 |
379 | 391 |
380 void | 392 void |
381 ngx_http_upstream_init(ngx_http_request_t *r) | 393 ngx_http_upstream_init(ngx_http_request_t *r) |
382 { | 394 { |
395 ngx_connection_t *c; | |
396 | |
397 c = r->connection; | |
398 | |
399 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
400 "http init upstream, client timer: %d", c->read->timer_set); | |
401 | |
402 if (c->read->timer_set) { | |
403 ngx_del_timer(c->read); | |
404 } | |
405 | |
406 if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { | |
407 | |
408 if (!c->write->active) { | |
409 if (ngx_add_event(c->write, NGX_WRITE_EVENT, NGX_CLEAR_EVENT) | |
410 == NGX_ERROR) | |
411 { | |
412 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
413 return; | |
414 } | |
415 } | |
416 } | |
417 | |
418 ngx_http_upstream_init_request(r); | |
419 } | |
420 | |
421 | |
422 static void | |
423 ngx_http_upstream_init_request(ngx_http_request_t *r) | |
424 { | |
383 ngx_str_t *host; | 425 ngx_str_t *host; |
384 ngx_uint_t i; | 426 ngx_uint_t i; |
385 ngx_connection_t *c; | |
386 ngx_resolver_ctx_t *ctx, temp; | 427 ngx_resolver_ctx_t *ctx, temp; |
387 ngx_http_cleanup_t *cln; | 428 ngx_http_cleanup_t *cln; |
388 ngx_http_upstream_t *u; | 429 ngx_http_upstream_t *u; |
389 ngx_http_core_loc_conf_t *clcf; | 430 ngx_http_core_loc_conf_t *clcf; |
390 ngx_http_upstream_srv_conf_t *uscf, **uscfp; | 431 ngx_http_upstream_srv_conf_t *uscf, **uscfp; |
391 ngx_http_upstream_main_conf_t *umcf; | 432 ngx_http_upstream_main_conf_t *umcf; |
392 | 433 |
393 c = r->connection; | 434 if (r->aio) { |
394 | 435 return; |
395 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
396 "http init upstream, client timer: %d", c->read->timer_set); | |
397 | |
398 if (c->read->timer_set) { | |
399 ngx_del_timer(c->read); | |
400 } | 436 } |
401 | 437 |
402 u = r->upstream; | 438 u = r->upstream; |
439 | |
440 #if (NGX_HTTP_CACHE) | |
441 | |
442 if (u->conf->cache) { | |
443 ngx_int_t rc; | |
444 | |
445 rc = ngx_http_upstream_cache(r, u); | |
446 | |
447 if (rc == NGX_BUSY) { | |
448 r->write_event_handler = ngx_http_upstream_init_request; | |
449 return; | |
450 } | |
451 | |
452 r->write_event_handler = ngx_http_request_empty_handler; | |
453 | |
454 if (rc == NGX_DONE) { | |
455 return; | |
456 } | |
457 | |
458 if (rc != NGX_DECLINED) { | |
459 ngx_http_finalize_request(r, rc); | |
460 return; | |
461 } | |
462 } | |
463 | |
464 #endif | |
403 | 465 |
404 u->store = (u->conf->store || u->conf->store_lengths); | 466 u->store = (u->conf->store || u->conf->store_lengths); |
405 | 467 |
406 if (!u->store && !r->post_action && !u->conf->ignore_client_abort) { | 468 if (!u->store && !r->post_action && !u->conf->ignore_client_abort) { |
407 r->read_event_handler = ngx_http_upstream_rd_check_broken_connection; | 469 r->read_event_handler = ngx_http_upstream_rd_check_broken_connection; |
408 r->write_event_handler = ngx_http_upstream_wr_check_broken_connection; | 470 r->write_event_handler = ngx_http_upstream_wr_check_broken_connection; |
409 } | 471 } |
410 | 472 |
411 if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { | |
412 | |
413 if (!c->write->active) { | |
414 if (ngx_add_event(c->write, NGX_WRITE_EVENT, NGX_CLEAR_EVENT) | |
415 == NGX_ERROR) | |
416 { | |
417 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
418 return; | |
419 } | |
420 } | |
421 } | |
422 | |
423 if (r->request_body) { | 473 if (r->request_body) { |
424 u->request_bufs = r->request_body->bufs; | 474 u->request_bufs = r->request_body->bufs; |
425 } | 475 } |
426 | 476 |
427 #if (NGX_HTTP_CACHE) | |
428 | |
429 if (u->conf->cache) { | |
430 ngx_int_t rc; | |
431 | |
432 rc = ngx_http_upstream_cache(r, u); | |
433 | |
434 if (rc == NGX_DONE) { | |
435 return; | |
436 } | |
437 | |
438 if (rc != NGX_DECLINED) { | |
439 ngx_http_finalize_request(r, rc); | |
440 return; | |
441 } | |
442 } | |
443 | |
444 #endif | |
445 | |
446 if (u->create_request(r) != NGX_OK) { | 477 if (u->create_request(r) != NGX_OK) { |
447 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | 478 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
448 return; | 479 return; |
449 } | 480 } |
450 | 481 |
451 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 482 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
452 | 483 |
484 u->output.alignment = clcf->directio_alignment; | |
453 u->output.pool = r->pool; | 485 u->output.pool = r->pool; |
454 u->output.bufs.num = 1; | 486 u->output.bufs.num = 1; |
455 u->output.bufs.size = clcf->client_body_buffer_size; | 487 u->output.bufs.size = clcf->client_body_buffer_size; |
456 u->output.output_filter = ngx_chain_writer; | 488 u->output.output_filter = ngx_chain_writer; |
457 u->output.filter_ctx = &u->writer; | 489 u->output.filter_ctx = &u->writer; |
535 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | 567 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
536 return; | 568 return; |
537 } | 569 } |
538 | 570 |
539 if (ctx == NGX_NO_RESOLVER) { | 571 if (ctx == NGX_NO_RESOLVER) { |
540 ngx_log_error(NGX_LOG_ERR, c->log, 0, | 572 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
541 "no resolver defined to resolve %V", host); | 573 "no resolver defined to resolve %V", host); |
542 | 574 |
543 ngx_http_finalize_request(r, NGX_HTTP_BAD_GATEWAY); | 575 ngx_http_finalize_request(r, NGX_HTTP_BAD_GATEWAY); |
544 return; | 576 return; |
545 } | 577 } |
578 ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u) | 610 ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u) |
579 { | 611 { |
580 ngx_int_t rc; | 612 ngx_int_t rc; |
581 ngx_http_cache_t *c; | 613 ngx_http_cache_t *c; |
582 | 614 |
583 if (!(r->method & u->conf->cache_methods)) { | 615 c = r->cache; |
584 return NGX_DECLINED; | 616 |
585 } | |
586 | |
587 if (r->method & NGX_HTTP_HEAD) { | |
588 u->method = ngx_http_core_get_method; | |
589 } | |
590 | |
591 c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t)); | |
592 if (c == NULL) { | 617 if (c == NULL) { |
593 return NGX_ERROR; | 618 |
594 } | 619 if (!(r->method & u->conf->cache_methods)) { |
595 | 620 return NGX_DECLINED; |
596 if (ngx_array_init(&c->keys, r->pool, 4, sizeof(ngx_str_t)) != NGX_OK) { | 621 } |
597 return NGX_ERROR; | 622 |
598 } | 623 if (r->method & NGX_HTTP_HEAD) { |
599 | 624 u->method = ngx_http_core_get_method; |
600 r->cache = c; | 625 } |
601 c->file.log = r->connection->log; | 626 |
602 | 627 c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t)); |
603 if (u->create_key(r) != NGX_OK) { | 628 if (c == NULL) { |
604 return NGX_ERROR; | 629 return NGX_ERROR; |
605 } | 630 } |
606 | 631 |
607 /* TODO: add keys */ | 632 if (ngx_array_init(&c->keys, r->pool, 4, sizeof(ngx_str_t)) != NGX_OK) { |
608 | 633 return NGX_ERROR; |
609 ngx_http_file_cache_create_key(r); | 634 } |
610 | 635 |
611 u->cacheable = 1; | 636 r->cache = c; |
612 | 637 c->file.log = r->connection->log; |
613 c->min_uses = u->conf->cache_min_uses; | 638 |
614 c->body_start = u->conf->buffer_size; | 639 if (u->create_key(r) != NGX_OK) { |
615 c->file_cache = u->conf->cache->data; | 640 return NGX_ERROR; |
616 | 641 } |
617 u->cache_status = NGX_HTTP_CACHE_MISS; | 642 |
643 /* TODO: add keys */ | |
644 | |
645 ngx_http_file_cache_create_key(r); | |
646 | |
647 u->cacheable = 1; | |
648 | |
649 c->min_uses = u->conf->cache_min_uses; | |
650 c->body_start = u->conf->buffer_size; | |
651 c->file_cache = u->conf->cache->data; | |
652 | |
653 u->cache_status = NGX_HTTP_CACHE_MISS; | |
654 } | |
618 | 655 |
619 rc = ngx_http_file_cache_open(r); | 656 rc = ngx_http_file_cache_open(r); |
620 | 657 |
621 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 658 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
622 "http upstream cache: %i", rc); | 659 "http upstream cache: %i", rc); |
649 return rc; | 686 return rc; |
650 } | 687 } |
651 | 688 |
652 break; | 689 break; |
653 | 690 |
654 case NGX_ERROR: | |
655 | |
656 return NGX_ERROR; | |
657 | |
658 case NGX_HTTP_CACHE_STALE: | 691 case NGX_HTTP_CACHE_STALE: |
659 | 692 |
660 c->valid_sec = 0; | 693 c->valid_sec = 0; |
661 u->buffer.start = NULL; | 694 u->buffer.start = NULL; |
662 u->cache_status = NGX_HTTP_CACHE_EXPIRED; | 695 u->cache_status = NGX_HTTP_CACHE_EXPIRED; |
673 u->buffer.last = u->buffer.pos; | 706 u->buffer.last = u->buffer.pos; |
674 } | 707 } |
675 | 708 |
676 break; | 709 break; |
677 | 710 |
711 case NGX_HTTP_CACHE_SCARCE: | |
712 | |
713 u->cacheable = 0; | |
714 | |
715 break; | |
716 | |
678 case NGX_AGAIN: | 717 case NGX_AGAIN: |
679 | 718 |
680 u->cacheable = 0; | 719 return NGX_BUSY; |
681 | 720 |
682 break; | 721 case NGX_ERROR: |
722 | |
723 return NGX_ERROR; | |
683 | 724 |
684 default: | 725 default: |
685 | 726 |
686 /* cached NGX_HTTP_BAD_GATEWAY, NGX_HTTP_GATEWAY_TIME_OUT, etc. */ | 727 /* cached NGX_HTTP_BAD_GATEWAY, NGX_HTTP_GATEWAY_TIME_OUT, etc. */ |
687 | 728 |
1772 } | 1813 } |
1773 | 1814 |
1774 r->valid_unparsed_uri = 0; | 1815 r->valid_unparsed_uri = 0; |
1775 | 1816 |
1776 ngx_http_internal_redirect(r, uri, &args); | 1817 ngx_http_internal_redirect(r, uri, &args); |
1818 ngx_http_finalize_request(r, NGX_DONE); | |
1777 return NGX_DONE; | 1819 return NGX_DONE; |
1778 } | 1820 } |
1779 | 1821 |
1780 part = &u->headers_in.headers.part; | 1822 part = &u->headers_in.headers.part; |
1781 h = part->elts; | 1823 h = part->elts; |
2070 } | 2112 } |
2071 } | 2113 } |
2072 | 2114 |
2073 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 2115 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
2074 "http cacheable: %d", u->cacheable); | 2116 "http cacheable: %d", u->cacheable); |
2117 | |
2118 if (u->cacheable == 0 && r->cache) { | |
2119 ngx_http_file_cache_free(r, u->pipe->temp_file); | |
2120 } | |
2075 | 2121 |
2076 #endif | 2122 #endif |
2077 | 2123 |
2078 p = u->pipe; | 2124 p = u->pipe; |
2079 | 2125 |
2252 if (do_write) { | 2298 if (do_write) { |
2253 | 2299 |
2254 if (u->out_bufs || u->busy_bufs) { | 2300 if (u->out_bufs || u->busy_bufs) { |
2255 rc = ngx_http_output_filter(r, u->out_bufs); | 2301 rc = ngx_http_output_filter(r, u->out_bufs); |
2256 | 2302 |
2257 if (downstream->destroyed) { | |
2258 return; | |
2259 } | |
2260 | |
2261 if (rc == NGX_ERROR) { | 2303 if (rc == NGX_ERROR) { |
2262 ngx_http_upstream_finalize_request(r, u, 0); | 2304 ngx_http_upstream_finalize_request(r, u, 0); |
2263 return; | 2305 return; |
2264 } | 2306 } |
2265 | 2307 |
2428 | 2470 |
2429 return; | 2471 return; |
2430 } | 2472 } |
2431 | 2473 |
2432 if (ngx_event_pipe(p, wev->write) == NGX_ABORT) { | 2474 if (ngx_event_pipe(p, wev->write) == NGX_ABORT) { |
2433 | |
2434 if (c->destroyed) { | |
2435 return; | |
2436 } | |
2437 | |
2438 ngx_http_upstream_finalize_request(r, u, 0); | 2475 ngx_http_upstream_finalize_request(r, u, 0); |
2439 return; | 2476 return; |
2440 } | 2477 } |
2441 | 2478 |
2442 } else { | 2479 } else { |
2458 | 2495 |
2459 return; | 2496 return; |
2460 } | 2497 } |
2461 | 2498 |
2462 if (ngx_event_pipe(p, 1) == NGX_ABORT) { | 2499 if (ngx_event_pipe(p, 1) == NGX_ABORT) { |
2463 | |
2464 if (c->destroyed) { | |
2465 return; | |
2466 } | |
2467 | |
2468 ngx_http_upstream_finalize_request(r, u, 0); | 2500 ngx_http_upstream_finalize_request(r, u, 0); |
2469 return; | 2501 return; |
2470 } | 2502 } |
2471 } | 2503 } |
2472 | 2504 |
2490 if (c->read->timedout) { | 2522 if (c->read->timedout) { |
2491 u->pipe->upstream_error = 1; | 2523 u->pipe->upstream_error = 1; |
2492 ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); | 2524 ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); |
2493 | 2525 |
2494 } else { | 2526 } else { |
2495 c = r->connection; | |
2496 | |
2497 if (ngx_event_pipe(u->pipe, 0) == NGX_ABORT) { | 2527 if (ngx_event_pipe(u->pipe, 0) == NGX_ABORT) { |
2498 | |
2499 if (c->destroyed) { | |
2500 return; | |
2501 } | |
2502 | |
2503 ngx_http_upstream_finalize_request(r, u, 0); | 2528 ngx_http_upstream_finalize_request(r, u, 0); |
2504 return; | 2529 return; |
2505 } | 2530 } |
2506 } | 2531 } |
2507 | 2532 |
2633 ext.access = u->conf->store_access; | 2658 ext.access = u->conf->store_access; |
2634 ext.path_access = u->conf->store_access; | 2659 ext.path_access = u->conf->store_access; |
2635 ext.time = -1; | 2660 ext.time = -1; |
2636 ext.create_path = 1; | 2661 ext.create_path = 1; |
2637 ext.delete_file = 1; | 2662 ext.delete_file = 1; |
2638 ext.log_rename_error = 1; | |
2639 ext.log = r->connection->log; | 2663 ext.log = r->connection->log; |
2640 | 2664 |
2641 if (u->headers_in.last_modified) { | 2665 if (u->headers_in.last_modified) { |
2642 | 2666 |
2643 lm = ngx_http_parse_time(u->headers_in.last_modified->value.data, | 2667 lm = ngx_http_parse_time(u->headers_in.last_modified->value.data, |
2660 { | 2684 { |
2661 return; | 2685 return; |
2662 } | 2686 } |
2663 } | 2687 } |
2664 | 2688 |
2689 path.len--; | |
2690 | |
2665 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 2691 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2666 "upstream stores \"%s\" to \"%s\"", | 2692 "upstream stores \"%s\" to \"%s\"", |
2667 tf->file.name.data, path.data); | 2693 tf->file.name.data, path.data); |
2668 | 2694 |
2669 (void) ngx_ext_rename_file(&tf->file.name, &path, &ext); | 2695 (void) ngx_ext_rename_file(&tf->file.name, &path, &ext); |
2881 u->pipe->temp_file->file.fd); | 2907 u->pipe->temp_file->file.fd); |
2882 } | 2908 } |
2883 | 2909 |
2884 #if (NGX_HTTP_CACHE) | 2910 #if (NGX_HTTP_CACHE) |
2885 | 2911 |
2886 if (u->cacheable) { | 2912 if (u->cacheable && r->cache) { |
2887 time_t valid; | 2913 time_t valid; |
2888 | 2914 |
2889 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 2915 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2890 "http upstream cache fd: %d", | 2916 "http upstream cache fd: %d", |
2891 r->cache->file.fd); | 2917 r->cache->file.fd); |