Mercurial > hg > nginx-vendor-0-5
comparison src/http/ngx_http_request.c @ 54:bcb5fce0b038 NGINX_0_1_27
nginx 0.1.27
*) Feature: the "blocked" parameter of the "valid_referers" directive.
*) Change: the errors while handling the request header now logged at
"info" level. The server name and the "Host" and "Referer" header
lines also logged.
*) Change: the "Host" header line is also logged in error log.
*) Feature: the proxy_pass_unparsed_uri directive. The special handling
of the "://" symbols in URI, appeared in 0.1.11 version, now is
canceled.
*) Bugfix: nginx could not be built on FreeBSD and Linux, if the
--without-ngx_http_auth_basic_module configuration parameter was
used.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 28 Mar 2005 00:00:00 +0400 |
parents | 0d75d65c642f |
children | 3050baa54a26 |
comparison
equal
deleted
inserted
replaced
53:b6565ddf033b | 54:bcb5fce0b038 |
---|---|
31 static void ngx_http_set_keepalive(ngx_http_request_t *r); | 31 static void ngx_http_set_keepalive(ngx_http_request_t *r); |
32 static void ngx_http_keepalive_handler(ngx_event_t *ev); | 32 static void ngx_http_keepalive_handler(ngx_event_t *ev); |
33 static void ngx_http_set_lingering_close(ngx_http_request_t *r); | 33 static void ngx_http_set_lingering_close(ngx_http_request_t *r); |
34 static void ngx_http_lingering_close_handler(ngx_event_t *ev); | 34 static void ngx_http_lingering_close_handler(ngx_event_t *ev); |
35 | 35 |
36 static void ngx_http_client_error(ngx_http_request_t *r, | |
37 int client_error, int error); | |
38 static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len); | 36 static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len); |
39 | 37 |
40 | 38 |
41 /* NGX_HTTP_PARSE_... errors */ | 39 static char *ngx_http_client_errors[] = { |
42 | 40 |
43 static char *client_header_errors[] = { | 41 /* NGX_HTTP_PARSE_INVALID_METHOD */ |
44 "client %V sent invalid method \"%V\"", | 42 "client sent invalid method", |
45 "client %V sent invalid request \"%V\"", | 43 |
46 "client %V sent too long URI in request \"%V\"", | 44 /* NGX_HTTP_PARSE_INVALID_REQUEST */ |
47 "client %V sent invalid method in HTTP/0.9 request \"%V\"", | 45 "client sent invalid request", |
48 | 46 |
49 "client %V sent invalid header, URL: \"%V\"", | 47 /* NGX_HTTP_PARSE_INVALID_09_METHOD */ |
50 "client %V sent too long header line, URL: \"%V\"", | 48 "client sent invalid method in HTTP/0.9 request" |
51 "client %V sent HTTP/1.1 request without \"Host\" header, URL: \"%V\"", | |
52 "client %V sent invalid \"Content-Length\" header, URL: \"%V\"", | |
53 "client %V sent POST method without \"Content-Length\" header, URL: \"%V\"", | |
54 }; | 49 }; |
55 | 50 |
56 | 51 |
57 ngx_http_header_t ngx_http_headers_in[] = { | 52 ngx_http_header_t ngx_http_headers_in[] = { |
58 { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host) }, | 53 { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host) }, |
197 struct sockaddr_in sin; | 192 struct sockaddr_in sin; |
198 ngx_connection_t *c; | 193 ngx_connection_t *c; |
199 ngx_http_request_t *r; | 194 ngx_http_request_t *r; |
200 ngx_http_in_port_t *in_port; | 195 ngx_http_in_port_t *in_port; |
201 ngx_http_in_addr_t *in_addr; | 196 ngx_http_in_addr_t *in_addr; |
197 ngx_http_log_ctx_t *ctx; | |
202 ngx_http_connection_t *hc; | 198 ngx_http_connection_t *hc; |
203 ngx_http_server_name_t *server_name; | 199 ngx_http_server_name_t *server_name; |
204 ngx_http_core_srv_conf_t *cscf; | 200 ngx_http_core_srv_conf_t *cscf; |
205 ngx_http_core_loc_conf_t *clcf; | 201 ngx_http_core_loc_conf_t *clcf; |
206 #if (NGX_HTTP_SSL) | 202 #if (NGX_HTTP_SSL) |
357 rev->event_handler = ngx_http_ssl_handshake; | 353 rev->event_handler = ngx_http_ssl_handshake; |
358 | 354 |
359 /* | 355 /* |
360 * The majority of browsers do not send the "close notify" alert. | 356 * The majority of browsers do not send the "close notify" alert. |
361 * Among them are MSIE, Mozilla, Netscape 4, Konqueror, and Links. | 357 * Among them are MSIE, Mozilla, Netscape 4, Konqueror, and Links. |
362 * And what is more MSIE ignores the server's alert. | 358 * And what is more, MSIE ignores the server's alert. |
363 * | 359 * |
364 * Opera always sends the alert. | 360 * Opera always sends the alert. |
365 */ | 361 */ |
366 | 362 |
367 c->ssl->no_rcv_shut = 1; | 363 c->ssl->no_rcv_shut = 1; |
437 r->headers_out.content_length_n = -1; | 433 r->headers_out.content_length_n = -1; |
438 r->headers_out.last_modified_time = -1; | 434 r->headers_out.last_modified_time = -1; |
439 | 435 |
440 r->http_state = NGX_HTTP_READING_REQUEST_STATE; | 436 r->http_state = NGX_HTTP_READING_REQUEST_STATE; |
441 | 437 |
438 ctx = c->log->data; | |
439 ctx->request = r; | |
440 | |
442 #if (NGX_STAT_STUB) | 441 #if (NGX_STAT_STUB) |
443 ngx_atomic_inc(ngx_stat_reading); | 442 ngx_atomic_inc(ngx_stat_reading); |
444 r->stat_reading = 1; | 443 r->stat_reading = 1; |
445 ngx_atomic_inc(ngx_stat_requests); | 444 ngx_atomic_inc(ngx_stat_requests); |
446 #endif | 445 #endif |
465 | 464 |
466 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, | 465 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, |
467 "http check ssl handshake"); | 466 "http check ssl handshake"); |
468 | 467 |
469 if (rev->timedout) { | 468 if (rev->timedout) { |
470 ngx_http_client_error(r, 0, NGX_HTTP_REQUEST_TIME_OUT); | 469 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); |
470 c->timedout = 1; | |
471 ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT); | |
472 ngx_http_close_connection(c); | |
471 return; | 473 return; |
472 } | 474 } |
473 | 475 |
474 n = recv(c->fd, buf, 1, MSG_PEEK); | 476 n = recv(c->fd, buf, 1, MSG_PEEK); |
475 | 477 |
526 | 528 |
527 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, | 529 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, |
528 "http process request line"); | 530 "http process request line"); |
529 | 531 |
530 if (rev->timedout) { | 532 if (rev->timedout) { |
531 ngx_http_client_error(r, 0, NGX_HTTP_REQUEST_TIME_OUT); | 533 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); |
534 c->timedout = 1; | |
535 ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT); | |
536 ngx_http_close_connection(c); | |
532 return; | 537 return; |
533 } | 538 } |
534 | 539 |
535 rc = NGX_AGAIN; | 540 rc = NGX_AGAIN; |
536 | 541 |
570 return; | 575 return; |
571 } | 576 } |
572 | 577 |
573 rc = ngx_http_parse_complex_uri(r); | 578 rc = ngx_http_parse_complex_uri(r); |
574 | 579 |
575 if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) { | 580 if (rc == NGX_HTTP_PARSE_INVALID_REQUEST) { |
576 ngx_http_close_request(r, rc); | 581 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
577 ngx_http_close_connection(c); | 582 "client sent invalid request"); |
578 return; | 583 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); |
579 } | |
580 | |
581 if (rc != NGX_OK) { | |
582 ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST); | |
583 return; | 584 return; |
584 } | 585 } |
585 | 586 |
586 } else { | 587 } else { |
587 r->uri.data = r->uri_start; | 588 r->uri.data = r->uri_start; |
630 "http args: \"%V\"", &r->args); | 631 "http args: \"%V\"", &r->args); |
631 | 632 |
632 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 633 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
633 "http exten: \"%V\"", &r->exten); | 634 "http exten: \"%V\"", &r->exten); |
634 | 635 |
635 ctx = c->log->data; | |
636 ctx->request = r; | |
637 | |
638 if (r->http_version < NGX_HTTP_VERSION_10) { | 636 if (r->http_version < NGX_HTTP_VERSION_10) { |
639 rev->event_handler = ngx_http_block_read; | 637 rev->event_handler = ngx_http_block_read; |
640 ngx_http_handler(r); | 638 ngx_http_handler(r); |
641 return; | 639 return; |
642 } | 640 } |
663 | 661 |
664 rev->event_handler = ngx_http_process_request_headers; | 662 rev->event_handler = ngx_http_process_request_headers; |
665 ngx_http_process_request_headers(rev); | 663 ngx_http_process_request_headers(rev); |
666 | 664 |
667 return; | 665 return; |
668 | 666 } |
669 } else if (rc != NGX_AGAIN) { | 667 |
668 if (rc != NGX_AGAIN) { | |
670 | 669 |
671 /* there was error while a request line parsing */ | 670 /* there was error while a request line parsing */ |
672 | 671 |
673 ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST); | 672 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
674 | 673 ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]); |
675 #if 0 | 674 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); |
676 for (p = r->request_start; p < r->header_in->last; p++) { | |
677 if (*p == CR || *p == LF) { | |
678 break; | |
679 } | |
680 } | |
681 | |
682 r->request_line.len = p - r->request_start; | |
683 r->request_line.data = r->request_start; | |
684 | |
685 if (rc == NGX_HTTP_PARSE_INVALID_METHOD) { | |
686 r->http_version = NGX_HTTP_VERSION_10; | |
687 } | |
688 | |
689 ngx_http_client_error(r, rc, | |
690 (rc == NGX_HTTP_PARSE_INVALID_METHOD) ? | |
691 NGX_HTTP_NOT_IMPLEMENTED: | |
692 NGX_HTTP_BAD_REQUEST); | |
693 #endif | |
694 | |
695 return; | 675 return; |
696 } | 676 } |
697 | 677 |
698 /* NGX_AGAIN: a request line parsing is still incomplete */ | 678 /* NGX_AGAIN: a request line parsing is still incomplete */ |
699 | 679 |
706 ngx_http_close_connection(c); | 686 ngx_http_close_connection(c); |
707 return; | 687 return; |
708 } | 688 } |
709 | 689 |
710 if (rv == NGX_DECLINED) { | 690 if (rv == NGX_DECLINED) { |
711 ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_URI, | 691 ctx = c->log->data; |
712 NGX_HTTP_REQUEST_URI_TOO_LARGE); | 692 ctx->request = r; |
693 | |
694 r->request_line.len = r->header_in->end - r->request_start; | |
695 r->request_line.data = r->request_start; | |
696 | |
697 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
698 "client sent too long URI"); | |
699 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE); | |
713 return; | 700 return; |
714 } | 701 } |
715 } | 702 } |
716 } | 703 } |
717 } | 704 } |
732 | 719 |
733 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, | 720 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, |
734 "http process request header line"); | 721 "http process request header line"); |
735 | 722 |
736 if (rev->timedout) { | 723 if (rev->timedout) { |
737 ngx_http_client_error(r, 0, NGX_HTTP_REQUEST_TIME_OUT); | 724 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); |
725 c->timedout = 1; | |
726 ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT); | |
727 ngx_http_close_connection(c); | |
738 return; | 728 return; |
739 } | 729 } |
740 | 730 |
741 rc = NGX_AGAIN; | 731 rc = NGX_AGAIN; |
742 | 732 |
753 ngx_http_close_connection(c); | 743 ngx_http_close_connection(c); |
754 return; | 744 return; |
755 } | 745 } |
756 | 746 |
757 if (rv == NGX_DECLINED) { | 747 if (rv == NGX_DECLINED) { |
758 ngx_http_client_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER, | 748 header.len = r->header_in->end - r->header_name_start; |
759 NGX_HTTP_BAD_REQUEST); | 749 header.data = r->header_name_start; |
750 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
751 "client sent too long header line: \"%V\"", | |
752 &header); | |
753 ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST); | |
754 ngx_http_close_connection(c); | |
760 return; | 755 return; |
761 } | 756 } |
762 } | 757 } |
763 | 758 |
764 n = ngx_http_read_request_header(r); | 759 n = ngx_http_read_request_header(r); |
777 /* there was error while a header line parsing */ | 772 /* there was error while a header line parsing */ |
778 | 773 |
779 header.len = r->header_end - r->header_name_start; | 774 header.len = r->header_end - r->header_name_start; |
780 header.data = r->header_name_start; | 775 header.data = r->header_name_start; |
781 | 776 |
782 ngx_log_error(NGX_LOG_INFO, rev->log, 0, | 777 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
783 "client sent invalid header: \"%V\", ignored,", | 778 "client sent invalid header line: \"%V\"", |
784 &header); | 779 &header); |
785 continue; | 780 continue; |
786 } | 781 } |
787 | 782 |
788 /* a header line has been parsed successfully */ | 783 /* a header line has been parsed successfully */ |
836 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 831 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
837 "http header: \"%V: %V\"", | 832 "http header: \"%V: %V\"", |
838 &h->key, &h->value); | 833 &h->key, &h->value); |
839 | 834 |
840 continue; | 835 continue; |
841 | 836 } |
842 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) { | 837 |
838 if (rc == NGX_HTTP_PARSE_HEADER_DONE) { | |
843 | 839 |
844 /* a whole header has been parsed successfully */ | 840 /* a whole header has been parsed successfully */ |
845 | 841 |
846 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 842 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
847 "http header done"); | 843 "http header done"); |
851 r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE; | 847 r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE; |
852 | 848 |
853 rc = ngx_http_process_request_header(r); | 849 rc = ngx_http_process_request_header(r); |
854 | 850 |
855 if (rc != NGX_OK) { | 851 if (rc != NGX_OK) { |
856 ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST); | |
857 return; | 852 return; |
858 } | 853 } |
859 | 854 |
860 if (rev->timer_set) { | 855 if (rev->timer_set) { |
861 ngx_del_timer(rev); | 856 ngx_del_timer(rev); |
869 #endif | 864 #endif |
870 | 865 |
871 rev->event_handler = ngx_http_block_read; | 866 rev->event_handler = ngx_http_block_read; |
872 ngx_http_handler(r); | 867 ngx_http_handler(r); |
873 return; | 868 return; |
874 | 869 } |
875 } else if (rc != NGX_AGAIN) { | 870 |
876 | 871 if (rc == NGX_AGAIN) { |
877 /* there was error while a header line parsing */ | 872 |
878 | 873 /* a header line parsing is still not complete */ |
879 #if (NGX_DEBUG) | 874 |
880 if (rc == NGX_HTTP_PARSE_INVALID_HEADER | 875 continue; |
881 && (rev->log->log_level & NGX_LOG_DEBUG_HTTP)) | 876 } |
882 { | 877 |
883 u_char *p; | 878 /* rc == NGX_HTTP_PARSE_INVALID_HEADER: "\r" is not followed by "\n" */ |
884 for (p = r->header_name_start; | 879 |
885 p < r->header_in->last - 1; | 880 header.len = r->header_end - r->header_name_start; |
886 p++) | 881 header.data = r->header_name_start; |
887 { | 882 ngx_log_error(NGX_LOG_INFO, c->log, 0, |
888 if (*p == LF) { | 883 "client sent invalid header line: \"%V\\r...\"", |
889 break; | 884 &header); |
890 } | 885 ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST); |
891 } | 886 ngx_http_close_connection(c); |
892 *p = '\0'; | 887 return; |
893 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, | |
894 "http invalid header: \"%s\"", | |
895 r->header_name_start); | |
896 } | |
897 #endif | |
898 | |
899 ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST); | |
900 return; | |
901 } | |
902 | |
903 /* NGX_AGAIN: a header line parsing is still not complete */ | |
904 | |
905 } | 888 } |
906 } | 889 } |
907 | 890 |
908 | 891 |
909 static ssize_t | 892 static ssize_t |
1106 | 1089 |
1107 | 1090 |
1108 static ngx_int_t | 1091 static ngx_int_t |
1109 ngx_http_process_request_header(ngx_http_request_t *r) | 1092 ngx_http_process_request_header(ngx_http_request_t *r) |
1110 { | 1093 { |
1111 u_char *ua, *user_agent, ch; | 1094 size_t len; |
1112 size_t len; | 1095 u_char *ua, *user_agent, ch; |
1096 ngx_http_core_srv_conf_t *cscf; | |
1113 | 1097 |
1114 if (r->headers_in.host) { | 1098 if (r->headers_in.host) { |
1115 for (len = 0; len < r->headers_in.host->value.len; len++) { | 1099 for (len = 0; len < r->headers_in.host->value.len; len++) { |
1116 ch = r->headers_in.host->value.data[len]; | 1100 ch = r->headers_in.host->value.data[len]; |
1117 | 1101 |
1119 break; | 1103 break; |
1120 } | 1104 } |
1121 | 1105 |
1122 r->headers_in.host->value.data[len] = ngx_tolower(ch); | 1106 r->headers_in.host->value.data[len] = ngx_tolower(ch); |
1123 } | 1107 } |
1108 | |
1124 r->headers_in.host_name_len = len; | 1109 r->headers_in.host_name_len = len; |
1125 | 1110 |
1126 if (ngx_http_find_virtual_server(r) != NGX_OK) { | 1111 if (ngx_http_find_virtual_server(r) != NGX_OK) { |
1127 return NGX_HTTP_PARSE_INVALID_HOST; | 1112 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, |
1113 "client sent invalid \"Host\" header"); | |
1114 | |
1115 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); | |
1116 | |
1117 if (cscf->restrict_host_names == NGX_HTTP_RESTRICT_HOST_CLOSE) { | |
1118 ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST); | |
1119 ngx_http_close_connection(r->connection); | |
1120 return NGX_ERROR; | |
1121 } | |
1122 | |
1123 ngx_http_finalize_request(r, NGX_HTTP_INVALID_HOST); | |
1124 return NGX_ERROR; | |
1128 } | 1125 } |
1129 | 1126 |
1130 } else { | 1127 } else { |
1131 if (r->http_version > NGX_HTTP_VERSION_10) { | 1128 if (r->http_version > NGX_HTTP_VERSION_10) { |
1132 return NGX_HTTP_PARSE_NO_HOST_HEADER; | 1129 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, |
1133 } | 1130 "client sent HTTP/1.1 request without \"Host\" header"); |
1131 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); | |
1132 return NGX_ERROR; | |
1133 } | |
1134 | |
1134 r->headers_in.host_name_len = 0; | 1135 r->headers_in.host_name_len = 0; |
1135 } | 1136 } |
1136 | 1137 |
1137 if (r->headers_in.content_length) { | 1138 if (r->headers_in.content_length) { |
1138 r->headers_in.content_length_n = | 1139 r->headers_in.content_length_n = |
1139 ngx_atosz(r->headers_in.content_length->value.data, | 1140 ngx_atosz(r->headers_in.content_length->value.data, |
1140 r->headers_in.content_length->value.len); | 1141 r->headers_in.content_length->value.len); |
1141 | 1142 |
1142 if (r->headers_in.content_length_n == NGX_ERROR) { | 1143 if (r->headers_in.content_length_n == NGX_ERROR) { |
1143 return NGX_HTTP_PARSE_INVALID_CL_HEADER; | 1144 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, |
1145 "client sent invalid \"Content-Length\" header"); | |
1146 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); | |
1147 return NGX_ERROR; | |
1144 } | 1148 } |
1145 } | 1149 } |
1146 | 1150 |
1147 if (r->method == NGX_HTTP_POST && r->headers_in.content_length_n == -1) { | 1151 if (r->method == NGX_HTTP_POST && r->headers_in.content_length_n == -1) { |
1148 return NGX_HTTP_PARSE_POST_WO_CL_HEADER; | 1152 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, |
1153 "client sent POST method without \"Content-Length\" header"); | |
1154 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); | |
1155 return NGX_ERROR; | |
1149 } | 1156 } |
1150 | 1157 |
1151 if (r->plain_http) { | 1158 if (r->plain_http) { |
1152 return NGX_HTTP_PARSE_HTTP_TO_HTTPS; | 1159 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, |
1160 "client sent plain HTTP request to HTTPS port"); | |
1161 ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS); | |
1162 return NGX_ERROR; | |
1153 } | 1163 } |
1154 | 1164 |
1155 if (r->headers_in.connection) { | 1165 if (r->headers_in.connection) { |
1156 if (r->headers_in.connection->value.len == 5 | 1166 if (r->headers_in.connection->value.len == 5 |
1157 && ngx_strcasecmp(r->headers_in.connection->value.data, "close") | 1167 && ngx_strcasecmp(r->headers_in.connection->value.data, "close") |
1455 c = wev->data; | 1465 c = wev->data; |
1456 r = c->data; | 1466 r = c->data; |
1457 | 1467 |
1458 if (wev->timedout) { | 1468 if (wev->timedout) { |
1459 if (!wev->delayed) { | 1469 if (!wev->delayed) { |
1460 ngx_http_client_error(r, 0, NGX_HTTP_REQUEST_TIME_OUT); | 1470 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, |
1471 "client timed out"); | |
1472 c->timedout = 1; | |
1473 ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT); | |
1474 ngx_http_close_connection(c); | |
1461 return; | 1475 return; |
1462 } | 1476 } |
1463 | 1477 |
1464 wev->timedout = 0; | 1478 wev->timedout = 0; |
1465 wev->delayed = 0; | 1479 wev->delayed = 0; |
2265 | 2279 |
2266 ngx_destroy_pool(pool); | 2280 ngx_destroy_pool(pool); |
2267 } | 2281 } |
2268 | 2282 |
2269 | 2283 |
2270 static void | |
2271 ngx_http_client_error(ngx_http_request_t *r, int client_error, int error) | |
2272 { | |
2273 u_char *p; | |
2274 ngx_http_log_ctx_t *ctx; | |
2275 ngx_http_core_srv_conf_t *cscf; | |
2276 | |
2277 ctx = r->connection->log->data; | |
2278 | |
2279 if (error == NGX_HTTP_REQUEST_TIME_OUT) { | |
2280 ngx_log_error(NGX_LOG_INFO, r->connection->log, NGX_ETIMEDOUT, | |
2281 "client timed out"); | |
2282 r->connection->timedout = 1; | |
2283 ngx_http_close_request(r, error); | |
2284 ngx_http_close_connection(r->connection); | |
2285 return; | |
2286 } | |
2287 | |
2288 r->connection->log->handler = NULL; | |
2289 | |
2290 if (ctx->request) { | |
2291 | |
2292 switch (client_error) { | |
2293 | |
2294 case NGX_HTTP_PARSE_INVALID_HOST: | |
2295 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
2296 "client %V sent invalid \"Host\" header \"%V\", URL: \"%V\"", | |
2297 ctx->client, &r->headers_in.host->value, | |
2298 &ctx->request->unparsed_uri); | |
2299 | |
2300 error = NGX_HTTP_INVALID_HOST; | |
2301 | |
2302 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); | |
2303 | |
2304 if (cscf->restrict_host_names == NGX_HTTP_RESTRICT_HOST_CLOSE) { | |
2305 ngx_http_close_request(r, error); | |
2306 ngx_http_close_connection(r->connection); | |
2307 return; | |
2308 } | |
2309 | |
2310 break; | |
2311 | |
2312 case NGX_HTTP_PARSE_HTTP_TO_HTTPS: | |
2313 error = NGX_HTTP_TO_HTTPS; | |
2314 if (ctx->request->headers_in.referer) { | |
2315 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
2316 "client %V sent plain HTTP request to HTTPS port, " | |
2317 "URL: \"%V\", referrer \"%V\"", | |
2318 ctx->client, &ctx->request->unparsed_uri, | |
2319 &ctx->request->headers_in.referer->value); | |
2320 | |
2321 } else { | |
2322 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
2323 "client %V sent plain HTTP request to HTTPS port, " | |
2324 "URL: \"%V\"", ctx->client, &ctx->request->unparsed_uri); | |
2325 } | |
2326 | |
2327 break; | |
2328 | |
2329 default: | |
2330 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
2331 client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR], | |
2332 ctx->client, &ctx->request->unparsed_uri); | |
2333 } | |
2334 | |
2335 } else { | |
2336 | |
2337 if (error == NGX_HTTP_REQUEST_URI_TOO_LARGE) { | |
2338 r->request_line.len = r->header_in->end - r->request_start; | |
2339 r->request_line.data = r->request_start; | |
2340 | |
2341 } else { | |
2342 if (r->request_line.data == NULL) { | |
2343 for (p = r->request_start; p < r->header_in->last; p++) { | |
2344 if (*p == CR || *p == LF) { | |
2345 break; | |
2346 } | |
2347 } | |
2348 | |
2349 r->request_line.len = p - r->request_start; | |
2350 r->request_line.data = r->request_start; | |
2351 } | |
2352 } | |
2353 | |
2354 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
2355 client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR], | |
2356 ctx->client, &r->request_line); | |
2357 } | |
2358 | |
2359 r->connection->log->handler = ngx_http_log_error; | |
2360 | |
2361 ngx_http_finalize_request(r, error); | |
2362 } | |
2363 | |
2364 | |
2365 static u_char * | 2284 static u_char * |
2366 ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len) | 2285 ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len) |
2367 { | 2286 { |
2368 u_char *p; | 2287 u_char *p; |
2288 ngx_http_request_t *r; | |
2369 ngx_http_log_ctx_t *ctx; | 2289 ngx_http_log_ctx_t *ctx; |
2370 | 2290 |
2371 p = buf; | 2291 p = buf; |
2372 | 2292 |
2373 ctx = log->data; | 2293 ctx = log->data; |
2374 | 2294 |
2375 if (log->action) { | 2295 if (log->action) { |
2376 p = ngx_snprintf(p, len, " while %s", log->action); | 2296 p = ngx_snprintf(p, len, " while %s", log->action); |
2377 len -= p - buf; | 2297 len -= p - buf; |
2378 } | 2298 buf = p; |
2379 | 2299 } |
2380 p = ngx_snprintf(p, len, ", client: %V", ctx->client); | 2300 |
2381 | 2301 p = ngx_snprintf(buf, len, ", client: %V", ctx->client); |
2382 if (ctx->request == NULL) { | 2302 |
2303 r = ctx->request; | |
2304 | |
2305 if (r == NULL) { | |
2383 return p; | 2306 return p; |
2384 } | 2307 } |
2385 | 2308 |
2386 len -= p - buf; | 2309 len -= p - buf; |
2387 | 2310 buf = p; |
2388 if (ctx->request->server_name.data) { | 2311 |
2389 p = ngx_snprintf(p, len, ", host: %V", &ctx->request->server_name); | 2312 if (r->server_name.data) { |
2313 p = ngx_snprintf(buf, len, ", server: %V", &r->server_name); | |
2390 len -= p - buf; | 2314 len -= p - buf; |
2391 } | 2315 buf = p; |
2392 | 2316 } |
2393 p = ngx_snprintf(p, len, ", URL: \"%V\"", &ctx->request->unparsed_uri); | 2317 |
2394 | 2318 if (r->unparsed_uri.data) { |
2395 if (ctx->request->headers_in.referer == NULL) { | 2319 p = ngx_snprintf(buf, len, ", URL: \"%V\"", &r->unparsed_uri); |
2396 return p; | 2320 len -= p - buf; |
2397 } | 2321 buf = p; |
2398 | 2322 |
2399 len -= p - buf; | 2323 } else { |
2400 | 2324 if (r->request_line.data == NULL && r->request_start) { |
2401 return ngx_snprintf(p, len, ", referrer: \"%V\"", | 2325 for (p = r->request_start; p < r->header_in->last; p++) { |
2402 &ctx->request->headers_in.referer->value); | 2326 if (*p == CR || *p == LF) { |
2403 } | 2327 break; |
2328 } | |
2329 } | |
2330 | |
2331 r->request_line.len = p - r->request_start; | |
2332 r->request_line.data = r->request_start; | |
2333 } | |
2334 | |
2335 if (r->request_line.len) { | |
2336 p = ngx_snprintf(buf, len, ", request: \"%V\"", &r->request_line); | |
2337 len -= p - buf; | |
2338 buf = p; | |
2339 } | |
2340 } | |
2341 | |
2342 return ngx_http_log_error_info(r, buf, len); | |
2343 } | |
2344 | |
2345 | |
2346 u_char * | |
2347 ngx_http_log_error_info(ngx_http_request_t *r, u_char *buf, size_t len) | |
2348 { | |
2349 u_char *p; | |
2350 | |
2351 if (r->headers_in.host) { | |
2352 p = ngx_snprintf(buf, len, ", host: \"%V\"", | |
2353 &r->headers_in.host->value); | |
2354 len -= p - buf; | |
2355 buf = p; | |
2356 } | |
2357 | |
2358 if (r->headers_in.referer) { | |
2359 p = ngx_snprintf(buf, len, ", referrer: \"%V\"", | |
2360 &r->headers_in.referer->value); | |
2361 buf = p; | |
2362 } | |
2363 | |
2364 return buf; | |
2365 } |