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