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 <memory> | 7 #include <memory> |
8 #include <set> | 8 #include <set> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 #include "net/http/http_request_info.h" | 45 #include "net/http/http_request_info.h" |
46 #include "net/http/http_response_headers.h" | 46 #include "net/http/http_response_headers.h" |
47 #include "net/http/http_response_info.h" | 47 #include "net/http/http_response_info.h" |
48 #include "net/http/http_server_properties.h" | 48 #include "net/http/http_server_properties.h" |
49 #include "net/http/http_status_code.h" | 49 #include "net/http/http_status_code.h" |
50 #include "net/http/http_stream.h" | 50 #include "net/http/http_stream.h" |
51 #include "net/http/http_stream_factory.h" | 51 #include "net/http/http_stream_factory.h" |
52 #include "net/http/http_util.h" | 52 #include "net/http/http_util.h" |
53 #include "net/http/transport_security_state.h" | 53 #include "net/http/transport_security_state.h" |
54 #include "net/http/url_security_manager.h" | 54 #include "net/http/url_security_manager.h" |
| 55 #include "net/log/net_log_event_type.h" |
55 #include "net/socket/client_socket_factory.h" | 56 #include "net/socket/client_socket_factory.h" |
56 #include "net/socket/socks_client_socket_pool.h" | 57 #include "net/socket/socks_client_socket_pool.h" |
57 #include "net/socket/ssl_client_socket.h" | 58 #include "net/socket/ssl_client_socket.h" |
58 #include "net/socket/ssl_client_socket_pool.h" | 59 #include "net/socket/ssl_client_socket_pool.h" |
59 #include "net/socket/transport_client_socket_pool.h" | 60 #include "net/socket/transport_client_socket_pool.h" |
60 #include "net/spdy/spdy_http_stream.h" | 61 #include "net/spdy/spdy_http_stream.h" |
61 #include "net/spdy/spdy_session.h" | 62 #include "net/spdy/spdy_session.h" |
62 #include "net/spdy/spdy_session_pool.h" | 63 #include "net/spdy/spdy_session_pool.h" |
63 #include "net/ssl/ssl_cert_request_info.h" | 64 #include "net/ssl/ssl_cert_request_info.h" |
64 #include "net/ssl/ssl_connection_status_flags.h" | 65 #include "net/ssl/ssl_connection_status_flags.h" |
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 break; | 693 break; |
693 case STATE_INIT_REQUEST_BODY: | 694 case STATE_INIT_REQUEST_BODY: |
694 DCHECK_EQ(OK, rv); | 695 DCHECK_EQ(OK, rv); |
695 rv = DoInitRequestBody(); | 696 rv = DoInitRequestBody(); |
696 break; | 697 break; |
697 case STATE_INIT_REQUEST_BODY_COMPLETE: | 698 case STATE_INIT_REQUEST_BODY_COMPLETE: |
698 rv = DoInitRequestBodyComplete(rv); | 699 rv = DoInitRequestBodyComplete(rv); |
699 break; | 700 break; |
700 case STATE_BUILD_REQUEST: | 701 case STATE_BUILD_REQUEST: |
701 DCHECK_EQ(OK, rv); | 702 DCHECK_EQ(OK, rv); |
702 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST); | 703 net_log_.BeginEvent(NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST); |
703 rv = DoBuildRequest(); | 704 rv = DoBuildRequest(); |
704 break; | 705 break; |
705 case STATE_BUILD_REQUEST_COMPLETE: | 706 case STATE_BUILD_REQUEST_COMPLETE: |
706 rv = DoBuildRequestComplete(rv); | 707 rv = DoBuildRequestComplete(rv); |
707 break; | 708 break; |
708 case STATE_SEND_REQUEST: | 709 case STATE_SEND_REQUEST: |
709 DCHECK_EQ(OK, rv); | 710 DCHECK_EQ(OK, rv); |
710 rv = DoSendRequest(); | 711 rv = DoSendRequest(); |
711 break; | 712 break; |
712 case STATE_SEND_REQUEST_COMPLETE: | 713 case STATE_SEND_REQUEST_COMPLETE: |
713 rv = DoSendRequestComplete(rv); | 714 rv = DoSendRequestComplete(rv); |
714 net_log_.EndEventWithNetErrorCode( | 715 net_log_.EndEventWithNetErrorCode( |
715 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST, rv); | 716 NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST, rv); |
716 break; | 717 break; |
717 case STATE_READ_HEADERS: | 718 case STATE_READ_HEADERS: |
718 DCHECK_EQ(OK, rv); | 719 DCHECK_EQ(OK, rv); |
719 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS); | 720 net_log_.BeginEvent(NetLogEventType::HTTP_TRANSACTION_READ_HEADERS); |
720 rv = DoReadHeaders(); | 721 rv = DoReadHeaders(); |
721 break; | 722 break; |
722 case STATE_READ_HEADERS_COMPLETE: | 723 case STATE_READ_HEADERS_COMPLETE: |
723 rv = DoReadHeadersComplete(rv); | 724 rv = DoReadHeadersComplete(rv); |
724 net_log_.EndEventWithNetErrorCode( | 725 net_log_.EndEventWithNetErrorCode( |
725 NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS, rv); | 726 NetLogEventType::HTTP_TRANSACTION_READ_HEADERS, rv); |
726 break; | 727 break; |
727 case STATE_READ_BODY: | 728 case STATE_READ_BODY: |
728 DCHECK_EQ(OK, rv); | 729 DCHECK_EQ(OK, rv); |
729 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_READ_BODY); | 730 net_log_.BeginEvent(NetLogEventType::HTTP_TRANSACTION_READ_BODY); |
730 rv = DoReadBody(); | 731 rv = DoReadBody(); |
731 break; | 732 break; |
732 case STATE_READ_BODY_COMPLETE: | 733 case STATE_READ_BODY_COMPLETE: |
733 rv = DoReadBodyComplete(rv); | 734 rv = DoReadBodyComplete(rv); |
734 net_log_.EndEventWithNetErrorCode( | 735 net_log_.EndEventWithNetErrorCode( |
735 NetLog::TYPE_HTTP_TRANSACTION_READ_BODY, rv); | 736 NetLogEventType::HTTP_TRANSACTION_READ_BODY, rv); |
736 break; | 737 break; |
737 case STATE_DRAIN_BODY_FOR_AUTH_RESTART: | 738 case STATE_DRAIN_BODY_FOR_AUTH_RESTART: |
738 DCHECK_EQ(OK, rv); | 739 DCHECK_EQ(OK, rv); |
739 net_log_.BeginEvent( | 740 net_log_.BeginEvent( |
740 NetLog::TYPE_HTTP_TRANSACTION_DRAIN_BODY_FOR_AUTH_RESTART); | 741 NetLogEventType::HTTP_TRANSACTION_DRAIN_BODY_FOR_AUTH_RESTART); |
741 rv = DoDrainBodyForAuthRestart(); | 742 rv = DoDrainBodyForAuthRestart(); |
742 break; | 743 break; |
743 case STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE: | 744 case STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE: |
744 rv = DoDrainBodyForAuthRestartComplete(rv); | 745 rv = DoDrainBodyForAuthRestartComplete(rv); |
745 net_log_.EndEventWithNetErrorCode( | 746 net_log_.EndEventWithNetErrorCode( |
746 NetLog::TYPE_HTTP_TRANSACTION_DRAIN_BODY_FOR_AUTH_RESTART, rv); | 747 NetLogEventType::HTTP_TRANSACTION_DRAIN_BODY_FOR_AUTH_RESTART, rv); |
747 break; | 748 break; |
748 default: | 749 default: |
749 NOTREACHED() << "bad state"; | 750 NOTREACHED() << "bad state"; |
750 rv = ERR_FAILED; | 751 rv = ERR_FAILED; |
751 break; | 752 break; |
752 } | 753 } |
753 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 754 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
754 | 755 |
755 return rv; | 756 return rv; |
756 } | 757 } |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
907 if (rv == OK) | 908 if (rv == OK) |
908 next_state_ = STATE_GET_PROVIDED_TOKEN_BINDING_KEY; | 909 next_state_ = STATE_GET_PROVIDED_TOKEN_BINDING_KEY; |
909 return rv; | 910 return rv; |
910 } | 911 } |
911 | 912 |
912 int HttpNetworkTransaction::DoGetProvidedTokenBindingKey() { | 913 int HttpNetworkTransaction::DoGetProvidedTokenBindingKey() { |
913 next_state_ = STATE_GET_PROVIDED_TOKEN_BINDING_KEY_COMPLETE; | 914 next_state_ = STATE_GET_PROVIDED_TOKEN_BINDING_KEY_COMPLETE; |
914 if (!IsTokenBindingEnabled()) | 915 if (!IsTokenBindingEnabled()) |
915 return OK; | 916 return OK; |
916 | 917 |
917 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_GET_TOKEN_BINDING_KEY); | 918 net_log_.BeginEvent(NetLogEventType::HTTP_TRANSACTION_GET_TOKEN_BINDING_KEY); |
918 ChannelIDService* channel_id_service = session_->params().channel_id_service; | 919 ChannelIDService* channel_id_service = session_->params().channel_id_service; |
919 return channel_id_service->GetOrCreateChannelID( | 920 return channel_id_service->GetOrCreateChannelID( |
920 request_->url.host(), &provided_token_binding_key_, io_callback_, | 921 request_->url.host(), &provided_token_binding_key_, io_callback_, |
921 &token_binding_request_); | 922 &token_binding_request_); |
922 } | 923 } |
923 | 924 |
924 int HttpNetworkTransaction::DoGetProvidedTokenBindingKeyComplete(int rv) { | 925 int HttpNetworkTransaction::DoGetProvidedTokenBindingKeyComplete(int rv) { |
925 DCHECK_NE(ERR_IO_PENDING, rv); | 926 DCHECK_NE(ERR_IO_PENDING, rv); |
926 if (IsTokenBindingEnabled()) { | 927 if (IsTokenBindingEnabled()) { |
927 net_log_.EndEventWithNetErrorCode( | 928 net_log_.EndEventWithNetErrorCode( |
928 NetLog::TYPE_HTTP_TRANSACTION_GET_TOKEN_BINDING_KEY, rv); | 929 NetLogEventType::HTTP_TRANSACTION_GET_TOKEN_BINDING_KEY, rv); |
929 } | 930 } |
930 | 931 |
931 if (rv == OK) | 932 if (rv == OK) |
932 next_state_ = STATE_GET_REFERRED_TOKEN_BINDING_KEY; | 933 next_state_ = STATE_GET_REFERRED_TOKEN_BINDING_KEY; |
933 return rv; | 934 return rv; |
934 } | 935 } |
935 | 936 |
936 int HttpNetworkTransaction::DoGetReferredTokenBindingKey() { | 937 int HttpNetworkTransaction::DoGetReferredTokenBindingKey() { |
937 next_state_ = STATE_GET_REFERRED_TOKEN_BINDING_KEY_COMPLETE; | 938 next_state_ = STATE_GET_REFERRED_TOKEN_BINDING_KEY_COMPLETE; |
938 if (!IsTokenBindingEnabled() || request_->token_binding_referrer.empty()) | 939 if (!IsTokenBindingEnabled() || request_->token_binding_referrer.empty()) |
939 return OK; | 940 return OK; |
940 | 941 |
941 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_GET_TOKEN_BINDING_KEY); | 942 net_log_.BeginEvent(NetLogEventType::HTTP_TRANSACTION_GET_TOKEN_BINDING_KEY); |
942 ChannelIDService* channel_id_service = session_->params().channel_id_service; | 943 ChannelIDService* channel_id_service = session_->params().channel_id_service; |
943 return channel_id_service->GetOrCreateChannelID( | 944 return channel_id_service->GetOrCreateChannelID( |
944 request_->token_binding_referrer, &referred_token_binding_key_, | 945 request_->token_binding_referrer, &referred_token_binding_key_, |
945 io_callback_, &token_binding_request_); | 946 io_callback_, &token_binding_request_); |
946 } | 947 } |
947 | 948 |
948 int HttpNetworkTransaction::DoGetReferredTokenBindingKeyComplete(int rv) { | 949 int HttpNetworkTransaction::DoGetReferredTokenBindingKeyComplete(int rv) { |
949 DCHECK_NE(ERR_IO_PENDING, rv); | 950 DCHECK_NE(ERR_IO_PENDING, rv); |
950 if (IsTokenBindingEnabled() && !request_->token_binding_referrer.empty()) { | 951 if (IsTokenBindingEnabled() && !request_->token_binding_referrer.empty()) { |
951 net_log_.EndEventWithNetErrorCode( | 952 net_log_.EndEventWithNetErrorCode( |
952 NetLog::TYPE_HTTP_TRANSACTION_GET_TOKEN_BINDING_KEY, rv); | 953 NetLogEventType::HTTP_TRANSACTION_GET_TOKEN_BINDING_KEY, rv); |
953 } | 954 } |
954 if (rv == OK) | 955 if (rv == OK) |
955 next_state_ = STATE_INIT_REQUEST_BODY; | 956 next_state_ = STATE_INIT_REQUEST_BODY; |
956 return rv; | 957 return rv; |
957 } | 958 } |
958 | 959 |
959 int HttpNetworkTransaction::BuildRequestHeaders( | 960 int HttpNetworkTransaction::BuildRequestHeaders( |
960 bool using_http_proxy_without_tunnel) { | 961 bool using_http_proxy_without_tunnel) { |
961 request_headers_.SetHeader(HttpRequestHeaders::kHost, | 962 request_headers_.SetHeader(HttpRequestHeaders::kHost, |
962 GetHostAndOptionalPort(request_->url)); | 963 GetHostAndOptionalPort(request_->url)); |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1175 return HandleIOError(result); | 1176 return HandleIOError(result); |
1176 | 1177 |
1177 DCHECK(response_.headers.get()); | 1178 DCHECK(response_.headers.get()); |
1178 | 1179 |
1179 // On a 408 response from the server ("Request Timeout") on a stale socket, | 1180 // On a 408 response from the server ("Request Timeout") on a stale socket, |
1180 // retry the request. | 1181 // retry the request. |
1181 // Headers can be NULL because of http://crbug.com/384554. | 1182 // Headers can be NULL because of http://crbug.com/384554. |
1182 if (response_.headers.get() && response_.headers->response_code() == 408 && | 1183 if (response_.headers.get() && response_.headers->response_code() == 408 && |
1183 stream_->IsConnectionReused()) { | 1184 stream_->IsConnectionReused()) { |
1184 net_log_.AddEventWithNetErrorCode( | 1185 net_log_.AddEventWithNetErrorCode( |
1185 NetLog::TYPE_HTTP_TRANSACTION_RESTART_AFTER_ERROR, | 1186 NetLogEventType::HTTP_TRANSACTION_RESTART_AFTER_ERROR, |
1186 response_.headers->response_code()); | 1187 response_.headers->response_code()); |
1187 // This will close the socket - it would be weird to try and reuse it, even | 1188 // This will close the socket - it would be weird to try and reuse it, even |
1188 // if the server doesn't actually close it. | 1189 // if the server doesn't actually close it. |
1189 ResetConnectionAndRequestForResend(); | 1190 ResetConnectionAndRequestForResend(); |
1190 return OK; | 1191 return OK; |
1191 } | 1192 } |
1192 | 1193 |
1193 // Like Net.HttpResponseCode, but only for MAIN_FRAME loads. | 1194 // Like Net.HttpResponseCode, but only for MAIN_FRAME loads. |
1194 if (request_->load_flags & LOAD_MAIN_FRAME_DEPRECATED) { | 1195 if (request_->load_flags & LOAD_MAIN_FRAME_DEPRECATED) { |
1195 const int response_code = response_.headers->response_code(); | 1196 const int response_code = response_.headers->response_code(); |
1196 UMA_HISTOGRAM_ENUMERATION( | 1197 UMA_HISTOGRAM_ENUMERATION( |
1197 "Net.HttpResponseCode_Nxx_MainFrame", response_code/100, 10); | 1198 "Net.HttpResponseCode_Nxx_MainFrame", response_code/100, 10); |
1198 } | 1199 } |
1199 | 1200 |
1200 net_log_.AddEvent( | 1201 net_log_.AddEvent( |
1201 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS, | 1202 NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS, |
1202 base::Bind(&HttpResponseHeaders::NetLogCallback, response_.headers)); | 1203 base::Bind(&HttpResponseHeaders::NetLogCallback, response_.headers)); |
1203 | 1204 |
1204 if (response_.headers->GetHttpVersion() < HttpVersion(1, 0)) { | 1205 if (response_.headers->GetHttpVersion() < HttpVersion(1, 0)) { |
1205 // HTTP/0.9 doesn't support the PUT method, so lack of response headers | 1206 // HTTP/0.9 doesn't support the PUT method, so lack of response headers |
1206 // indicates a buggy server. See: | 1207 // indicates a buggy server. See: |
1207 // https://bugzilla.mozilla.org/show_bug.cgi?id=193921 | 1208 // https://bugzilla.mozilla.org/show_bug.cgi?id=193921 |
1208 if (request_->method == "PUT") | 1209 if (request_->method == "PUT") |
1209 return ERR_METHOD_NOT_SUPPORTED; | 1210 return ERR_METHOD_NOT_SUPPORTED; |
1210 } | 1211 } |
1211 | 1212 |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1415 HandleClientAuthError(error); | 1416 HandleClientAuthError(error); |
1416 | 1417 |
1417 // Accept deprecated cipher suites, but only on a fallback. This makes UMA | 1418 // Accept deprecated cipher suites, but only on a fallback. This makes UMA |
1418 // reflect servers require a deprecated cipher rather than merely prefer | 1419 // reflect servers require a deprecated cipher rather than merely prefer |
1419 // it. This, however, has no security benefit until the ciphers are actually | 1420 // it. This, however, has no security benefit until the ciphers are actually |
1420 // removed. | 1421 // removed. |
1421 if (!server_ssl_config_.deprecated_cipher_suites_enabled && | 1422 if (!server_ssl_config_.deprecated_cipher_suites_enabled && |
1422 (error == ERR_SSL_VERSION_OR_CIPHER_MISMATCH || | 1423 (error == ERR_SSL_VERSION_OR_CIPHER_MISMATCH || |
1423 error == ERR_CONNECTION_CLOSED || error == ERR_CONNECTION_RESET)) { | 1424 error == ERR_CONNECTION_CLOSED || error == ERR_CONNECTION_RESET)) { |
1424 net_log_.AddEvent( | 1425 net_log_.AddEvent( |
1425 NetLog::TYPE_SSL_CIPHER_FALLBACK, | 1426 NetLogEventType::SSL_CIPHER_FALLBACK, |
1426 base::Bind(&NetLogSSLCipherFallbackCallback, &request_->url, error)); | 1427 base::Bind(&NetLogSSLCipherFallbackCallback, &request_->url, error)); |
1427 server_ssl_config_.deprecated_cipher_suites_enabled = true; | 1428 server_ssl_config_.deprecated_cipher_suites_enabled = true; |
1428 ResetConnectionAndRequestForResend(); | 1429 ResetConnectionAndRequestForResend(); |
1429 return OK; | 1430 return OK; |
1430 } | 1431 } |
1431 | 1432 |
1432 return error; | 1433 return error; |
1433 } | 1434 } |
1434 | 1435 |
1435 // This method determines whether it is safe to resend the request after an | 1436 // This method determines whether it is safe to resend the request after an |
(...skipping 20 matching lines...) Expand all Loading... |
1456 // is disconnected when we get a ERR_SOCKET_NOT_CONNECTED. This will most | 1457 // is disconnected when we get a ERR_SOCKET_NOT_CONNECTED. This will most |
1457 // likely happen when trying to retrieve its IP address. | 1458 // likely happen when trying to retrieve its IP address. |
1458 // See http://crbug.com/105824 for more details. | 1459 // See http://crbug.com/105824 for more details. |
1459 case ERR_SOCKET_NOT_CONNECTED: | 1460 case ERR_SOCKET_NOT_CONNECTED: |
1460 // If a socket is closed on its initial request, HttpStreamParser returns | 1461 // If a socket is closed on its initial request, HttpStreamParser returns |
1461 // ERR_EMPTY_RESPONSE. This may still be close/reuse race if the socket was | 1462 // ERR_EMPTY_RESPONSE. This may still be close/reuse race if the socket was |
1462 // preconnected but failed to be used before the server timed it out. | 1463 // preconnected but failed to be used before the server timed it out. |
1463 case ERR_EMPTY_RESPONSE: | 1464 case ERR_EMPTY_RESPONSE: |
1464 if (ShouldResendRequest()) { | 1465 if (ShouldResendRequest()) { |
1465 net_log_.AddEventWithNetErrorCode( | 1466 net_log_.AddEventWithNetErrorCode( |
1466 NetLog::TYPE_HTTP_TRANSACTION_RESTART_AFTER_ERROR, error); | 1467 NetLogEventType::HTTP_TRANSACTION_RESTART_AFTER_ERROR, error); |
1467 ResetConnectionAndRequestForResend(); | 1468 ResetConnectionAndRequestForResend(); |
1468 error = OK; | 1469 error = OK; |
1469 } | 1470 } |
1470 break; | 1471 break; |
1471 case ERR_SPDY_PING_FAILED: | 1472 case ERR_SPDY_PING_FAILED: |
1472 case ERR_SPDY_SERVER_REFUSED_STREAM: | 1473 case ERR_SPDY_SERVER_REFUSED_STREAM: |
1473 case ERR_QUIC_HANDSHAKE_FAILED: | 1474 case ERR_QUIC_HANDSHAKE_FAILED: |
1474 net_log_.AddEventWithNetErrorCode( | 1475 net_log_.AddEventWithNetErrorCode( |
1475 NetLog::TYPE_HTTP_TRANSACTION_RESTART_AFTER_ERROR, error); | 1476 NetLogEventType::HTTP_TRANSACTION_RESTART_AFTER_ERROR, error); |
1476 ResetConnectionAndRequestForResend(); | 1477 ResetConnectionAndRequestForResend(); |
1477 error = OK; | 1478 error = OK; |
1478 break; | 1479 break; |
1479 } | 1480 } |
1480 return error; | 1481 return error; |
1481 } | 1482 } |
1482 | 1483 |
1483 void HttpNetworkTransaction::ResetStateForRestart() { | 1484 void HttpNetworkTransaction::ResetStateForRestart() { |
1484 ResetStateForAuthRestart(); | 1485 ResetStateForAuthRestart(); |
1485 if (stream_) { | 1486 if (stream_) { |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1669 DCHECK(stream_request_); | 1670 DCHECK(stream_request_); |
1670 | 1671 |
1671 // Since the transaction can restart with auth credentials, it may create a | 1672 // Since the transaction can restart with auth credentials, it may create a |
1672 // stream more than once. Accumulate all of the connection attempts across | 1673 // stream more than once. Accumulate all of the connection attempts across |
1673 // those streams by appending them to the vector: | 1674 // those streams by appending them to the vector: |
1674 for (const auto& attempt : stream_request_->connection_attempts()) | 1675 for (const auto& attempt : stream_request_->connection_attempts()) |
1675 connection_attempts_.push_back(attempt); | 1676 connection_attempts_.push_back(attempt); |
1676 } | 1677 } |
1677 | 1678 |
1678 } // namespace net | 1679 } // namespace net |
OLD | NEW |