| 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 |