OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/http/http_stream_parser.h" | 5 #include "net/http/http_stream_parser.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
207 request_(request), | 207 request_(request), |
208 request_headers_(nullptr), | 208 request_headers_(nullptr), |
209 request_headers_length_(0), | 209 request_headers_length_(0), |
210 read_buf_(read_buffer), | 210 read_buf_(read_buffer), |
211 read_buf_unused_offset_(0), | 211 read_buf_unused_offset_(0), |
212 response_header_start_offset_(-1), | 212 response_header_start_offset_(-1), |
213 received_bytes_(0), | 213 received_bytes_(0), |
214 sent_bytes_(0), | 214 sent_bytes_(0), |
215 response_(nullptr), | 215 response_(nullptr), |
216 response_body_length_(-1), | 216 response_body_length_(-1), |
217 response_is_keep_alive_(false), | |
217 response_body_read_(0), | 218 response_body_read_(0), |
218 user_read_buf_(nullptr), | 219 user_read_buf_(nullptr), |
219 user_read_buf_len_(0), | 220 user_read_buf_len_(0), |
220 connection_(connection), | 221 connection_(connection), |
221 net_log_(net_log), | 222 net_log_(net_log), |
222 sent_last_chunk_(false), | 223 sent_last_chunk_(false), |
223 upload_error_(OK), | 224 upload_error_(OK), |
224 weak_ptr_factory_(this) { | 225 weak_ptr_factory_(this) { |
225 io_callback_ = base::Bind(&HttpStreamParser::OnIOComplete, | 226 io_callback_ = base::Bind(&HttpStreamParser::OnIOComplete, |
226 weak_ptr_factory_.GetWeakPtr()); | 227 weak_ptr_factory_.GetWeakPtr()); |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
587 read_buf_->SetCapacity(read_buf_->capacity() + kHeaderBufInitialSize); | 588 read_buf_->SetCapacity(read_buf_->capacity() + kHeaderBufInitialSize); |
588 | 589 |
589 // http://crbug.com/16371: We're seeing |user_buf_->data()| return NULL. | 590 // http://crbug.com/16371: We're seeing |user_buf_->data()| return NULL. |
590 // See if the user is passing in an IOBuffer with a NULL |data_|. | 591 // See if the user is passing in an IOBuffer with a NULL |data_|. |
591 CHECK(read_buf_->data()); | 592 CHECK(read_buf_->data()); |
592 | 593 |
593 return connection_->socket() | 594 return connection_->socket() |
594 ->Read(read_buf_.get(), read_buf_->RemainingCapacity(), io_callback_); | 595 ->Read(read_buf_.get(), read_buf_->RemainingCapacity(), io_callback_); |
595 } | 596 } |
596 | 597 |
597 int HttpStreamParser::DoReadHeadersComplete(int result) { | 598 int HttpStreamParser::DoReadHeadersComplete(int result) { |
mmenke
2016/05/20 21:50:02
We could probably null out response_ now, whenever
| |
598 // DoReadHeadersComplete is called with the result of Socket::Read, which is a | 599 // DoReadHeadersComplete is called with the result of Socket::Read, which is a |
599 // (byte_count | error), and returns (error | OK). | 600 // (byte_count | error), and returns (error | OK). |
600 | 601 |
601 result = HandleReadHeaderResult(result); | 602 result = HandleReadHeaderResult(result); |
602 | 603 |
603 // TODO(mmenke): The code below is ugly and hacky. A much better and more | 604 // TODO(mmenke): The code below is ugly and hacky. A much better and more |
604 // flexible long term solution would be to separate out the read and write | 605 // flexible long term solution would be to separate out the read and write |
605 // loops, though this would involve significant changes, both here and | 606 // loops, though this would involve significant changes, both here and |
606 // elsewhere (WebSockets, for instance). | 607 // elsewhere (WebSockets, for instance). |
607 | 608 |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
862 | 863 |
863 if (end_of_header_offset == -1) { | 864 if (end_of_header_offset == -1) { |
864 io_state_ = STATE_READ_HEADERS; | 865 io_state_ = STATE_READ_HEADERS; |
865 // Prevent growing the headers buffer indefinitely. | 866 // Prevent growing the headers buffer indefinitely. |
866 if (read_buf_->offset() >= kMaxHeaderBufSize) { | 867 if (read_buf_->offset() >= kMaxHeaderBufSize) { |
867 io_state_ = STATE_DONE; | 868 io_state_ = STATE_DONE; |
868 return ERR_RESPONSE_HEADERS_TOO_BIG; | 869 return ERR_RESPONSE_HEADERS_TOO_BIG; |
869 } | 870 } |
870 } else { | 871 } else { |
871 CalculateResponseBodySize(); | 872 CalculateResponseBodySize(); |
873 | |
872 // If the body is zero length, the caller may not call ReadResponseBody, | 874 // If the body is zero length, the caller may not call ReadResponseBody, |
873 // which is where any extra data is copied to read_buf_, so we move the | 875 // which is where any extra data is copied to read_buf_, so we move the |
874 // data here. | 876 // data here. |
875 if (response_body_length_ == 0) { | 877 if (response_body_length_ == 0) { |
876 int extra_bytes = read_buf_->offset() - end_of_header_offset; | 878 int extra_bytes = read_buf_->offset() - end_of_header_offset; |
877 if (extra_bytes) { | 879 if (extra_bytes) { |
878 CHECK_GT(extra_bytes, 0); | 880 CHECK_GT(extra_bytes, 0); |
879 memmove(read_buf_->StartOfBuffer(), | 881 memmove(read_buf_->StartOfBuffer(), |
880 read_buf_->StartOfBuffer() + end_of_header_offset, | 882 read_buf_->StartOfBuffer() + end_of_header_offset, |
881 extra_bytes); | 883 extra_bytes); |
882 } | 884 } |
883 read_buf_->SetCapacity(extra_bytes); | 885 read_buf_->SetCapacity(extra_bytes); |
884 if (response_->headers->response_code() / 100 == 1) { | 886 if (response_->headers->response_code() / 100 == 1) { |
885 // After processing a 1xx response, the caller will ask for the next | 887 // After processing a 1xx response, the caller will ask for the next |
886 // header, so reset state to support that. We don't completely ignore a | 888 // header, so reset state to support that. We don't completely ignore a |
887 // 1xx response because it cannot be returned in reply to a CONNECT | 889 // 1xx response because it cannot be returned in reply to a CONNECT |
888 // request so we return OK here, which lets the caller inspect the | 890 // request so we return OK here, which lets the caller inspect the |
889 // response and reject it in the event that we're setting up a CONNECT | 891 // response and reject it in the event that we're setting up a CONNECT |
890 // tunnel. | 892 // tunnel. |
891 response_header_start_offset_ = -1; | 893 response_header_start_offset_ = -1; |
892 response_body_length_ = -1; | 894 response_body_length_ = -1; |
893 // Now waiting for the second set of headers to be read. | 895 // Now waiting for the second set of headers to be read. |
894 } else { | 896 } else { |
897 // Only set keep-alive based on final set of headers. | |
898 response_is_keep_alive_ = response_->headers->IsKeepAlive(); | |
899 | |
895 io_state_ = STATE_DONE; | 900 io_state_ = STATE_DONE; |
896 } | 901 } |
897 return OK; | 902 return OK; |
898 } | 903 } |
899 | 904 |
905 // Only set keep-alive based on final set of headers. | |
906 response_is_keep_alive_ = response_->headers->IsKeepAlive(); | |
907 | |
900 // Note where the headers stop. | 908 // Note where the headers stop. |
901 read_buf_unused_offset_ = end_of_header_offset; | 909 read_buf_unused_offset_ = end_of_header_offset; |
902 // Now waiting for the body to be read. | 910 // Now waiting for the body to be read. |
903 } | 911 } |
904 return OK; | 912 return OK; |
905 } | 913 } |
906 | 914 |
907 int HttpStreamParser::FindAndParseResponseHeaders() { | 915 int HttpStreamParser::FindAndParseResponseHeaders() { |
908 int end_offset = -1; | 916 int end_offset = -1; |
909 DCHECK_EQ(0, read_buf_unused_offset_); | 917 DCHECK_EQ(0, read_buf_unused_offset_); |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1080 reuse_type == ClientSocketHandle::UNUSED_IDLE; | 1088 reuse_type == ClientSocketHandle::UNUSED_IDLE; |
1081 } | 1089 } |
1082 | 1090 |
1083 void HttpStreamParser::SetConnectionReused() { | 1091 void HttpStreamParser::SetConnectionReused() { |
1084 connection_->set_reuse_type(ClientSocketHandle::REUSED_IDLE); | 1092 connection_->set_reuse_type(ClientSocketHandle::REUSED_IDLE); |
1085 } | 1093 } |
1086 | 1094 |
1087 bool HttpStreamParser::CanReuseConnection() const { | 1095 bool HttpStreamParser::CanReuseConnection() const { |
1088 if (!CanFindEndOfResponse()) | 1096 if (!CanFindEndOfResponse()) |
1089 return false; | 1097 return false; |
1090 if (!response_->headers || !response_->headers->IsKeepAlive()) | 1098 |
1099 if (!response_is_keep_alive_) | |
1091 return false; | 1100 return false; |
1101 | |
1102 // Check if extra data was received after reading the entire response body. If | |
1103 // extra data was received reusing the socket is not a great idea. This does | |
1104 // have the down side of papering over certain server bugs, but seems to be | |
1105 // the best option here. | |
1106 // | |
1107 // TODO(mmenke): Consider logging this - hard to decipher socket reuse | |
1108 // behavior makes NetLogs harder to read. | |
1109 if (IsResponseBodyComplete() && read_buf_->offset() > 0) | |
asanka
2016/06/01 19:43:35
Is it possible for (read_buf_->offset() > 0) to be
mmenke
2016/06/02 15:56:23
Done. Good suggestion - it's much clearer.
| |
1110 return false; | |
1111 | |
1092 return connection_->socket() && connection_->socket()->IsConnected(); | 1112 return connection_->socket() && connection_->socket()->IsConnected(); |
1093 } | 1113 } |
1094 | 1114 |
1095 void HttpStreamParser::GetSSLInfo(SSLInfo* ssl_info) { | 1115 void HttpStreamParser::GetSSLInfo(SSLInfo* ssl_info) { |
1096 if (request_->url.SchemeIsCryptographic() && connection_->socket()) { | 1116 if (request_->url.SchemeIsCryptographic() && connection_->socket()) { |
1097 SSLClientSocket* ssl_socket = | 1117 SSLClientSocket* ssl_socket = |
1098 static_cast<SSLClientSocket*>(connection_->socket()); | 1118 static_cast<SSLClientSocket*>(connection_->socket()); |
1099 ssl_socket->GetSSLInfo(ssl_info); | 1119 ssl_socket->GetSSLInfo(ssl_info); |
1100 } | 1120 } |
1101 } | 1121 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1160 } | 1180 } |
1161 | 1181 |
1162 void HttpStreamParser::ValidateStatusLine(const std::string& status_line) { | 1182 void HttpStreamParser::ValidateStatusLine(const std::string& status_line) { |
1163 HttpStatusLineValidator::StatusLineStatus status = | 1183 HttpStatusLineValidator::StatusLineStatus status = |
1164 HttpStatusLineValidator::ValidateStatusLine(status_line); | 1184 HttpStatusLineValidator::ValidateStatusLine(status_line); |
1165 UMA_HISTOGRAM_ENUMERATION("Net.HttpStatusLineStatus", status, | 1185 UMA_HISTOGRAM_ENUMERATION("Net.HttpStatusLineStatus", status, |
1166 HttpStatusLineValidator::STATUS_LINE_MAX); | 1186 HttpStatusLineValidator::STATUS_LINE_MAX); |
1167 } | 1187 } |
1168 | 1188 |
1169 } // namespace net | 1189 } // namespace net |
OLD | NEW |