Mercurial > hg > nginx
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 { |