comparison src/http/ngx_http_request.c @ 144:ef8c87afcfc5

nginx-0.0.1-2003-10-12-20:49:16 import
author Igor Sysoev <igor@sysoev.ru>
date Sun, 12 Oct 2003 16:49:16 +0000
parents 5526213be452
children 5afee0074707
comparison
equal deleted inserted replaced
143:5526213be452 144:ef8c87afcfc5
20 static void ngx_http_keepalive_handler(ngx_event_t *ev); 20 static void ngx_http_keepalive_handler(ngx_event_t *ev);
21 static void ngx_http_set_lingering_close(ngx_http_request_t *r); 21 static void ngx_http_set_lingering_close(ngx_http_request_t *r);
22 static void ngx_http_lingering_close_handler(ngx_event_t *ev); 22 static void ngx_http_lingering_close_handler(ngx_event_t *ev);
23 static void ngx_http_empty_handler(ngx_event_t *wev); 23 static void ngx_http_empty_handler(ngx_event_t *wev);
24 24
25 static void ngx_http_header_parse_error(ngx_http_request_t *r, int parse_err); 25 static void ngx_http_header_parse_error(ngx_http_request_t *r,
26 int parse_err, int error);
26 static size_t ngx_http_log_error(void *data, char *buf, size_t len); 27 static size_t ngx_http_log_error(void *data, char *buf, size_t len);
27 28
28 29
29 /* NGX_HTTP_PARSE_ ... errors */ 30 /* NGX_HTTP_PARSE_ ... errors */
30 31
63 }; 64 };
64 65
65 66
66 void ngx_http_init_connection(ngx_connection_t *c) 67 void ngx_http_init_connection(ngx_connection_t *c)
67 { 68 {
68 int event;
69 ngx_event_t *rev; 69 ngx_event_t *rev;
70 ngx_http_log_ctx_t *lctx; 70 ngx_http_log_ctx_t *lctx;
71 71
72 c->addr_text.data = ngx_palloc(c->pool, c->listening->addr_text_max_len); 72 c->addr_text.data = ngx_palloc(c->pool, c->listening->addr_text_max_len);
73 if (c->addr_text.data == NULL) { 73 if (c->addr_text.data == NULL) {
102 ngx_http_init_request(rev); 102 ngx_http_init_request(rev);
103 return; 103 return;
104 } 104 }
105 105
106 ngx_add_timer(rev, c->listening->post_accept_timeout); 106 ngx_add_timer(rev, c->listening->post_accept_timeout);
107 rev->timer_set = 1; 107
108 108 if (ngx_event_flags & (NGX_USE_AIO_EVENT|NGX_USE_EDGE_EVENT)) {
109 if (ngx_event_flags & (NGX_HAVE_AIO_EVENT|NGX_HAVE_EDGE_EVENT)) {
110 /* aio, iocp, epoll */ 109 /* aio, iocp, epoll */
111 ngx_http_init_request(rev); 110 ngx_http_init_request(rev);
112 return; 111 return;
113 } 112 }
114 113
115 if (ngx_handle_read_event(rev) == NGX_ERROR) { 114 if (ngx_handle_read_event(rev) == NGX_ERROR) {
116 ngx_http_close_connection(c); 115 ngx_http_close_connection(c);
117 return; 116 return;
118 } 117 }
119
120 #if 0
121
122 if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) {
123 /* kqueue */
124 event = NGX_CLEAR_EVENT;
125
126 } else {
127 /* select, poll, /dev/poll */
128 event = NGX_LEVEL_EVENT;
129 }
130
131 if (ngx_add_event(rev, NGX_READ_EVENT, event) == NGX_ERROR) {
132 ngx_http_close_connection(c);
133 }
134
135 #endif
136
137 return;
138 } 118 }
139 119
140 120
141 static void ngx_http_init_request(ngx_event_t *rev) 121 static void ngx_http_init_request(ngx_event_t *rev)
142 { 122 {
151 ngx_http_core_srv_conf_t *cscf; 131 ngx_http_core_srv_conf_t *cscf;
152 ngx_http_core_loc_conf_t *clcf; 132 ngx_http_core_loc_conf_t *clcf;
153 133
154 c = rev->data; 134 c = rev->data;
155 135
156 r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)); 136 if (c->data) {
157 if (r == NULL) { 137 r = c->data;
158 ngx_http_close_connection(c); 138 ngx_memzero(r, sizeof(ngx_http_request_t));
159 return; 139
140 } else {
141 r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t));
142 if (r == NULL) {
143 ngx_http_close_connection(c);
144 return;
145 }
160 } 146 }
161 147
162 /* find the server configuration for the address:port */ 148 /* find the server configuration for the address:port */
163 149
164 /* AF_INET only */ 150 /* AF_INET only */
313 if (r->complex_uri || r->unusual_uri) { 299 if (r->complex_uri || r->unusual_uri) {
314 r->request_line.len = r->request_end - r->request_start; 300 r->request_line.len = r->request_end - r->request_start;
315 r->request_line.data = r->request_start; 301 r->request_line.data = r->request_start;
316 r->request_line.data[r->request_line.len] = '\0'; 302 r->request_line.data[r->request_line.len] = '\0';
317 303
318 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_INVALID_REQUEST); 304 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_INVALID_REQUEST,
319 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); 305 NGX_HTTP_BAD_REQUEST);
320 return; 306 return;
321 } 307 }
322 308
323 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); 309 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
324 310
326 && cscf->large_client_header == 0 312 && cscf->large_client_header == 0
327 && r->header_in->pos == r->header_in->end) 313 && r->header_in->pos == r->header_in->end)
328 { 314 {
329 /* no space for "\r\n" at the end of the header */ 315 /* no space for "\r\n" at the end of the header */
330 316
331 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI); 317 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI,
332 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE); 318 NGX_HTTP_REQUEST_URI_TOO_LARGE);
333 return; 319 return;
334 } 320 }
335 321
336 /* copy URI */ 322 /* copy URI */
337 323
457 443
458 } else if (rc != NGX_AGAIN) { 444 } else if (rc != NGX_AGAIN) {
459 445
460 /* there was error while a request line parsing */ 446 /* there was error while a request line parsing */
461 447
462 ngx_http_header_parse_error(r, rc); 448 ngx_http_header_parse_error(r, rc, NGX_HTTP_BAD_REQUEST);
463 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
464 449
465 return; 450 return;
466 } 451 }
467 452
468 /* NGX_AGAIN: a request line parsing is still not complete */ 453 /* NGX_AGAIN: a request line parsing is still not complete */
469 454
470 if (r->header_in->last == r->header_in->end) { 455 if (r->header_in->last == r->header_in->end) {
471 456
472 /* If it's a pipelined request and a request line is not complete 457 /*
473 then we need to copy it to the start of the r->header_in hunk. 458 * If it's a pipelined request and a request line is not complete
474 We need to copy it here only if the large client headers 459 * then we need to copy it to the start of the r->header_in hunk.
475 are enabled otherwise a request line had been already copied 460 * We need to copy it here only if the large client headers
476 to the start of the r->header_in hunk in ngx_http_set_keepalive() */ 461 * are enabled otherwise a request line had been already copied
462 * to the start of the r->header_in hunk in ngx_http_set_keepalive().
463 */
477 464
478 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); 465 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
479 466
480 if (cscf->large_client_header) { 467 if (cscf->large_client_header) {
481 offset = r->request_start - r->header_in->start; 468 offset = r->request_start - r->header_in->start;
482 469
483 if (offset == 0) { 470 if (offset == 0) {
484 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI); 471 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI,
485 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE); 472 NGX_HTTP_REQUEST_URI_TOO_LARGE);
486
487 return; 473 return;
488 } 474 }
489 475
490 ngx_memcpy(r->header_in->start, r->request_start, 476 ngx_memcpy(r->header_in->start, r->request_start,
491 r->header_in->last - r->request_start); 477 r->header_in->last - r->request_start);
502 if (r->args_start) { 488 if (r->args_start) {
503 r->args_start -= offset; 489 r->args_start -= offset;
504 } 490 }
505 491
506 } else { 492 } else {
507 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI); 493 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI,
508 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE); 494 NGX_HTTP_REQUEST_URI_TOO_LARGE);
509 } 495 }
510 } 496 }
511 497
512 return; 498 return;
513 } 499 }
649 } 635 }
650 636
651 } else { 637 } else {
652 if (r->http_version > NGX_HTTP_VERSION_10) { 638 if (r->http_version > NGX_HTTP_VERSION_10) {
653 ngx_http_header_parse_error(r, 639 ngx_http_header_parse_error(r,
654 NGX_HTTP_PARSE_NO_HOST_HEADER); 640 NGX_HTTP_PARSE_NO_HOST_HEADER,
655 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); 641 NGX_HTTP_BAD_REQUEST);
656 return; 642 return;
657 } 643 }
658 r->headers_in.host_name_len = 0; 644 r->headers_in.host_name_len = 0;
659 } 645 }
660 646
661 if (r->headers_in.content_length) { 647 if (r->headers_in.content_length) {
662 r->headers_in.content_length_n = 648 r->headers_in.content_length_n =
663 ngx_atoi(r->headers_in.content_length->value.data, 649 ngx_atoi(r->headers_in.content_length->value.data,
664 r->headers_in.content_length->value.len); 650 r->headers_in.content_length->value.len);
651
665 if (r->headers_in.content_length_n == NGX_ERROR) { 652 if (r->headers_in.content_length_n == NGX_ERROR) {
666 ngx_http_header_parse_error(r, 653 ngx_http_header_parse_error(r,
667 NGX_HTTP_PARSE_INVALID_CL_HEADER); 654 NGX_HTTP_PARSE_INVALID_CL_HEADER,
668 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); 655 NGX_HTTP_BAD_REQUEST);
669 return; 656 return;
670 } 657 }
671 } 658 }
672 659
660 if (r->header_timeout_set) {
661 ngx_del_timer(rev);
662 }
663
673 rev->event_handler = ngx_http_block_read; 664 rev->event_handler = ngx_http_block_read;
674 c->write->event_handler = ngx_http_writer;
675 ngx_http_handler(r); 665 ngx_http_handler(r);
676 return; 666 return;
677 667
678 } else if (rc != NGX_AGAIN) { 668 } else if (rc != NGX_AGAIN) {
679 669
680 /* there was error while a header line parsing */ 670 /* there was error while a header line parsing */
681 671
682 ngx_http_header_parse_error(r, rc); 672 ngx_http_header_parse_error(r, rc, NGX_HTTP_BAD_REQUEST);
683 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
684
685 return; 673 return;
686 } 674 }
687 675
688 /* NGX_AGAIN: a header line parsing is still not complete */ 676 /* NGX_AGAIN: a header line parsing is still not complete */
689 677
695 if (cscf->large_client_header) { 683 if (cscf->large_client_header) {
696 offset = r->header_name_start - r->header_in->start; 684 offset = r->header_name_start - r->header_in->start;
697 685
698 if (offset == 0) { 686 if (offset == 0) {
699 ngx_http_header_parse_error(r, 687 ngx_http_header_parse_error(r,
700 NGX_HTTP_PARSE_TOO_LONG_HEADER); 688 NGX_HTTP_PARSE_TOO_LONG_HEADER,
701 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); 689 NGX_HTTP_BAD_REQUEST);
702 return; 690 return;
703 } 691 }
704 692
705 ngx_memcpy(r->header_in->start, r->header_name_start, 693 ngx_memcpy(r->header_in->start, r->header_name_start,
706 r->header_in->last - r->header_name_start); 694 r->header_in->last - r->header_name_start);
711 r->header_name_end -= offset; 699 r->header_name_end -= offset;
712 r->header_start -= offset; 700 r->header_start -= offset;
713 r->header_end -= offset; 701 r->header_end -= offset;
714 702
715 } else { 703 } else {
716 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER); 704 ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER,
717 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); 705 NGX_HTTP_BAD_REQUEST);
718 return; 706 return;
719 } 707 }
720 } 708 }
721 } 709 }
722 } 710 }
723 711
724 712
725 static ssize_t ngx_http_read_request_header(ngx_http_request_t *r) 713 static ssize_t ngx_http_read_request_header(ngx_http_request_t *r)
726 { 714 {
727 int event;
728 ssize_t n; 715 ssize_t n;
729 ngx_event_t *rev; 716 ngx_event_t *rev;
730 ngx_http_core_srv_conf_t *cscf; 717 ngx_http_core_srv_conf_t *cscf;
731 718
732 rev = r->connection->read; 719 rev = r->connection->read;
741 n = ngx_recv(r->connection, r->header_in->last, 728 n = ngx_recv(r->connection, r->header_in->last,
742 r->header_in->end - r->header_in->last); 729 r->header_in->end - r->header_in->last);
743 730
744 if (n == NGX_AGAIN) { 731 if (n == NGX_AGAIN) {
745 if (!r->header_timeout_set) { 732 if (!r->header_timeout_set) {
746 if (rev->timer_set) {
747 ngx_del_timer(rev);
748 } else {
749 rev->timer_set = 1;
750 }
751
752 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); 733 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
753
754 ngx_add_timer(rev, cscf->client_header_timeout); 734 ngx_add_timer(rev, cscf->client_header_timeout);
755 r->header_timeout_set = 1; 735 r->header_timeout_set = 1;
756 } 736 }
757 737
758 if (ngx_handle_read_event(rev) == NGX_ERROR) { 738 if (ngx_handle_read_event(rev) == NGX_ERROR) {
759 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 739 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
760 ngx_http_close_connection(r->connection); 740 ngx_http_close_connection(r->connection);
761 return NGX_ERROR; 741 return NGX_ERROR;
762 } 742 }
763 743
764 #if 0
765 if (!rev->active) {
766 if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) {
767 /* kqueue */
768 event = NGX_CLEAR_EVENT;
769
770 } else {
771 /* select, poll, /dev/poll */
772 event = NGX_LEVEL_EVENT;
773 }
774
775 if (ngx_add_event(rev, NGX_READ_EVENT, event) == NGX_ERROR) {
776 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
777 ngx_http_close_connection(r->connection);
778 return NGX_ERROR;
779 }
780 }
781 #endif
782
783 return NGX_AGAIN; 744 return NGX_AGAIN;
784 } 745 }
785 746
786 if (n == 0) { 747 if (n == 0) {
787 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, 748 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
800 } 761 }
801 762
802 763
803 void ngx_http_finalize_request(ngx_http_request_t *r, int rc) 764 void ngx_http_finalize_request(ngx_http_request_t *r, int rc)
804 { 765 {
805 ngx_event_t *rev, *wev; 766 ngx_log_debug(r->connection->log, "finalize http request");
806 767
807 if (r->main || r->closed) { 768 if (r->main || r->closed) {
808 return; 769 return;
809 } 770 }
810 771
811 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { 772 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
812 773
813 rev = r->connection->read; 774 if (r->connection->read->timer_set) {
814 if (rev->timer_set) { 775 ngx_del_timer(r->connection->read);
815 ngx_del_timer(rev); 776 }
816 rev->timer_set = 0; 777
817 } 778 if (r->connection->write->timer_set) {
818 779 ngx_del_timer(r->connection->write);
819 wev = r->connection->write;
820 if (wev->timer_set) {
821 ngx_del_timer(wev);
822 wev->timer_set = 0;
823 } 780 }
824 781
825 ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc)); 782 ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc));
826 783
827 return; 784 return;
834 } else if (rc == NGX_AGAIN) { 791 } else if (rc == NGX_AGAIN) {
835 ngx_http_set_write_handler(r); 792 ngx_http_set_write_handler(r);
836 return; 793 return;
837 } 794 }
838 795
839 rev = r->connection->read; 796 if (r->connection->read->timer_set) {
840 if (rev->timer_set) { 797 ngx_del_timer(r->connection->read);
841 ngx_del_timer(rev); 798 }
842 rev->timer_set = 0; 799
843 } 800 if (r->connection->write->timer_set) {
844 801 ngx_del_timer(r->connection->write);
845 wev = r->connection->write;
846 if (wev->timer_set) {
847 ngx_del_timer(wev);
848 wev->timer_set = 0;
849 } 802 }
850 803
851 if (r->keepalive != 0) { 804 if (r->keepalive != 0) {
852 ngx_http_set_keepalive(r); 805 ngx_http_set_keepalive(r);
853 806
863 } 816 }
864 817
865 818
866 static void ngx_http_set_write_handler(ngx_http_request_t *r) 819 static void ngx_http_set_write_handler(ngx_http_request_t *r)
867 { 820 {
868 int event;
869 ngx_event_t *wev; 821 ngx_event_t *wev;
870 ngx_http_core_loc_conf_t *clcf; 822 ngx_http_core_loc_conf_t *clcf;
871 823
872 wev = r->connection->write; 824 wev = r->connection->write;
873 wev->event_handler = ngx_http_writer; 825 wev->event_handler = ngx_http_writer;
877 } 829 }
878 830
879 clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r, 831 clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
880 ngx_http_core_module); 832 ngx_http_core_module);
881 ngx_add_timer(wev, clcf->send_timeout); 833 ngx_add_timer(wev, clcf->send_timeout);
882 wev->timer_set = 1;
883 834
884 if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) { 835 if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) {
885 ngx_http_close_request(r, 0); 836 ngx_http_close_request(r, 0);
886 ngx_http_close_connection(r->connection); 837 ngx_http_close_connection(r->connection);
887 } 838 }
888 839
889 #if 0
890
891 if (ngx_event_flags & (NGX_HAVE_AIO_EVENT|NGX_HAVE_EDGE_EVENT)) {
892 /* aio, iocp, epoll */
893 return;
894 }
895
896 #if (HAVE_LOWAT_EVENT) /* kqueue's NOTE_LOWAT */
897
898 if (ngx_event_flags & NGX_HAVE_LOWAT_EVENT) {
899 wev->lowat = clcf->send_lowat;
900 }
901
902 #endif
903
904 if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) {
905 /* kqueue */
906 event = NGX_CLEAR_EVENT;
907
908 } else {
909 /* select, poll, /dev/poll */
910 event = NGX_LEVEL_EVENT;
911 }
912
913 if (ngx_add_event(wev, NGX_WRITE_EVENT, event) == NGX_ERROR) {
914 ngx_http_close_request(r, 0);
915 ngx_http_close_connection(r->connection);
916 }
917
918 #endif
919
920 return; 840 return;
921 } 841 }
922 842
923 843
924 void ngx_http_writer(ngx_event_t *wev) 844 void ngx_http_writer(ngx_event_t *wev)
925 { 845 {
926 int rc; 846 int rc;
927 ngx_event_t *rev;
928 ngx_connection_t *c; 847 ngx_connection_t *c;
929 ngx_http_request_t *r; 848 ngx_http_request_t *r;
930 ngx_http_core_loc_conf_t *clcf; 849 ngx_http_core_loc_conf_t *clcf;
931 850
932 c = wev->data; 851 c = wev->data;
935 rc = ngx_http_output_filter(r, NULL); 854 rc = ngx_http_output_filter(r, NULL);
936 855
937 ngx_log_debug(c->log, "writer output filter: %d" _ rc); 856 ngx_log_debug(c->log, "writer output filter: %d" _ rc);
938 857
939 if (rc == NGX_AGAIN) { 858 if (rc == NGX_AGAIN) {
940 859 if (!wev->ready) {
941 clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r, 860 clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
942 ngx_http_core_module); 861 ngx_http_core_module);
943 if (wev->timer_set) { 862 ngx_add_timer(wev, clcf->send_timeout);
944 ngx_del_timer(wev); 863 }
945 } else { 864
946 wev->timer_set = 1; 865 if (ngx_handle_level_write_event(wev) == NGX_ERROR) {
947 } 866 ngx_http_close_request(r, 0);
948 867 ngx_http_close_connection(r->connection);
949 ngx_add_timer(wev, clcf->send_timeout); 868 }
950 869
951 return; 870 return;
952 } 871 }
953
954 if (rc == NGX_ERROR) {
955 ngx_http_close_request(r, 0);
956 ngx_http_close_connection(c);
957 return;
958 }
959
960 /* rc == NGX_OK */
961 872
962 ngx_log_debug(c->log, "http writer done"); 873 ngx_log_debug(c->log, "http writer done");
963 874
875 ngx_http_finalize_request(r, rc);
876 }
877
878
879 static void ngx_http_block_read(ngx_event_t *rev)
880 {
881 ngx_connection_t *c;
882 ngx_http_request_t *r;
883
884 ngx_log_debug(rev->log, "http read blocked");
885
886 /* aio does not call this handler */
887
888 if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && rev->active) {
889 if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
890 c = rev->data;
891 r = c->data;
892 ngx_http_close_request(r, 0);
893 ngx_http_close_connection(c);
894 }
895 }
896
897 return;
898 }
899
900
901 int ngx_http_discard_body(ngx_http_request_t *r)
902 {
903 ssize_t size;
904 ngx_event_t *rev;
905
964 rev = r->connection->read; 906 rev = r->connection->read;
907
908 ngx_log_debug(rev->log, "set discard body");
909
965 if (rev->timer_set) { 910 if (rev->timer_set) {
966 ngx_del_timer(rev); 911 ngx_del_timer(rev);
967 rev->timer_set = 0; 912 }
968 } 913
969 914 if (r->headers_in.content_length_n <= 0) {
970 if (wev->timer_set) { 915 return NGX_OK;
971 ngx_del_timer(wev); 916 }
972 wev->timer_set = 0; 917
973 } 918 size = r->header_in->last - r->header_in->pos;
974 919
975 if (r->keepalive != 0) { 920 if (size) {
976 ngx_http_set_keepalive(r); 921 if (r->headers_in.content_length_n > size) {
977 922 r->headers_in.content_length_n -= size;
978 } else if (r->lingering_close) { 923
979 ngx_http_set_lingering_close(r); 924 } else {
980 925 r->header_in->pos += r->headers_in.content_length_n;
981 } else { 926 r->headers_in.content_length_n = 0;
982 ngx_http_close_request(r, 0); 927 return NGX_OK;
983 ngx_http_close_connection(r->connection); 928 }
984 } 929 }
985 930
986 return; 931 rev->event_handler = ngx_http_read_discarded_body_event;
987 } 932
988 933 if (ngx_handle_level_read_event(rev) == NGX_ERROR) {
989 934 return NGX_HTTP_INTERNAL_SERVER_ERROR;
990 static void ngx_http_block_read(ngx_event_t *rev) 935 }
991 { 936
992 ngx_connection_t *c; 937 return ngx_http_read_discarded_body(r);
993 ngx_http_request_t *r;
994
995 ngx_log_debug(rev->log, "http read blocked");
996
997 /* aio does not call this handler */
998
999 if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
1000
1001 /* select, poll, /dev/poll */
1002
1003 rev->blocked = 1;
1004
1005 if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
1006 c = (ngx_connection_t *) rev->data;
1007 r = (ngx_http_request_t *) c->data;
1008 ngx_http_close_request(r, 0);
1009 ngx_http_close_connection(c);
1010 }
1011 }
1012
1013 /* kqueue, epoll */
1014
1015 return;
1016 }
1017
1018
1019 int ngx_http_discard_body(ngx_http_request_t *r)
1020 {
1021 ssize_t size;
1022 ngx_event_t *rev;
1023
1024 rev = r->connection->read;
1025
1026 ngx_log_debug(rev->log, "set discard body");
1027
1028 if (rev->timer_set) {
1029 ngx_del_timer(rev);
1030 rev->timer_set = 0;
1031 }
1032
1033 if (r->headers_in.content_length_n > 0) {
1034
1035 size = r->header_in->last - r->header_in->pos;
1036
1037 if (size) {
1038 if (r->headers_in.content_length_n > size) {
1039 r->headers_in.content_length_n -= size;
1040
1041 } else {
1042 r->header_in->pos += r->headers_in.content_length_n;
1043 r->headers_in.content_length_n = 0;
1044 return NGX_OK;
1045 }
1046 }
1047
1048 rev->event_handler = ngx_http_read_discarded_body_event;
1049
1050 if (rev->blocked) {
1051 if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
1052 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT)
1053 == NGX_ERROR) {
1054 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1055 }
1056 }
1057
1058 rev->blocked = 0;
1059 return ngx_http_read_discarded_body(r);
1060 }
1061 }
1062 938
1063 return NGX_OK; 939 return NGX_OK;
1064 } 940 }
1065 941
1066 942
1073 c = rev->data; 949 c = rev->data;
1074 r = c->data; 950 r = c->data;
1075 951
1076 rc = ngx_http_read_discarded_body(r); 952 rc = ngx_http_read_discarded_body(r);
1077 953
954 if (rc == NGX_AGAIN) {
955 if (ngx_handle_level_read_event(rev) == NGX_ERROR) {
956 ngx_http_close_request(r, rc);
957 ngx_http_close_connection(c);
958 return;
959 }
960 }
961
1078 if (rc != NGX_OK) { 962 if (rc != NGX_OK) {
1079 ngx_http_close_request(r, rc); 963 ngx_http_close_request(r, rc);
1080 ngx_http_close_connection(c); 964 ngx_http_close_connection(c);
1081 } 965 }
1082
1083 return;
1084 } 966 }
1085 967
1086 968
1087 static int ngx_http_read_discarded_body(ngx_http_request_t *r) 969 static int ngx_http_read_discarded_body(ngx_http_request_t *r)
1088 { 970 {
1089 ssize_t size, n; 971 ssize_t size, n;
1090 ngx_http_core_loc_conf_t *clcf; 972 ngx_http_core_loc_conf_t *clcf;
1091 973
1092 ngx_log_debug(r->connection->log, "http read discarded body"); 974 ngx_log_debug(r->connection->log, "http read discarded body");
975
976 if (r->headers_in.content_length_n == 0) {
977 return NGX_OK;
978 }
1093 979
1094 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 980 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1095 981
1096 if (r->discarded_buffer == NULL) { 982 if (r->discarded_buffer == NULL) {
1097 r->discarded_buffer = ngx_palloc(r->pool, clcf->discarded_buffer_size); 983 r->discarded_buffer = ngx_palloc(r->pool, clcf->discarded_buffer_size);
1099 return NGX_HTTP_INTERNAL_SERVER_ERROR; 985 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1100 } 986 }
1101 } 987 }
1102 988
1103 size = r->headers_in.content_length_n; 989 size = r->headers_in.content_length_n;
990
1104 if (size > clcf->discarded_buffer_size) { 991 if (size > clcf->discarded_buffer_size) {
1105 size = clcf->discarded_buffer_size; 992 size = clcf->discarded_buffer_size;
1106 } 993 }
1107 994
1108 n = ngx_recv(r->connection, r->discarded_buffer, size); 995 n = ngx_recv(r->connection, r->discarded_buffer, size);
1109 if (n == NGX_ERROR) { 996 if (n == NGX_ERROR) {
1110 return NGX_HTTP_BAD_REQUEST; 997 return NGX_HTTP_BAD_REQUEST;
1111 } 998 }
1112 999
1113 if (n == NGX_AGAIN) { 1000 if (n == NGX_AGAIN) {
1114 return NGX_OK; 1001 return NGX_AGAIN;
1115 } 1002 }
1116 1003
1117 r->headers_in.content_length_n -= n; 1004 r->headers_in.content_length_n -= n;
1118 1005
1119 return NGX_OK; 1006 return NGX_OK;
1120 } 1007 }
1121 1008
1122 1009
1123 static void ngx_http_set_keepalive(ngx_http_request_t *r) 1010 static void ngx_http_set_keepalive(ngx_http_request_t *r)
1124 { 1011 {
1125 int len, blocked; 1012 int len;
1126 ngx_hunk_t *h; 1013 ngx_hunk_t *h;
1127 ngx_event_t *rev, *wev; 1014 ngx_event_t *rev, *wev;
1128 ngx_connection_t *c; 1015 ngx_connection_t *c;
1129 ngx_http_log_ctx_t *ctx; 1016 ngx_http_log_ctx_t *ctx;
1130 ngx_http_core_srv_conf_t *cscf; 1017 ngx_http_core_srv_conf_t *cscf;
1137 1024
1138 ctx = (ngx_http_log_ctx_t *) c->log->data; 1025 ctx = (ngx_http_log_ctx_t *) c->log->data;
1139 ctx->action = "closing request"; 1026 ctx->action = "closing request";
1140 ngx_http_close_request(r, 0); 1027 ngx_http_close_request(r, 0);
1141 1028
1142 if (rev->timer_set) {
1143 ngx_del_timer(rev);
1144 } else {
1145 rev->timer_set = 1;
1146 }
1147
1148 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 1029 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1149
1150 ngx_add_timer(rev, clcf->keepalive_timeout); 1030 ngx_add_timer(rev, clcf->keepalive_timeout);
1151 1031
1152 if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) { 1032 if (ngx_handle_level_read_event(rev) == NGX_ERROR) {
1153 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) { 1033 ngx_http_close_connection(c);
1154 ngx_http_close_connection(c); 1034 return;
1155 return;
1156 }
1157
1158 blocked = 1;
1159 rev->blocked = 0;
1160
1161 } else {
1162 blocked = 0;
1163 } 1035 }
1164 1036
1165 h = c->buffer; 1037 h = c->buffer;
1166 1038
1167 /* pipelined request */
1168 if (h->pos < h->last) { 1039 if (h->pos < h->last) {
1169 1040
1170 /* We do not know here whether a pipelined request is complete 1041 /* Pipelined request.
1171 so if the large client headers are not enabled 1042 *
1172 we need to copy the data to the start of c->buffer. 1043 * We do not know here whether a pipelined request is complete
1173 This copy should be rare because clients that support 1044 * so if the large client headers are not enabled
1174 pipelined requests (Mozilla 1.x, Opera 6.x) are still rare */ 1045 * we need to copy the data to the start of c->buffer.
1046 * This copy should be rare because clients that support
1047 * pipelined requests (Mozilla 1.x, Opera 6.x+) are still rare.
1048 */
1175 1049
1176 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); 1050 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
1177 1051
1178 if (!cscf->large_client_header) { 1052 if (!cscf->large_client_header) {
1179 len = h->last - h->pos; 1053 len = h->last - h->pos;
1193 c->pipeline = 0; 1067 c->pipeline = 0;
1194 1068
1195 h->pos = h->last = h->start; 1069 h->pos = h->last = h->start;
1196 rev->event_handler = ngx_http_keepalive_handler; 1070 rev->event_handler = ngx_http_keepalive_handler;
1197 wev = c->write; 1071 wev = c->write;
1198 1072 wev->event_handler = ngx_http_empty_handler;
1199 if (wev->active) { 1073
1200 if (ngx_event_flags & NGX_USE_LEVEL_EVENT) { 1074 if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && wev->active) {
1201 if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) { 1075 if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
1202 ngx_http_close_connection(c); 1076 ngx_http_close_connection(c);
1203 return; 1077 return;
1204 }
1205
1206 } else if ((ngx_event_flags & NGX_HAVE_AIO_EVENT) == 0) {
1207 wev->event_handler = ngx_http_empty_handler;
1208 } 1078 }
1209 } 1079 }
1210 1080
1211 ctx->action = "keepalive"; 1081 ctx->action = "keepalive";
1212 1082
1218 return; 1088 return;
1219 } 1089 }
1220 c->tcp_nopush = 0; 1090 c->tcp_nopush = 0;
1221 } 1091 }
1222 1092
1223 if ((ngx_event_flags & NGX_HAVE_AIO_EVENT) || blocked) { 1093 if (rev->ready || (ngx_event_flags & NGX_USE_AIO_EVENT)) {
1224 ngx_http_keepalive_handler(rev); 1094 ngx_http_keepalive_handler(rev);
1225 } 1095 }
1226 } 1096 }
1227 1097
1228 1098
1229 static void ngx_http_keepalive_handler(ngx_event_t *rev) 1099 static void ngx_http_keepalive_handler(ngx_event_t *rev)
1230 { 1100 {
1231 ssize_t n; 1101 ssize_t n;
1232 ngx_connection_t *c; 1102 ngx_connection_t *c;
1233 ngx_http_log_ctx_t *lctx; 1103 ngx_http_log_ctx_t *lctx;
1234 1104
1235 c = (ngx_connection_t *) rev->data; 1105 c = (ngx_connection_t *) rev->data;
1236 1106
1239 if (rev->timedout) { 1109 if (rev->timedout) {
1240 ngx_http_close_connection(c); 1110 ngx_http_close_connection(c);
1241 return; 1111 return;
1242 } 1112 }
1243 1113
1244 /* MSIE closes a keepalive connection with RST flag 1114 /*
1245 so we ignore ECONNRESET here */ 1115 * MSIE closes a keepalive connection with RST flag
1116 * so we ignore ECONNRESET here.
1117 */
1246 1118
1247 rev->ignore_econnreset = 1; 1119 rev->ignore_econnreset = 1;
1248 ngx_set_socket_errno(0); 1120 ngx_set_socket_errno(0);
1249 n = ngx_recv(c, c->buffer->last, c->buffer->end - c->buffer->last); 1121 n = ngx_recv(c, c->buffer->last, c->buffer->end - c->buffer->last);
1250 rev->ignore_econnreset = 0; 1122 rev->ignore_econnreset = 0;
1276 } 1148 }
1277 1149
1278 1150
1279 static void ngx_http_set_lingering_close(ngx_http_request_t *r) 1151 static void ngx_http_set_lingering_close(ngx_http_request_t *r)
1280 { 1152 {
1281 ngx_event_t *rev; 1153 ngx_event_t *rev, *wev;
1282 ngx_connection_t *c; 1154 ngx_connection_t *c;
1283 ngx_http_core_loc_conf_t *clcf; 1155 ngx_http_core_loc_conf_t *clcf;
1284 1156
1285 c = r->connection; 1157 c = r->connection;
1158
1159 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1160
1286 rev = c->read; 1161 rev = c->read;
1287 1162 rev->event_handler = ngx_http_lingering_close_handler;
1288 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1289 1163
1290 r->lingering_time = ngx_time() + clcf->lingering_time / 1000; 1164 r->lingering_time = ngx_time() + clcf->lingering_time / 1000;
1291 rev->event_handler = ngx_http_lingering_close_handler;
1292
1293 if (rev->timer_set) {
1294 ngx_del_timer(rev);
1295 } else {
1296 rev->timer_set = 1;
1297 }
1298
1299 ngx_add_timer(rev, clcf->lingering_timeout); 1165 ngx_add_timer(rev, clcf->lingering_timeout);
1300 1166
1301 if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) { 1167 if (ngx_handle_level_read_event(rev) == NGX_ERROR) {
1302 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) { 1168 ngx_http_close_request(r, 0);
1169 ngx_http_close_connection(c);
1170 return;
1171 }
1172
1173 wev = c->write;
1174 wev->event_handler = ngx_http_empty_handler;
1175
1176 if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && wev->active) {
1177 if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
1303 ngx_http_close_request(r, 0); 1178 ngx_http_close_request(r, 0);
1304 ngx_http_close_connection(c); 1179 ngx_http_close_connection(c);
1305 return; 1180 return;
1306 }
1307 rev->blocked = 0;
1308 }
1309
1310 if (c->write->active) {
1311 if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
1312 if (ngx_del_event(c->write, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
1313 ngx_http_close_request(r, 0);
1314 ngx_http_close_connection(c);
1315 return;
1316 }
1317
1318 } else if ((ngx_event_flags & NGX_HAVE_AIO_EVENT) == 0) {
1319 c->write->event_handler = ngx_http_empty_handler;
1320 } 1181 }
1321 } 1182 }
1322 1183
1323 if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) { 1184 if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
1324 ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno, 1185 ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
1326 ngx_http_close_request(r, 0); 1187 ngx_http_close_request(r, 0);
1327 ngx_http_close_connection(c); 1188 ngx_http_close_connection(c);
1328 return; 1189 return;
1329 } 1190 }
1330 1191
1331 if (rev->ready || (ngx_event_flags & NGX_HAVE_AIO_EVENT)) { 1192 if (rev->ready || (ngx_event_flags & NGX_USE_AIO_EVENT)) {
1332 ngx_http_lingering_close_handler(rev); 1193 ngx_http_lingering_close_handler(rev);
1333 } 1194 }
1334 } 1195 }
1335 1196
1336 1197
1399 timer *= 1000; 1260 timer *= 1000;
1400 if (timer > clcf->lingering_timeout) { 1261 if (timer > clcf->lingering_timeout) {
1401 timer = clcf->lingering_timeout; 1262 timer = clcf->lingering_timeout;
1402 } 1263 }
1403 1264
1404 if (rev->timer_set) {
1405 ngx_del_timer(rev);
1406 } else {
1407 rev->timer_set = 1;
1408 }
1409 ngx_add_timer(rev, timer); 1265 ngx_add_timer(rev, timer);
1410 1266
1411 return; 1267 return;
1412 } 1268 }
1413 1269
1414 1270
1415 static void ngx_http_empty_handler(ngx_event_t *wev) 1271 static void ngx_http_empty_handler(ngx_event_t *wev)
1416 { 1272 {
1417 ngx_log_debug(wev->log, "http empty handler"); 1273 ngx_log_debug(wev->log, "http EMPTY handler");
1418 1274
1419 return; 1275 return;
1420 } 1276 }
1421 1277
1422 1278
1455 ngx_close_file_n " \"%s\" failed", r->file.name.data); 1311 ngx_close_file_n " \"%s\" failed", r->file.name.data);
1456 } 1312 }
1457 } 1313 }
1458 1314
1459 /* ctx->url was allocated from r->pool */ 1315 /* ctx->url was allocated from r->pool */
1460 ctx = (ngx_http_log_ctx_t *) r->connection->log->data; 1316 ctx = r->connection->log->data;
1461 ctx->url = NULL; 1317 ctx->url = NULL;
1462 1318
1463 ngx_destroy_pool(r->pool); 1319 ngx_destroy_pool(r->pool);
1464 1320
1465 r->closed = 1; 1321 r->closed = 1;
1477 return; 1333 return;
1478 } 1334 }
1479 1335
1480 if (c->read->timer_set) { 1336 if (c->read->timer_set) {
1481 ngx_del_timer(c->read); 1337 ngx_del_timer(c->read);
1482 c->read->timer_set = 0;
1483 } 1338 }
1484 1339
1485 if (c->write->timer_set) { 1340 if (c->write->timer_set) {
1486 ngx_del_timer(c->write); 1341 ngx_del_timer(c->write);
1487 c->write->timer_set = 0;
1488 } 1342 }
1489 1343
1490 if (ngx_del_conn) { 1344 if (ngx_del_conn) {
1491 ngx_del_conn(c); 1345 ngx_del_conn(c);
1492 1346
1511 1365
1512 return; 1366 return;
1513 } 1367 }
1514 1368
1515 1369
1516 static void ngx_http_header_parse_error(ngx_http_request_t *r, int parse_err) 1370 static void ngx_http_header_parse_error(ngx_http_request_t *r,
1371 int parse_err, int error)
1517 { 1372 {
1518 ngx_http_log_ctx_t *ctx; 1373 ngx_http_log_ctx_t *ctx;
1519 1374
1520 ctx = r->connection->log->data; 1375 ctx = r->connection->log->data;
1521 r->connection->log->handler = NULL; 1376 r->connection->log->handler = NULL;
1530 header_errors[parse_err - NGX_HTTP_PARSE_INVALID_METHOD], 1385 header_errors[parse_err - NGX_HTTP_PARSE_INVALID_METHOD],
1531 ctx->client); 1386 ctx->client);
1532 } 1387 }
1533 1388
1534 r->connection->log->handler = ngx_http_log_error; 1389 r->connection->log->handler = ngx_http_log_error;
1390
1391 ngx_http_finalize_request(r, error);
1535 } 1392 }
1536 1393
1537 1394
1538 static size_t ngx_http_log_error(void *data, char *buf, size_t len) 1395 static size_t ngx_http_log_error(void *data, char *buf, size_t len)
1539 { 1396 {