comparison src/http/ngx_http_core_module.c @ 230:38e7b94d63ac NGINX_0_4_0

nginx 0.4.0 *) Change in internal API: the HTTP modules initialization was moved from the init module phase to the HTTP postconfiguration phase. *) Change: now the request body is not read beforehand for the ngx_http_perl_module: it's required to start the reading using the $r->has_request_body method. *) Feature: the ngx_http_perl_module supports the DECLINED return code. *) Feature: the ngx_http_dav_module supports the incoming "Date" header line for the PUT method. *) Feature: the "ssi" directive is available inside the "if" block. *) Bugfix: a segmentation fault occurred if there was an "index" directive with variables and the first index name was without variables; bug appeared in 0.1.29.
author Igor Sysoev <http://sysoev.ru>
date Wed, 30 Aug 2006 00:00:00 +0400
parents 9eebc1b2cdbb
children c982febb7588
comparison
equal deleted inserted replaced
229:1965c8e23be7 230:38e7b94d63ac
21 #define NGX_HTTP_LOCATION_AUTO_REDIRECT 2 21 #define NGX_HTTP_LOCATION_AUTO_REDIRECT 2
22 #define NGX_HTTP_LOCATION_NOREGEX 3 22 #define NGX_HTTP_LOCATION_NOREGEX 3
23 #define NGX_HTTP_LOCATION_REGEX 4 23 #define NGX_HTTP_LOCATION_REGEX 4
24 24
25 25
26 static void ngx_http_core_run_phases(ngx_http_request_t *r);
27 static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r, 26 static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r,
28 ngx_array_t *locations, size_t len); 27 ngx_array_t *locations, size_t len);
29 28
30 static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf); 29 static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
31 static void *ngx_http_core_create_main_conf(ngx_conf_t *cf); 30 static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
472 471
473 472
474 void 473 void
475 ngx_http_handler(ngx_http_request_t *r) 474 ngx_http_handler(ngx_http_request_t *r)
476 { 475 {
476 ngx_http_core_main_conf_t *cmcf;
477
477 r->connection->log->action = NULL; 478 r->connection->log->action = NULL;
478 479
479 r->connection->unexpected_eof = 0; 480 r->connection->unexpected_eof = 0;
480 481
481 if (!r->internal) { 482 if (!r->internal) {
498 } 499 }
499 500
500 if (r->keepalive && r->headers_in.msie && r->method == NGX_HTTP_POST) { 501 if (r->keepalive && r->headers_in.msie && r->method == NGX_HTTP_POST) {
501 502
502 /* 503 /*
503 * MSIE may wait for some time if the response for 504 * MSIE may wait for some time if an response for
504 * the POST request is sent over the keepalive connection 505 * a POST request was sent over a keepalive connection
505 */ 506 */
506 507
507 r->keepalive = 0; 508 r->keepalive = 0;
508 } 509 }
509 510
513 } else { 514 } else {
514 r->lingering_close = 0; 515 r->lingering_close = 0;
515 } 516 }
516 } 517 }
517 518
518 r->write_event_handler = ngx_http_core_run_phases;
519
520 r->valid_unparsed_uri = 1; 519 r->valid_unparsed_uri = 1;
521 r->valid_location = 1; 520 r->valid_location = 1;
522 r->uri_changed = 1; 521
523 522 if (!r->internal) {
524 r->phase = (!r->internal) ? NGX_HTTP_POST_READ_PHASE: 523 r->phase_handler = 0;
525 NGX_HTTP_SERVER_REWRITE_PHASE; 524
526 r->phase_handler = 0; 525 } else {
527 526 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
527 r->phase_handler = cmcf->phase_engine.server_rewrite_index;
528 }
529
530 r->write_event_handler = ngx_http_core_run_phases;
528 ngx_http_core_run_phases(r); 531 ngx_http_core_run_phases(r);
529 } 532 }
530 533
531 534
532 static void 535 void
533 ngx_http_core_run_phases(ngx_http_request_t *r) 536 ngx_http_core_run_phases(ngx_http_request_t *r)
534 { 537 {
535 ngx_int_t rc; 538 ngx_int_t rc;
536 ngx_str_t path; 539 ngx_http_phase_handler_t *ph;
537 ngx_http_handler_pt *h;
538 ngx_http_core_loc_conf_t *clcf;
539 ngx_http_core_main_conf_t *cmcf; 540 ngx_http_core_main_conf_t *cmcf;
540 541
541 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
542 "http phase handler");
543
544 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); 542 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
545 543
546 for (/* void */; r->phase < NGX_HTTP_LOG_PHASE; r->phase++) { 544 ph = cmcf->phase_engine.handlers;
547 545
548 if (r->phase == NGX_HTTP_REWRITE_PHASE + 1 && r->uri_changed) { 546 while (ph[r->phase_handler].checker) {
549 547
550 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 548 rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler]);
551 "uri changes: %d", r->uri_changes); 549
552 550 if (rc == NGX_OK) {
553 /*
554 * gcc before 3.3 compiles the broken code for
555 * if (r->uri_changes-- == 0)
556 * if the r->uri_changes is defined as
557 * unsigned uri_changes:4
558 */
559
560 r->uri_changes--;
561
562 if (r->uri_changes == 0) {
563 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
564 "rewrite or internal redirection cycle "
565 "while processing \"%V\"", &r->uri);
566 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
567 return;
568 }
569
570 r->phase = NGX_HTTP_FIND_CONFIG_PHASE;
571 }
572
573 if (r->phase == NGX_HTTP_ACCESS_PHASE && r != r->main) {
574 continue;
575 }
576
577 if (r->phase == NGX_HTTP_CONTENT_PHASE && r->content_handler) {
578 r->write_event_handler = ngx_http_request_empty_handler;
579 ngx_http_finalize_request(r, r->content_handler(r));
580 return; 551 return;
581 } 552 }
582 553 }
583 h = cmcf->phases[r->phase].handlers.elts;
584 for (r->phase_handler = cmcf->phases[r->phase].handlers.nelts - 1;
585 r->phase_handler >= 0;
586 r->phase_handler--)
587 {
588 rc = h[r->phase_handler](r);
589
590 if (rc == NGX_DONE) {
591
592 /*
593 * we should never use r here because
594 * it may point to already freed data
595 */
596
597 return;
598 }
599
600 if (rc == NGX_DECLINED) {
601 continue;
602 }
603
604 if (r->phase == NGX_HTTP_ACCESS_PHASE) {
605 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
606
607 if (clcf->satisfy_any) {
608
609 if (rc == NGX_OK) {
610 r->access_code = 0;
611
612 if (r->headers_out.www_authenticate) {
613 r->headers_out.www_authenticate->hash = 0;
614 }
615
616 break;
617 }
618
619 if (rc == NGX_HTTP_FORBIDDEN || rc == NGX_HTTP_UNAUTHORIZED)
620 {
621 r->access_code = rc;
622
623 continue;
624 }
625 }
626 }
627
628 if (rc >= NGX_HTTP_SPECIAL_RESPONSE
629 || rc == NGX_HTTP_NO_CONTENT
630 || rc == NGX_ERROR)
631 {
632 ngx_http_finalize_request(r, rc);
633 return;
634 }
635
636 if (r->phase == NGX_HTTP_CONTENT_PHASE) {
637 ngx_http_finalize_request(r, rc);
638 return;
639 }
640
641 if (rc == NGX_AGAIN) {
642 return;
643 }
644
645 if (rc == NGX_OK && cmcf->phases[r->phase].type == NGX_OK) {
646 break;
647 }
648
649 }
650
651 if (r->phase == NGX_HTTP_ACCESS_PHASE && r->access_code) {
652
653 if (r->access_code == NGX_HTTP_FORBIDDEN) {
654 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
655 "access forbidden by rule");
656 }
657
658 ngx_http_finalize_request(r, r->access_code);
659 return;
660 }
661 }
662
663 /* no content handler was found */
664
665 if (r->uri.data[r->uri.len - 1] == '/' && !r->zero_in_uri) {
666
667 if (ngx_http_map_uri_to_path(r, &path, 0) != NULL) {
668 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
669 "directory index of \"%V\" is forbidden", &path);
670 }
671
672 ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
673 return;
674 }
675
676 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no handler found");
677
678 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
679 } 554 }
680 555
681 556
682 ngx_int_t 557 ngx_int_t
683 ngx_http_find_location_config(ngx_http_request_t *r) 558 ngx_http_core_generic_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
559 {
560 ngx_int_t rc;
561
562 /*
563 * generic phase checker,
564 * used by the post read, server rewrite, rewrite, and pre-access phases
565 */
566
567 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
568 "generic phase: %ui", r->phase_handler);
569
570 rc = ph->handler(r);
571
572 if (rc == NGX_OK) {
573 r->phase_handler = ph->next;
574 return NGX_AGAIN;
575 }
576
577 if (rc == NGX_DECLINED) {
578 r->phase_handler++;
579 return NGX_AGAIN;
580 }
581
582 if (rc == NGX_AGAIN || rc == NGX_DONE) {
583 return NGX_OK;
584 }
585
586 /* rc == NGX_ERROR || rc == NGX_HTTP_... */
587
588 ngx_http_finalize_request(r, rc);
589
590 return NGX_OK;
591 }
592
593
594 ngx_int_t
595 ngx_http_core_find_config_phase(ngx_http_request_t *r,
596 ngx_http_phase_handler_t *ph)
684 { 597 {
685 ngx_int_t rc; 598 ngx_int_t rc;
686 ngx_http_core_loc_conf_t *clcf; 599 ngx_http_core_loc_conf_t *clcf;
687 ngx_http_core_srv_conf_t *cscf; 600 ngx_http_core_srv_conf_t *cscf;
688 601
692 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); 605 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
693 606
694 rc = ngx_http_core_find_location(r, &cscf->locations, 0); 607 rc = ngx_http_core_find_location(r, &cscf->locations, 0);
695 608
696 if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) { 609 if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
697 return rc; 610 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
611 return NGX_OK;
698 } 612 }
699 613
700 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 614 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
701 615
702 if (!r->internal && clcf->internal) { 616 if (!r->internal && clcf->internal) {
703 return NGX_HTTP_NOT_FOUND; 617 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
618 return NGX_OK;
704 } 619 }
705 620
706 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 621 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
707 "using configuration \"%s%V\"", 622 "using configuration \"%s%V\"",
708 (clcf->noname ? "*" : (clcf->exact_match ? "=" : "")), 623 (clcf->noname ? "*" : (clcf->exact_match ? "=" : "")),
721 { 636 {
722 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 637 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
723 "client intented to send too large body: %O bytes", 638 "client intented to send too large body: %O bytes",
724 r->headers_in.content_length_n); 639 r->headers_in.content_length_n);
725 640
726 return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE; 641 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
642 return NGX_OK;
727 } 643 }
728 644
729 645
730 if (rc == NGX_HTTP_LOCATION_AUTO_REDIRECT) { 646 if (rc == NGX_HTTP_LOCATION_AUTO_REDIRECT) {
731 r->headers_out.location = ngx_list_push(&r->headers_out.headers); 647 r->headers_out.location = ngx_list_push(&r->headers_out.headers);
732 if (r->headers_out.location == NULL) { 648 if (r->headers_out.location == NULL) {
733 return NGX_HTTP_INTERNAL_SERVER_ERROR; 649 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
650 return NGX_OK;
734 } 651 }
735 652
736 /* 653 /*
737 * we do not need to set the r->headers_out.location->hash and 654 * we do not need to set the r->headers_out.location->hash and
738 * r->headers_out.location->key fields 655 * r->headers_out.location->key fields
739 */ 656 */
740 657
741 r->headers_out.location->value = clcf->name; 658 r->headers_out.location->value = clcf->name;
742 659
743 return NGX_HTTP_MOVED_PERMANENTLY; 660 ngx_http_finalize_request(r, NGX_HTTP_MOVED_PERMANENTLY);
744 } 661 return NGX_OK;
745 662 }
663
664 r->phase_handler++;
665 return NGX_AGAIN;
666 }
667
668
669 ngx_int_t
670 ngx_http_core_post_rewrite_phase(ngx_http_request_t *r,
671 ngx_http_phase_handler_t *ph)
672 {
673 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
674 "post rewrite phase: %ui", r->phase_handler);
675
676 if (!r->uri_changed) {
677 r->phase_handler++;
678 return NGX_AGAIN;
679 }
680
681 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
682 "uri changes: %d", r->uri_changes);
683
684 /*
685 * gcc before 3.3 compiles the broken code for
686 * if (r->uri_changes-- == 0)
687 * if the r->uri_changes is defined as
688 * unsigned uri_changes:4
689 */
690
691 r->uri_changes--;
692
693 if (r->uri_changes == 0) {
694 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
695 "rewrite or internal redirection cycle "
696 "while processing \"%V\"", &r->uri);
697
698 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
699 return NGX_OK;
700 }
701
702 r->phase_handler = ph->next;
703
704 return NGX_AGAIN;
705 }
706
707
708 ngx_int_t
709 ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
710 {
711 ngx_int_t rc;
712 ngx_http_core_loc_conf_t *clcf;
713
714 if (r != r->main) {
715 r->phase_handler = ph->next;
716 return NGX_AGAIN;
717 }
718
719 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
720 "access phase: %ui", r->phase_handler);
721
722 rc = ph->handler(r);
723
724 if (rc == NGX_DECLINED) {
725 r->phase_handler++;
726 return NGX_AGAIN;
727 }
728
729 if (rc == NGX_AGAIN || rc == NGX_DONE) {
730 return NGX_OK;
731 }
732
733 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
734
735 if (clcf->satisfy_any == 0) {
736
737 if (rc == NGX_OK) {
738 r->phase_handler++;
739 return NGX_AGAIN;
740 }
741
742 } else {
743 if (rc == NGX_OK) {
744 r->access_code = 0;
745
746 if (r->headers_out.www_authenticate) {
747 r->headers_out.www_authenticate->hash = 0;
748 }
749
750 r->phase_handler = ph->next;
751 return NGX_AGAIN;
752 }
753
754 if (rc == NGX_HTTP_FORBIDDEN || rc == NGX_HTTP_UNAUTHORIZED) {
755 r->access_code = rc;
756
757 r->phase_handler++;
758 return NGX_AGAIN;
759 }
760 }
761
762 /* rc == NGX_ERROR || rc == NGX_HTTP_... */
763
764 ngx_http_finalize_request(r, rc);
765 return NGX_OK;
766 }
767
768
769 ngx_int_t
770 ngx_http_core_post_access_phase(ngx_http_request_t *r,
771 ngx_http_phase_handler_t *ph)
772 {
773 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
774 "post access phase: %ui", r->phase_handler);
775
776 if (r->access_code) {
777
778 if (r->access_code == NGX_HTTP_FORBIDDEN) {
779 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
780 "access forbidden by rule");
781 }
782
783 ngx_http_finalize_request(r, r->access_code);
784 return NGX_OK;
785 }
786
787 r->phase_handler++;
788 return NGX_AGAIN;
789 }
790
791
792 ngx_int_t
793 ngx_http_core_content_phase(ngx_http_request_t *r,
794 ngx_http_phase_handler_t *ph)
795 {
796 ngx_int_t rc;
797 ngx_str_t path;
798
799 if (r->content_handler) {
800 r->write_event_handler = ngx_http_request_empty_handler;
801 ngx_http_finalize_request(r, r->content_handler(r));
802 return NGX_OK;
803 }
804
805 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
806 "content phase: %ui", r->phase_handler);
807
808 rc = ph->handler(r);
809
810 if (rc == NGX_DONE) {
811 return NGX_OK;
812 }
813
814 if (rc != NGX_DECLINED) {
815 ngx_http_finalize_request(r, rc);
816 return NGX_OK;
817 }
818
819 /* rc == NGX_DECLINED */
820
821 ph++;
822
823 if (ph->checker) {
824 r->phase_handler++;
825 return NGX_AGAIN;
826 }
827
828 /* no content handler was found */
829
830 if (r->uri.data[r->uri.len - 1] == '/' && !r->zero_in_uri) {
831
832 if (ngx_http_map_uri_to_path(r, &path, 0) != NULL) {
833 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
834 "directory index of \"%V\" is forbidden", &path);
835 }
836
837 ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
838 return NGX_OK;
839 }
840
841 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no handler found");
842
843 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
746 return NGX_OK; 844 return NGX_OK;
747 } 845 }
748 846
749 847
750 void 848 void
1914 == NGX_ERROR) 2012 == NGX_ERROR)
1915 { 2013 {
1916 return NGX_CONF_ERROR; 2014 return NGX_CONF_ERROR;
1917 } 2015 }
1918 2016
1919 if (ngx_array_init(&cscf->server_names, cf->pool, 4, 2017 if (ngx_array_init(&cscf->server_names, cf->temp_pool, 4,
1920 sizeof(ngx_http_server_name_t)) 2018 sizeof(ngx_http_server_name_t))
1921 == NGX_ERROR) 2019 == NGX_ERROR)
1922 { 2020 {
1923 return NGX_CONF_ERROR; 2021 return NGX_CONF_ERROR;
1924 } 2022 }