Mercurial > hg > nginx-vendor-0-8
comparison src/http/ngx_http_upstream.c @ 518:86dad910eeb6 NGINX_0_8_11
nginx 0.8.11
*) Change: directive "gzip_disable msie6" enables gzipping for
MSIE 6.0 SV1.
*) Feature: file AIO support on FreeBSD and Linux.
*) Feature: the "directio_alignment" directive.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Fri, 28 Aug 2009 00:00:00 +0400 |
parents | 7efcdb937752 |
children | 80f7156c2965 |
comparison
equal
deleted
inserted
replaced
517:15b5cddc5190 | 518:86dad910eeb6 |
---|---|
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); |
377 u->peer.log_error = NGX_ERROR_ERR; | 378 u->peer.log_error = NGX_ERROR_ERR; |
378 #if (NGX_THREADS) | 379 #if (NGX_THREADS) |
379 u->peer.lock = &r->connection->lock; | 380 u->peer.lock = &r->connection->lock; |
380 #endif | 381 #endif |
381 | 382 |
383 #if (NGX_HTTP_CACHE) | |
384 r->cache = NULL; | |
385 #endif | |
386 | |
382 return NGX_OK; | 387 return NGX_OK; |
383 } | 388 } |
384 | 389 |
385 | 390 |
386 void | 391 void |
387 ngx_http_upstream_init(ngx_http_request_t *r) | 392 ngx_http_upstream_init(ngx_http_request_t *r) |
388 { | 393 { |
394 ngx_connection_t *c; | |
395 | |
396 c = r->connection; | |
397 | |
398 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
399 "http init upstream, client timer: %d", c->read->timer_set); | |
400 | |
401 if (c->read->timer_set) { | |
402 ngx_del_timer(c->read); | |
403 } | |
404 | |
405 if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { | |
406 | |
407 if (!c->write->active) { | |
408 if (ngx_add_event(c->write, NGX_WRITE_EVENT, NGX_CLEAR_EVENT) | |
409 == NGX_ERROR) | |
410 { | |
411 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
412 return; | |
413 } | |
414 } | |
415 } | |
416 | |
417 ngx_http_upstream_init_request(r); | |
418 } | |
419 | |
420 | |
421 static void | |
422 ngx_http_upstream_init_request(ngx_http_request_t *r) | |
423 { | |
389 ngx_str_t *host; | 424 ngx_str_t *host; |
390 ngx_uint_t i; | 425 ngx_uint_t i; |
391 ngx_connection_t *c; | |
392 ngx_resolver_ctx_t *ctx, temp; | 426 ngx_resolver_ctx_t *ctx, temp; |
393 ngx_http_cleanup_t *cln; | 427 ngx_http_cleanup_t *cln; |
394 ngx_http_upstream_t *u; | 428 ngx_http_upstream_t *u; |
395 ngx_http_core_loc_conf_t *clcf; | 429 ngx_http_core_loc_conf_t *clcf; |
396 ngx_http_upstream_srv_conf_t *uscf, **uscfp; | 430 ngx_http_upstream_srv_conf_t *uscf, **uscfp; |
397 ngx_http_upstream_main_conf_t *umcf; | 431 ngx_http_upstream_main_conf_t *umcf; |
398 | 432 |
399 c = r->connection; | 433 if (r->aio) { |
400 | 434 return; |
401 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
402 "http init upstream, client timer: %d", c->read->timer_set); | |
403 | |
404 if (c->read->timer_set) { | |
405 ngx_del_timer(c->read); | |
406 } | 435 } |
407 | 436 |
408 u = r->upstream; | 437 u = r->upstream; |
438 | |
439 #if (NGX_HTTP_CACHE) | |
440 | |
441 if (u->conf->cache) { | |
442 ngx_int_t rc; | |
443 | |
444 rc = ngx_http_upstream_cache(r, u); | |
445 | |
446 if (rc == NGX_BUSY) { | |
447 r->write_event_handler = ngx_http_upstream_init_request; | |
448 return; | |
449 } | |
450 | |
451 r->write_event_handler = ngx_http_request_empty_handler; | |
452 | |
453 if (rc == NGX_DONE) { | |
454 return; | |
455 } | |
456 | |
457 if (rc != NGX_DECLINED) { | |
458 ngx_http_finalize_request(r, rc); | |
459 return; | |
460 } | |
461 } | |
462 | |
463 #endif | |
409 | 464 |
410 u->store = (u->conf->store || u->conf->store_lengths); | 465 u->store = (u->conf->store || u->conf->store_lengths); |
411 | 466 |
412 if (!u->store && !r->post_action && !u->conf->ignore_client_abort) { | 467 if (!u->store && !r->post_action && !u->conf->ignore_client_abort) { |
413 r->read_event_handler = ngx_http_upstream_rd_check_broken_connection; | 468 r->read_event_handler = ngx_http_upstream_rd_check_broken_connection; |
414 r->write_event_handler = ngx_http_upstream_wr_check_broken_connection; | 469 r->write_event_handler = ngx_http_upstream_wr_check_broken_connection; |
415 } | 470 } |
416 | 471 |
417 if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { | |
418 | |
419 if (!c->write->active) { | |
420 if (ngx_add_event(c->write, NGX_WRITE_EVENT, NGX_CLEAR_EVENT) | |
421 == NGX_ERROR) | |
422 { | |
423 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
424 return; | |
425 } | |
426 } | |
427 } | |
428 | |
429 if (r->request_body) { | 472 if (r->request_body) { |
430 u->request_bufs = r->request_body->bufs; | 473 u->request_bufs = r->request_body->bufs; |
431 } | 474 } |
432 | 475 |
433 #if (NGX_HTTP_CACHE) | |
434 | |
435 if (u->conf->cache) { | |
436 ngx_int_t rc; | |
437 | |
438 rc = ngx_http_upstream_cache(r, u); | |
439 | |
440 if (rc == NGX_DONE) { | |
441 return; | |
442 } | |
443 | |
444 if (rc != NGX_DECLINED) { | |
445 ngx_http_finalize_request(r, rc); | |
446 return; | |
447 } | |
448 } | |
449 | |
450 #endif | |
451 | |
452 if (u->create_request(r) != NGX_OK) { | 476 if (u->create_request(r) != NGX_OK) { |
453 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | 477 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
454 return; | 478 return; |
455 } | 479 } |
456 | 480 |
457 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 481 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
458 | 482 |
483 u->output.alignment = clcf->directio_alignment; | |
459 u->output.pool = r->pool; | 484 u->output.pool = r->pool; |
460 u->output.bufs.num = 1; | 485 u->output.bufs.num = 1; |
461 u->output.bufs.size = clcf->client_body_buffer_size; | 486 u->output.bufs.size = clcf->client_body_buffer_size; |
462 u->output.output_filter = ngx_chain_writer; | 487 u->output.output_filter = ngx_chain_writer; |
463 u->output.filter_ctx = &u->writer; | 488 u->output.filter_ctx = &u->writer; |
541 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | 566 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
542 return; | 567 return; |
543 } | 568 } |
544 | 569 |
545 if (ctx == NGX_NO_RESOLVER) { | 570 if (ctx == NGX_NO_RESOLVER) { |
546 ngx_log_error(NGX_LOG_ERR, c->log, 0, | 571 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
547 "no resolver defined to resolve %V", host); | 572 "no resolver defined to resolve %V", host); |
548 | 573 |
549 ngx_http_finalize_request(r, NGX_HTTP_BAD_GATEWAY); | 574 ngx_http_finalize_request(r, NGX_HTTP_BAD_GATEWAY); |
550 return; | 575 return; |
551 } | 576 } |
584 ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u) | 609 ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u) |
585 { | 610 { |
586 ngx_int_t rc; | 611 ngx_int_t rc; |
587 ngx_http_cache_t *c; | 612 ngx_http_cache_t *c; |
588 | 613 |
589 if (!(r->method & u->conf->cache_methods)) { | 614 c = r->cache; |
590 return NGX_DECLINED; | 615 |
591 } | |
592 | |
593 if (r->method & NGX_HTTP_HEAD) { | |
594 u->method = ngx_http_core_get_method; | |
595 } | |
596 | |
597 c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t)); | |
598 if (c == NULL) { | 616 if (c == NULL) { |
599 return NGX_ERROR; | 617 |
600 } | 618 if (!(r->method & u->conf->cache_methods)) { |
601 | 619 return NGX_DECLINED; |
602 if (ngx_array_init(&c->keys, r->pool, 4, sizeof(ngx_str_t)) != NGX_OK) { | 620 } |
603 return NGX_ERROR; | 621 |
604 } | 622 if (r->method & NGX_HTTP_HEAD) { |
605 | 623 u->method = ngx_http_core_get_method; |
606 r->cache = c; | 624 } |
607 c->file.log = r->connection->log; | 625 |
608 | 626 c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t)); |
609 if (u->create_key(r) != NGX_OK) { | 627 if (c == NULL) { |
610 return NGX_ERROR; | 628 return NGX_ERROR; |
611 } | 629 } |
612 | 630 |
613 /* TODO: add keys */ | 631 if (ngx_array_init(&c->keys, r->pool, 4, sizeof(ngx_str_t)) != NGX_OK) { |
614 | 632 return NGX_ERROR; |
615 ngx_http_file_cache_create_key(r); | 633 } |
616 | 634 |
617 u->cacheable = 1; | 635 r->cache = c; |
618 | 636 c->file.log = r->connection->log; |
619 c->min_uses = u->conf->cache_min_uses; | 637 |
620 c->body_start = u->conf->buffer_size; | 638 if (u->create_key(r) != NGX_OK) { |
621 c->file_cache = u->conf->cache->data; | 639 return NGX_ERROR; |
622 | 640 } |
623 u->cache_status = NGX_HTTP_CACHE_MISS; | 641 |
642 /* TODO: add keys */ | |
643 | |
644 ngx_http_file_cache_create_key(r); | |
645 | |
646 u->cacheable = 1; | |
647 | |
648 c->min_uses = u->conf->cache_min_uses; | |
649 c->body_start = u->conf->buffer_size; | |
650 c->file_cache = u->conf->cache->data; | |
651 | |
652 u->cache_status = NGX_HTTP_CACHE_MISS; | |
653 } | |
624 | 654 |
625 rc = ngx_http_file_cache_open(r); | 655 rc = ngx_http_file_cache_open(r); |
626 | 656 |
627 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 657 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
628 "http upstream cache: %i", rc); | 658 "http upstream cache: %i", rc); |
655 return rc; | 685 return rc; |
656 } | 686 } |
657 | 687 |
658 break; | 688 break; |
659 | 689 |
660 case NGX_ERROR: | |
661 | |
662 return NGX_ERROR; | |
663 | |
664 case NGX_HTTP_CACHE_STALE: | 690 case NGX_HTTP_CACHE_STALE: |
665 | 691 |
666 c->valid_sec = 0; | 692 c->valid_sec = 0; |
667 u->buffer.start = NULL; | 693 u->buffer.start = NULL; |
668 u->cache_status = NGX_HTTP_CACHE_EXPIRED; | 694 u->cache_status = NGX_HTTP_CACHE_EXPIRED; |
679 u->buffer.last = u->buffer.pos; | 705 u->buffer.last = u->buffer.pos; |
680 } | 706 } |
681 | 707 |
682 break; | 708 break; |
683 | 709 |
710 case NGX_HTTP_CACHE_SCARCE: | |
711 | |
712 u->cacheable = 0; | |
713 | |
714 break; | |
715 | |
684 case NGX_AGAIN: | 716 case NGX_AGAIN: |
685 | 717 |
686 u->cacheable = 0; | 718 return NGX_BUSY; |
687 | 719 |
688 break; | 720 case NGX_ERROR: |
721 | |
722 return NGX_ERROR; | |
689 | 723 |
690 default: | 724 default: |
691 | 725 |
692 /* cached NGX_HTTP_BAD_GATEWAY, NGX_HTTP_GATEWAY_TIME_OUT, etc. */ | 726 /* cached NGX_HTTP_BAD_GATEWAY, NGX_HTTP_GATEWAY_TIME_OUT, etc. */ |
693 | 727 |
2258 if (do_write) { | 2292 if (do_write) { |
2259 | 2293 |
2260 if (u->out_bufs || u->busy_bufs) { | 2294 if (u->out_bufs || u->busy_bufs) { |
2261 rc = ngx_http_output_filter(r, u->out_bufs); | 2295 rc = ngx_http_output_filter(r, u->out_bufs); |
2262 | 2296 |
2263 if (downstream->destroyed) { | |
2264 return; | |
2265 } | |
2266 | |
2267 if (rc == NGX_ERROR) { | 2297 if (rc == NGX_ERROR) { |
2268 ngx_http_upstream_finalize_request(r, u, 0); | 2298 ngx_http_upstream_finalize_request(r, u, 0); |
2269 return; | 2299 return; |
2270 } | 2300 } |
2271 | 2301 |
2434 | 2464 |
2435 return; | 2465 return; |
2436 } | 2466 } |
2437 | 2467 |
2438 if (ngx_event_pipe(p, wev->write) == NGX_ABORT) { | 2468 if (ngx_event_pipe(p, wev->write) == NGX_ABORT) { |
2439 | |
2440 if (c->destroyed) { | |
2441 return; | |
2442 } | |
2443 | |
2444 ngx_http_upstream_finalize_request(r, u, 0); | 2469 ngx_http_upstream_finalize_request(r, u, 0); |
2445 return; | 2470 return; |
2446 } | 2471 } |
2447 | 2472 |
2448 } else { | 2473 } else { |
2464 | 2489 |
2465 return; | 2490 return; |
2466 } | 2491 } |
2467 | 2492 |
2468 if (ngx_event_pipe(p, 1) == NGX_ABORT) { | 2493 if (ngx_event_pipe(p, 1) == NGX_ABORT) { |
2469 | |
2470 if (c->destroyed) { | |
2471 return; | |
2472 } | |
2473 | |
2474 ngx_http_upstream_finalize_request(r, u, 0); | 2494 ngx_http_upstream_finalize_request(r, u, 0); |
2475 return; | 2495 return; |
2476 } | 2496 } |
2477 } | 2497 } |
2478 | 2498 |
2496 if (c->read->timedout) { | 2516 if (c->read->timedout) { |
2497 u->pipe->upstream_error = 1; | 2517 u->pipe->upstream_error = 1; |
2498 ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); | 2518 ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); |
2499 | 2519 |
2500 } else { | 2520 } else { |
2501 c = r->connection; | |
2502 | |
2503 if (ngx_event_pipe(u->pipe, 0) == NGX_ABORT) { | 2521 if (ngx_event_pipe(u->pipe, 0) == NGX_ABORT) { |
2504 | |
2505 if (c->destroyed) { | |
2506 return; | |
2507 } | |
2508 | |
2509 ngx_http_upstream_finalize_request(r, u, 0); | 2522 ngx_http_upstream_finalize_request(r, u, 0); |
2510 return; | 2523 return; |
2511 } | 2524 } |
2512 } | 2525 } |
2513 | 2526 |