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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 #include "net/spdy/chromium/spdy_session_pool.h" | 63 #include "net/spdy/chromium/spdy_session_pool.h" |
64 #include "net/ssl/ssl_cert_request_info.h" | 64 #include "net/ssl/ssl_cert_request_info.h" |
65 #include "net/ssl/ssl_connection_status_flags.h" | 65 #include "net/ssl/ssl_connection_status_flags.h" |
66 #include "net/ssl/ssl_private_key.h" | 66 #include "net/ssl/ssl_private_key.h" |
67 #include "net/ssl/token_binding.h" | 67 #include "net/ssl/token_binding.h" |
68 #include "url/gurl.h" | 68 #include "url/gurl.h" |
69 #include "url/url_canon.h" | 69 #include "url/url_canon.h" |
70 | 70 |
71 namespace net { | 71 namespace net { |
72 | 72 |
73 namespace { | |
74 | |
75 std::unique_ptr<base::Value> NetLogSSLCipherFallbackCallback( | |
76 const GURL* url, | |
77 int net_error, | |
78 NetLogCaptureMode /* capture_mode */) { | |
79 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | |
80 dict->SetString("host_and_port", GetHostAndPort(*url)); | |
81 dict->SetInteger("net_error", net_error); | |
82 return std::move(dict); | |
83 } | |
84 | |
85 } // namespace | |
86 | |
87 //----------------------------------------------------------------------------- | |
88 | |
89 HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority, | 73 HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority, |
90 HttpNetworkSession* session) | 74 HttpNetworkSession* session) |
91 : pending_auth_target_(HttpAuth::AUTH_NONE), | 75 : pending_auth_target_(HttpAuth::AUTH_NONE), |
92 io_callback_(base::Bind(&HttpNetworkTransaction::OnIOComplete, | 76 io_callback_(base::Bind(&HttpNetworkTransaction::OnIOComplete, |
93 base::Unretained(this))), | 77 base::Unretained(this))), |
94 session_(session), | 78 session_(session), |
95 request_(NULL), | 79 request_(NULL), |
96 priority_(priority), | 80 priority_(priority), |
97 headers_valid_(false), | 81 headers_valid_(false), |
98 request_headers_(), | 82 request_headers_(), |
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
874 } | 858 } |
875 | 859 |
876 int HttpNetworkTransaction::DoCreateStreamComplete(int result) { | 860 int HttpNetworkTransaction::DoCreateStreamComplete(int result) { |
877 // If |result| is ERR_HTTPS_PROXY_TUNNEL_RESPONSE, then | 861 // If |result| is ERR_HTTPS_PROXY_TUNNEL_RESPONSE, then |
878 // DoCreateStreamComplete is being called from OnHttpsProxyTunnelResponse, | 862 // DoCreateStreamComplete is being called from OnHttpsProxyTunnelResponse, |
879 // which resets the stream request first. Therefore, we have to grab the | 863 // which resets the stream request first. Therefore, we have to grab the |
880 // connection attempts in *that* function instead of here in that case. | 864 // connection attempts in *that* function instead of here in that case. |
881 if (result != ERR_HTTPS_PROXY_TUNNEL_RESPONSE) | 865 if (result != ERR_HTTPS_PROXY_TUNNEL_RESPONSE) |
882 CopyConnectionAttemptsFromStreamRequest(); | 866 CopyConnectionAttemptsFromStreamRequest(); |
883 | 867 |
884 if (request_->url.SchemeIsCryptographic()) | |
885 RecordSSLFallbackMetrics(result); | |
886 | |
887 if (result == OK) { | 868 if (result == OK) { |
888 next_state_ = STATE_INIT_STREAM; | 869 next_state_ = STATE_INIT_STREAM; |
889 DCHECK(stream_.get()); | 870 DCHECK(stream_.get()); |
890 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 871 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
891 result = HandleCertificateRequest(result); | 872 result = HandleCertificateRequest(result); |
892 } else if (result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { | 873 } else if (result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { |
893 // Return OK and let the caller read the proxy's error page | 874 // Return OK and let the caller read the proxy's error page |
894 next_state_ = STATE_NONE; | 875 next_state_ = STATE_NONE; |
895 return OK; | 876 return OK; |
896 } else if (result == ERR_HTTP_1_1_REQUIRED || | 877 } else if (result == ERR_HTTP_1_1_REQUIRED || |
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1505 } | 1486 } |
1506 } | 1487 } |
1507 | 1488 |
1508 // TODO(rch): This does not correctly handle errors when an SSL proxy is | 1489 // TODO(rch): This does not correctly handle errors when an SSL proxy is |
1509 // being used, as all of the errors are handled as if they were generated | 1490 // being used, as all of the errors are handled as if they were generated |
1510 // by the endpoint host, request_->url, rather than considering if they were | 1491 // by the endpoint host, request_->url, rather than considering if they were |
1511 // generated by the SSL proxy. http://crbug.com/69329 | 1492 // generated by the SSL proxy. http://crbug.com/69329 |
1512 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) { | 1493 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) { |
1513 DCHECK(request_); | 1494 DCHECK(request_); |
1514 HandleClientAuthError(error); | 1495 HandleClientAuthError(error); |
1515 | |
1516 // Accept deprecated cipher suites, but only on a fallback. This makes UMA | |
1517 // reflect servers require a deprecated cipher rather than merely prefer | |
1518 // it. This, however, has no security benefit until the ciphers are actually | |
1519 // removed. | |
1520 if (!server_ssl_config_.deprecated_cipher_suites_enabled && | |
1521 (error == ERR_SSL_VERSION_OR_CIPHER_MISMATCH || | |
1522 error == ERR_CONNECTION_CLOSED || error == ERR_CONNECTION_RESET)) { | |
1523 net_log_.AddEvent( | |
1524 NetLogEventType::SSL_CIPHER_FALLBACK, | |
1525 base::Bind(&NetLogSSLCipherFallbackCallback, &request_->url, error)); | |
1526 server_ssl_config_.deprecated_cipher_suites_enabled = true; | |
1527 ResetConnectionAndRequestForResend(); | |
1528 return OK; | |
1529 } | |
1530 | |
1531 return error; | 1496 return error; |
1532 } | 1497 } |
1533 | 1498 |
1534 // This method determines whether it is safe to resend the request after an | 1499 // This method determines whether it is safe to resend the request after an |
1535 // IO error. It can only be called in response to request header or body | 1500 // IO error. It can only be called in response to request header or body |
1536 // write errors or response header read errors. It should not be used in | 1501 // write errors or response header read errors. It should not be used in |
1537 // other cases, such as a Connect error. | 1502 // other cases, such as a Connect error. |
1538 int HttpNetworkTransaction::HandleIOError(int error) { | 1503 int HttpNetworkTransaction::HandleIOError(int error) { |
1539 // Because the peer may request renegotiation with client authentication at | 1504 // Because the peer may request renegotiation with client authentication at |
1540 // any time, check and handle client authentication errors. | 1505 // any time, check and handle client authentication errors. |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1634 provided_token_binding_key_.reset(); | 1599 provided_token_binding_key_.reset(); |
1635 referred_token_binding_key_.reset(); | 1600 referred_token_binding_key_.reset(); |
1636 } | 1601 } |
1637 | 1602 |
1638 void HttpNetworkTransaction::CacheNetErrorDetailsAndResetStream() { | 1603 void HttpNetworkTransaction::CacheNetErrorDetailsAndResetStream() { |
1639 if (stream_) | 1604 if (stream_) |
1640 stream_->PopulateNetErrorDetails(&net_error_details_); | 1605 stream_->PopulateNetErrorDetails(&net_error_details_); |
1641 stream_.reset(); | 1606 stream_.reset(); |
1642 } | 1607 } |
1643 | 1608 |
1644 void HttpNetworkTransaction::RecordSSLFallbackMetrics(int result) { | |
1645 if (result != OK) | |
1646 return; | |
1647 | |
1648 UMA_HISTOGRAM_BOOLEAN("Net.ConnectionUsedSSLDeprecatedCipherFallback2", | |
1649 server_ssl_config_.deprecated_cipher_suites_enabled); | |
1650 } | |
1651 | |
1652 HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const { | 1609 HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const { |
1653 return response_.headers.get(); | 1610 return response_.headers.get(); |
1654 } | 1611 } |
1655 | 1612 |
1656 bool HttpNetworkTransaction::ShouldResendRequest() const { | 1613 bool HttpNetworkTransaction::ShouldResendRequest() const { |
1657 bool connection_is_proven = stream_->IsConnectionReused(); | 1614 bool connection_is_proven = stream_->IsConnectionReused(); |
1658 bool has_received_headers = GetResponseHeaders() != NULL; | 1615 bool has_received_headers = GetResponseHeaders() != NULL; |
1659 | 1616 |
1660 // NOTE: we resend a request only if we reused a keep-alive connection. | 1617 // NOTE: we resend a request only if we reused a keep-alive connection. |
1661 // This automatically prevents an infinite resend loop because we'll run | 1618 // This automatically prevents an infinite resend loop because we'll run |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1815 if (headers->IsRedirect(nullptr)) { | 1772 if (headers->IsRedirect(nullptr)) { |
1816 UMA_HISTOGRAM_BOOLEAN("Net.RedirectWithUnadvertisedContentEncoding", | 1773 UMA_HISTOGRAM_BOOLEAN("Net.RedirectWithUnadvertisedContentEncoding", |
1817 !result); | 1774 !result); |
1818 return true; | 1775 return true; |
1819 } | 1776 } |
1820 | 1777 |
1821 return result; | 1778 return result; |
1822 } | 1779 } |
1823 | 1780 |
1824 } // namespace net | 1781 } // namespace net |
OLD | NEW |