Chromium Code Reviews| 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_network_transaction.h" | 5 #include "net/http/http_network_transaction.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 #endif | 68 #endif |
| 69 | 69 |
| 70 | 70 |
| 71 using base::Time; | 71 using base::Time; |
| 72 using base::TimeDelta; | 72 using base::TimeDelta; |
| 73 | 73 |
| 74 namespace net { | 74 namespace net { |
| 75 | 75 |
| 76 namespace { | 76 namespace { |
| 77 | 77 |
| 78 // Array of all network error codes. Needed for histograms. | |
|
mmenke
2014/07/22 14:57:41
Not needed. See GetAllErrorCodesForUma (declared
jonnyr
2014/07/23 08:43:04
Done.
| |
| 79 const int kAllNetErrorCodes[] = { | |
| 80 #define NET_ERROR(label, value) - (value), | |
| 81 #include "net/base/net_error_list.h" | |
| 82 #undef NET_ERROR | |
| 83 }; | |
| 84 | |
| 78 void ProcessAlternateProtocol( | 85 void ProcessAlternateProtocol( |
| 79 HttpNetworkSession* session, | 86 HttpNetworkSession* session, |
| 80 const HttpResponseHeaders& headers, | 87 const HttpResponseHeaders& headers, |
| 81 const HostPortPair& http_host_port_pair) { | 88 const HostPortPair& http_host_port_pair) { |
| 82 if (!headers.HasHeader(kAlternateProtocolHeader)) | 89 if (!headers.HasHeader(kAlternateProtocolHeader)) |
| 83 return; | 90 return; |
| 84 | 91 |
| 85 std::vector<std::string> alternate_protocol_values; | 92 std::vector<std::string> alternate_protocol_values; |
| 86 void* iter = NULL; | 93 void* iter = NULL; |
| 87 std::string alternate_protocol_str; | 94 std::string alternate_protocol_str; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 135 base::Unretained(this))), | 142 base::Unretained(this))), |
| 136 session_(session), | 143 session_(session), |
| 137 request_(NULL), | 144 request_(NULL), |
| 138 priority_(priority), | 145 priority_(priority), |
| 139 headers_valid_(false), | 146 headers_valid_(false), |
| 140 logged_response_time_(false), | 147 logged_response_time_(false), |
| 141 fallback_error_code_(ERR_SSL_INAPPROPRIATE_FALLBACK), | 148 fallback_error_code_(ERR_SSL_INAPPROPRIATE_FALLBACK), |
| 142 request_headers_(), | 149 request_headers_(), |
| 143 read_buf_len_(0), | 150 read_buf_len_(0), |
| 144 total_received_bytes_(0), | 151 total_received_bytes_(0), |
| 152 retry_attempt_(0), | |
| 153 offset_(0), | |
| 154 previous_content_length_(0), | |
| 145 next_state_(STATE_NONE), | 155 next_state_(STATE_NONE), |
| 146 establishing_tunnel_(false), | 156 establishing_tunnel_(false), |
| 147 websocket_handshake_stream_base_create_helper_(NULL) { | 157 websocket_handshake_stream_base_create_helper_(NULL) { |
| 148 session->ssl_config_service()->GetSSLConfig(&server_ssl_config_); | 158 session->ssl_config_service()->GetSSLConfig(&server_ssl_config_); |
| 149 session->GetNextProtos(&server_ssl_config_.next_protos); | 159 session->GetNextProtos(&server_ssl_config_.next_protos); |
| 150 proxy_ssl_config_ = server_ssl_config_; | 160 proxy_ssl_config_ = server_ssl_config_; |
| 151 } | 161 } |
| 152 | 162 |
| 153 HttpNetworkTransaction::~HttpNetworkTransaction() { | 163 HttpNetworkTransaction::~HttpNetworkTransaction() { |
| 154 if (stream_.get()) { | 164 if (stream_.get()) { |
| (...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 771 } | 781 } |
| 772 | 782 |
| 773 int HttpNetworkTransaction::DoInitStream() { | 783 int HttpNetworkTransaction::DoInitStream() { |
| 774 DCHECK(stream_.get()); | 784 DCHECK(stream_.get()); |
| 775 next_state_ = STATE_INIT_STREAM_COMPLETE; | 785 next_state_ = STATE_INIT_STREAM_COMPLETE; |
| 776 return stream_->InitializeStream(request_, priority_, net_log_, io_callback_); | 786 return stream_->InitializeStream(request_, priority_, net_log_, io_callback_); |
| 777 } | 787 } |
| 778 | 788 |
| 779 int HttpNetworkTransaction::DoInitStreamComplete(int result) { | 789 int HttpNetworkTransaction::DoInitStreamComplete(int result) { |
| 780 if (result == OK) { | 790 if (result == OK) { |
| 791 if (offset_) | |
| 792 stream_->SetRestartInfo(offset_, hash_, sizeof(hash_)); | |
| 781 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; | 793 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; |
| 782 } else { | 794 } else { |
| 783 if (result < 0) | 795 if (result < 0) |
| 784 result = HandleIOError(result); | 796 result = HandleIOError(result); |
| 785 | 797 |
| 786 // The stream initialization failed, so this stream will never be useful. | 798 // The stream initialization failed, so this stream will never be useful. |
| 787 if (stream_) | 799 if (stream_) |
| 788 total_received_bytes_ += stream_->GetTotalReceivedBytes(); | 800 total_received_bytes_ += stream_->GetTotalReceivedBytes(); |
| 789 stream_.reset(); | 801 stream_.reset(); |
| 790 } | 802 } |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 993 // bizarre for SPDY. Assuming this logic is useful at all. | 1005 // bizarre for SPDY. Assuming this logic is useful at all. |
| 994 // TODO(davidben): Bubble the error code up so we do not cache? | 1006 // TODO(davidben): Bubble the error code up so we do not cache? |
| 995 if (result == ERR_CONNECTION_CLOSED && response_.headers.get()) | 1007 if (result == ERR_CONNECTION_CLOSED && response_.headers.get()) |
| 996 result = OK; | 1008 result = OK; |
| 997 | 1009 |
| 998 if (result < 0) | 1010 if (result < 0) |
| 999 return HandleIOError(result); | 1011 return HandleIOError(result); |
| 1000 | 1012 |
| 1001 DCHECK(response_.headers.get()); | 1013 DCHECK(response_.headers.get()); |
| 1002 | 1014 |
| 1015 if ((response_.headers->response_code() == 200 || | |
| 1016 response_.headers->response_code() == 206) && offset_) { | |
| 1017 std::string etag, last_modified; | |
| 1018 response_.headers->EnumerateHeader(NULL, "last-modified", &last_modified); | |
| 1019 if (response_.headers->GetHttpVersion() >= HttpVersion(1, 1)) | |
| 1020 response_.headers->EnumerateHeader(NULL, "etag", &etag); | |
| 1021 | |
| 1022 // Return an error if content was updated on a retry. | |
| 1023 if ((previous_content_length_ != response_.headers->GetContentLength() && | |
| 1024 response_.headers->response_code() == 200) || | |
| 1025 previous_etag_ != etag || previous_last_modified_ != last_modified) | |
| 1026 return HandleIOError(ERR_RETRY_CONTENT_UPDATED); | |
| 1027 } | |
| 1028 | |
| 1003 // On a 408 response from the server ("Request Timeout") on a stale socket, | 1029 // On a 408 response from the server ("Request Timeout") on a stale socket, |
| 1004 // retry the request. | 1030 // retry the request. |
| 1005 // Headers can be NULL because of http://crbug.com/384554. | 1031 // Headers can be NULL because of http://crbug.com/384554. |
| 1006 if (response_.headers.get() && response_.headers->response_code() == 408 && | 1032 if (response_.headers.get() && response_.headers->response_code() == 408 && |
| 1007 stream_->IsConnectionReused()) { | 1033 stream_->IsConnectionReused()) { |
| 1008 net_log_.AddEventWithNetErrorCode( | 1034 net_log_.AddEventWithNetErrorCode( |
| 1009 NetLog::TYPE_HTTP_TRANSACTION_RESTART_AFTER_ERROR, | 1035 NetLog::TYPE_HTTP_TRANSACTION_RESTART_AFTER_ERROR, |
| 1010 response_.headers->response_code()); | 1036 response_.headers->response_code()); |
| 1011 // This will close the socket - it would be weird to try and reuse it, even | 1037 // This will close the socket - it would be weird to try and reuse it, even |
| 1012 // if the server doesn't actually close it. | 1038 // if the server doesn't actually close it. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1054 | 1080 |
| 1055 int rv = HandleAuthChallenge(); | 1081 int rv = HandleAuthChallenge(); |
| 1056 if (rv != OK) | 1082 if (rv != OK) |
| 1057 return rv; | 1083 return rv; |
| 1058 | 1084 |
| 1059 if (is_https_request()) | 1085 if (is_https_request()) |
| 1060 stream_->GetSSLInfo(&response_.ssl_info); | 1086 stream_->GetSSLInfo(&response_.ssl_info); |
| 1061 | 1087 |
| 1062 headers_valid_ = true; | 1088 headers_valid_ = true; |
| 1063 | 1089 |
| 1090 if (retry_attempt_ && read_buf_.get()) | |
| 1091 next_state_ = STATE_READ_BODY; | |
| 1092 | |
| 1064 if (session_->huffman_aggregator()) { | 1093 if (session_->huffman_aggregator()) { |
| 1065 session_->huffman_aggregator()->AggregateTransactionCharacterCounts( | 1094 session_->huffman_aggregator()->AggregateTransactionCharacterCounts( |
| 1066 *request_, | 1095 *request_, |
| 1067 request_headers_, | 1096 request_headers_, |
| 1068 proxy_info_.proxy_server(), | 1097 proxy_info_.proxy_server(), |
| 1069 *response_.headers); | 1098 *response_.headers); |
| 1070 } | 1099 } |
| 1071 return OK; | 1100 return OK; |
| 1072 } | 1101 } |
| 1073 | 1102 |
| 1074 int HttpNetworkTransaction::DoReadBody() { | 1103 int HttpNetworkTransaction::DoReadBody() { |
| 1075 DCHECK(read_buf_.get()); | 1104 DCHECK(read_buf_.get()); |
| 1076 DCHECK_GT(read_buf_len_, 0); | 1105 DCHECK_GT(read_buf_len_, 0); |
| 1077 DCHECK(stream_ != NULL); | 1106 DCHECK(stream_ != NULL); |
| 1078 | 1107 |
| 1079 next_state_ = STATE_READ_BODY_COMPLETE; | 1108 next_state_ = STATE_READ_BODY_COMPLETE; |
| 1080 return stream_->ReadResponseBody( | 1109 return stream_->ReadResponseBody( |
| 1081 read_buf_.get(), read_buf_len_, io_callback_); | 1110 read_buf_.get(), read_buf_len_, io_callback_); |
| 1082 } | 1111 } |
| 1083 | 1112 |
| 1084 int HttpNetworkTransaction::DoReadBodyComplete(int result) { | 1113 int HttpNetworkTransaction::DoReadBodyComplete(int result) { |
| 1085 // We are done with the Read call. | 1114 // We are done with the Read call. |
| 1086 bool done = false; | 1115 bool done = false; |
| 1087 if (result <= 0) { | 1116 if (result <= 0) { |
| 1088 DCHECK_NE(ERR_IO_PENDING, result); | 1117 DCHECK_NE(ERR_IO_PENDING, result); |
| 1118 if (result < 0) | |
| 1119 return HandleIOError(result); | |
| 1089 done = true; | 1120 done = true; |
| 1090 } | 1121 } |
| 1091 | 1122 |
| 1092 bool keep_alive = false; | 1123 bool keep_alive = false; |
| 1093 if (stream_->IsResponseBodyComplete()) { | 1124 if (stream_->IsResponseBodyComplete()) { |
| 1094 // Note: Just because IsResponseBodyComplete is true, we're not | 1125 // Note: Just because IsResponseBodyComplete is true, we're not |
| 1095 // necessarily "done". We're only "done" when it is the last | 1126 // necessarily "done". We're only "done" when it is the last |
| 1096 // read on this HttpNetworkTransaction, which will be signified | 1127 // read on this HttpNetworkTransaction, which will be signified |
| 1097 // by a zero-length read. | 1128 // by a zero-length read. |
| 1098 // TODO(mbelshe): The keepalive property is really a property of | 1129 // TODO(mbelshe): The keepalive property is really a property of |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1220 base::TimeDelta::FromMinutes(10), 100); | 1251 base::TimeDelta::FromMinutes(10), 100); |
| 1221 | 1252 |
| 1222 if (!stream_->IsConnectionReused()) { | 1253 if (!stream_->IsConnectionReused()) { |
| 1223 UMA_HISTOGRAM_CUSTOM_TIMES( | 1254 UMA_HISTOGRAM_CUSTOM_TIMES( |
| 1224 "Net.Transaction_Latency_Total_New_Connection", | 1255 "Net.Transaction_Latency_Total_New_Connection", |
| 1225 total_duration, base::TimeDelta::FromMilliseconds(1), | 1256 total_duration, base::TimeDelta::FromMilliseconds(1), |
| 1226 base::TimeDelta::FromMinutes(10), 100); | 1257 base::TimeDelta::FromMinutes(10), 100); |
| 1227 } | 1258 } |
| 1228 } | 1259 } |
| 1229 | 1260 |
| 1261 void HttpNetworkTransaction::LogTransactionRetryMetrics(int error) const { | |
| 1262 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.HttpRetry.Count", retry_attempt_, 1, 5, 5); | |
| 1263 if (request_->load_flags & LOAD_MAIN_FRAME) | |
|
mmenke
2014/07/22 14:57:41
Use braces when the body of an if takes more than
jonnyr
2014/07/23 08:43:04
Done.
| |
| 1264 UMA_HISTOGRAM_CUSTOM_ENUMERATION( | |
| 1265 "Net.HttpRetry.Cause.MainFrame", | |
| 1266 -error, | |
| 1267 base::CustomHistogram::ArrayToCustomRanges( | |
| 1268 kAllNetErrorCodes, arraysize(kAllNetErrorCodes))); | |
|
mmenke
2014/07/22 14:57:41
Should indent lines that continue statements by 4
jonnyr
2014/07/23 08:43:04
Done.
| |
| 1269 else | |
| 1270 UMA_HISTOGRAM_CUSTOM_ENUMERATION( | |
| 1271 "Net.HttpRetry.Cause.Subresource", | |
| 1272 -error, | |
| 1273 base::CustomHistogram::ArrayToCustomRanges( | |
| 1274 kAllNetErrorCodes, arraysize(kAllNetErrorCodes))); | |
| 1275 } | |
| 1276 | |
| 1230 int HttpNetworkTransaction::HandleCertificateRequest(int error) { | 1277 int HttpNetworkTransaction::HandleCertificateRequest(int error) { |
| 1231 // There are two paths through which the server can request a certificate | 1278 // There are two paths through which the server can request a certificate |
| 1232 // from us. The first is during the initial handshake, the second is | 1279 // from us. The first is during the initial handshake, the second is |
| 1233 // during SSL renegotiation. | 1280 // during SSL renegotiation. |
| 1234 // | 1281 // |
| 1235 // In both cases, we want to close the connection before proceeding. | 1282 // In both cases, we want to close the connection before proceeding. |
| 1236 // We do this for two reasons: | 1283 // We do this for two reasons: |
| 1237 // First, we don't want to keep the connection to the server hung for a | 1284 // First, we don't want to keep the connection to the server hung for a |
| 1238 // long time while the user selects a certificate. | 1285 // long time while the user selects a certificate. |
| 1239 // Second, even if we did keep the connection open, NSS has a bug where | 1286 // Second, even if we did keep the connection open, NSS has a bug where |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1410 // socket is still connected, receiving the FIN, and sending/reading data | 1457 // socket is still connected, receiving the FIN, and sending/reading data |
| 1411 // on a reused socket. If we receive the FIN between the connectedness | 1458 // on a reused socket. If we receive the FIN between the connectedness |
| 1412 // check and writing/reading from the socket, we may first learn the socket | 1459 // check and writing/reading from the socket, we may first learn the socket |
| 1413 // is disconnected when we get a ERR_SOCKET_NOT_CONNECTED. This will most | 1460 // is disconnected when we get a ERR_SOCKET_NOT_CONNECTED. This will most |
| 1414 // likely happen when trying to retrieve its IP address. | 1461 // likely happen when trying to retrieve its IP address. |
| 1415 // See http://crbug.com/105824 for more details. | 1462 // See http://crbug.com/105824 for more details. |
| 1416 case ERR_SOCKET_NOT_CONNECTED: | 1463 case ERR_SOCKET_NOT_CONNECTED: |
| 1417 // If a socket is closed on its initial request, HttpStreamParser returns | 1464 // If a socket is closed on its initial request, HttpStreamParser returns |
| 1418 // ERR_EMPTY_RESPONSE. This may still be close/reuse race if the socket was | 1465 // ERR_EMPTY_RESPONSE. This may still be close/reuse race if the socket was |
| 1419 // preconnected but failed to be used before the server timed it out. | 1466 // preconnected but failed to be used before the server timed it out. |
| 1420 case ERR_EMPTY_RESPONSE: | 1467 case ERR_EMPTY_RESPONSE: |
|
mmenke
2014/07/22 15:01:41
Note that this is a conservative list of all "expe
jonnyr
2014/07/23 08:43:04
Agreed, ERR_CONTENT_LENGTH_MISMATCH should probabl
| |
| 1421 if (ShouldResendRequest()) { | 1468 if (ShouldResendRequest()) { |
| 1422 net_log_.AddEventWithNetErrorCode( | 1469 net_log_.AddEventWithNetErrorCode( |
| 1423 NetLog::TYPE_HTTP_TRANSACTION_RESTART_AFTER_ERROR, error); | 1470 NetLog::TYPE_HTTP_TRANSACTION_RESTART_AFTER_ERROR, error); |
| 1471 retry_attempt_++; | |
| 1472 LogTransactionRetryMetrics(error); | |
| 1424 ResetConnectionAndRequestForResend(); | 1473 ResetConnectionAndRequestForResend(); |
| 1425 error = OK; | 1474 error = OK; |
| 1426 } | 1475 } |
| 1427 break; | 1476 break; |
| 1428 case ERR_SPDY_PING_FAILED: | 1477 case ERR_SPDY_PING_FAILED: |
| 1429 case ERR_SPDY_SERVER_REFUSED_STREAM: | 1478 case ERR_SPDY_SERVER_REFUSED_STREAM: |
| 1430 case ERR_QUIC_HANDSHAKE_FAILED: | 1479 case ERR_QUIC_HANDSHAKE_FAILED: |
| 1431 net_log_.AddEventWithNetErrorCode( | 1480 net_log_.AddEventWithNetErrorCode( |
| 1432 NetLog::TYPE_HTTP_TRANSACTION_RESTART_AFTER_ERROR, error); | 1481 NetLog::TYPE_HTTP_TRANSACTION_RESTART_AFTER_ERROR, error); |
| 1433 ResetConnectionAndRequestForResend(); | 1482 ResetConnectionAndRequestForResend(); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1455 request_headers_.Clear(); | 1504 request_headers_.Clear(); |
| 1456 response_ = HttpResponseInfo(); | 1505 response_ = HttpResponseInfo(); |
| 1457 establishing_tunnel_ = false; | 1506 establishing_tunnel_ = false; |
| 1458 } | 1507 } |
| 1459 | 1508 |
| 1460 HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const { | 1509 HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const { |
| 1461 return response_.headers.get(); | 1510 return response_.headers.get(); |
| 1462 } | 1511 } |
| 1463 | 1512 |
| 1464 bool HttpNetworkTransaction::ShouldResendRequest() const { | 1513 bool HttpNetworkTransaction::ShouldResendRequest() const { |
| 1465 bool connection_is_proven = stream_->IsConnectionReused(); | 1514 if (request_->method != "GET" || retry_attempt_ > 3) |
|
mmenke
2014/07/22 14:57:41
The 3 should be a constant at the top of this file
mmenke
2014/07/22 14:57:41
Not retrying on POSTs when we received a connectio
jonnyr
2014/07/23 08:43:04
Done.
jonnyr
2014/07/23 08:43:04
Done.
jonnyr
2014/07/23 08:43:04
Done.
jonnyr
2014/07/23 08:43:04
Done.
| |
| 1466 bool has_received_headers = GetResponseHeaders() != NULL; | 1515 return false; |
| 1467 | 1516 |
| 1468 // NOTE: we resend a request only if we reused a keep-alive connection. | 1517 if (headers_valid_) { |
|
mmenke
2014/07/22 14:57:41
Your should have some sort of time check here. If
| |
| 1469 // This automatically prevents an infinite resend loop because we'll run | 1518 // Do not retry automatically if resource is larger than 1 Mb until byte |
| 1470 // out of the cached keep-alive connections eventually. | 1519 // range support is enabled. |
| 1471 if (connection_is_proven && !has_received_headers) | 1520 if (response_.headers->GetContentLength() > 1000000) |
| 1472 return true; | 1521 return false; |
| 1473 return false; | 1522 |
| 1523 // If etag or last-modified is set we can always retry since the responce | |
|
mmenke
2014/07/22 14:57:41
response
jonnyr
2014/07/23 08:43:04
Done.
| |
| 1524 // can be verified. | |
| 1525 if (response_.headers->HasHeader("etag") || | |
| 1526 response_.headers->HasHeader("Last-Modified")) | |
| 1527 return true; | |
|
mmenke
2014/07/22 14:57:41
Use braces when the condition of an if statement t
jonnyr
2014/07/23 08:43:04
Done.
| |
| 1528 | |
| 1529 if (response_.headers->HasHeaderValue("cache-control", "no-cache") || | |
| 1530 response_.headers->HasHeaderValue("pragma", "no-cache")) | |
| 1531 return false; | |
|
mmenke
2014/07/22 14:57:41
Not a big fan of having all this cache logic dupli
jonnyr
2014/07/23 08:43:04
I did not like it either. I also missed must-reval
mmenke
2014/07/23 15:08:40
I'm not at all familiar with caching semantics or
| |
| 1532 | |
| 1533 TimeDelta max_age_value; | |
| 1534 if (response_.headers->GetMaxAgeValue(&max_age_value)) | |
| 1535 return max_age_value.InSeconds() > 60; | |
| 1536 | |
| 1537 // If there is no Date header, then assume that the server response was | |
| 1538 // generated at the time when we received the response, hence do not retry. | |
| 1539 Time date_value; | |
| 1540 if (!response_.headers->GetDateValue(&date_value)) | |
| 1541 return false; | |
| 1542 | |
| 1543 Time expires_value; | |
| 1544 if (response_.headers->GetExpiresValue(&expires_value)) { | |
| 1545 max_age_value = expires_value - date_value; | |
| 1546 if (max_age_value.InSeconds() > 60) | |
| 1547 return true; | |
| 1548 } | |
| 1549 return false; | |
| 1550 } | |
| 1551 return true; | |
| 1474 } | 1552 } |
| 1475 | 1553 |
| 1476 void HttpNetworkTransaction::ResetConnectionAndRequestForResend() { | 1554 void HttpNetworkTransaction::ResetConnectionAndRequestForResend() { |
| 1555 // We need to clear request_headers_ because it contains the real request | |
| 1556 // headers, but we may need to resend the CONNECT request first to recreate | |
| 1557 // the SSL tunnel. | |
| 1558 request_headers_.Clear(); | |
| 1559 headers_valid_ = false; | |
| 1560 | |
| 1561 if (stream_) { | |
| 1562 total_received_bytes_ += stream_->GetTotalReceivedBytes(); | |
| 1563 if (stream_->GetReceivedBodyLength() > offset_) { | |
| 1564 offset_ = stream_->GetReceivedBodyLength(); | |
| 1565 stream_->GetHash(hash_, sizeof(hash_)); | |
| 1566 } | |
| 1567 } | |
| 1568 | |
| 1569 HttpResponseHeaders* headers = GetResponseHeaders(); | |
| 1570 if (offset_ && headers) { | |
| 1571 previous_content_length_ = headers->GetContentLength(); | |
| 1572 headers->EnumerateHeader(NULL, "last-modified", | |
| 1573 &previous_last_modified_); | |
| 1574 if (headers->GetHttpVersion() >= HttpVersion(1, 1)) | |
| 1575 headers->EnumerateHeader(NULL, "etag", &previous_etag_); | |
| 1576 | |
| 1577 // Disable until we have statistics that show that retrying does not | |
| 1578 // result in too many ERR_RETRY_HASH_MISMATCH. | |
| 1579 if (0 && previous_content_length_ && | |
| 1580 headers->HasHeaderValue("Accept-Ranges", "bytes")) { | |
| 1581 // Try resending using a range request if supported. | |
| 1582 request_headers_.SetHeader(HttpRequestHeaders::kRange, | |
| 1583 "bytes=" + base::Uint64ToString(offset_) + "-"); | |
| 1584 if (!previous_last_modified_.empty()) | |
| 1585 request_headers_.SetHeader("If-Unmodified-Since", | |
| 1586 previous_last_modified_); | |
| 1587 if (!previous_etag_.empty()) | |
| 1588 request_headers_.SetHeader("If-Match", previous_etag_); | |
| 1589 } | |
| 1590 } | |
| 1591 | |
| 1592 response_ = HttpResponseInfo(); | |
| 1593 establishing_tunnel_ = false; | |
| 1477 if (stream_.get()) { | 1594 if (stream_.get()) { |
| 1478 stream_->Close(true); | 1595 stream_->Close(true); |
| 1479 stream_.reset(); | 1596 stream_.reset(); |
| 1480 } | 1597 } |
| 1481 | |
| 1482 // We need to clear request_headers_ because it contains the real request | |
| 1483 // headers, but we may need to resend the CONNECT request first to recreate | |
| 1484 // the SSL tunnel. | |
| 1485 request_headers_.Clear(); | |
| 1486 next_state_ = STATE_CREATE_STREAM; // Resend the request. | 1598 next_state_ = STATE_CREATE_STREAM; // Resend the request. |
| 1487 } | 1599 } |
| 1488 | 1600 |
| 1489 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const { | 1601 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const { |
| 1490 return !is_https_request() && | 1602 return !is_https_request() && |
| 1491 (proxy_info_.is_https() || proxy_info_.is_http()); | 1603 (proxy_info_.is_https() || proxy_info_.is_http()); |
| 1492 } | 1604 } |
| 1493 | 1605 |
| 1494 bool HttpNetworkTransaction::ShouldApplyServerAuth() const { | 1606 bool HttpNetworkTransaction::ShouldApplyServerAuth() const { |
| 1495 return !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA); | 1607 return !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1584 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, | 1696 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, |
| 1585 state); | 1697 state); |
| 1586 break; | 1698 break; |
| 1587 } | 1699 } |
| 1588 return description; | 1700 return description; |
| 1589 } | 1701 } |
| 1590 | 1702 |
| 1591 #undef STATE_CASE | 1703 #undef STATE_CASE |
| 1592 | 1704 |
| 1593 } // namespace net | 1705 } // namespace net |
| OLD | NEW |