| 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 #include "net/spdy/spdy_session_pool.h" | 62 #include "net/spdy/spdy_session_pool.h" |
| 63 #include "net/ssl/ssl_cert_request_info.h" | 63 #include "net/ssl/ssl_cert_request_info.h" |
| 64 #include "net/ssl/ssl_connection_status_flags.h" | 64 #include "net/ssl/ssl_connection_status_flags.h" |
| 65 #include "net/ssl/ssl_private_key.h" | 65 #include "net/ssl/ssl_private_key.h" |
| 66 #include "net/ssl/token_binding.h" | 66 #include "net/ssl/token_binding.h" |
| 67 #include "url/gurl.h" | 67 #include "url/gurl.h" |
| 68 #include "url/url_canon.h" | 68 #include "url/url_canon.h" |
| 69 | 69 |
| 70 namespace net { | 70 namespace net { |
| 71 | 71 |
| 72 namespace { | |
| 73 | |
| 74 std::unique_ptr<base::Value> NetLogSSLCipherFallbackCallback( | |
| 75 const GURL* url, | |
| 76 int net_error, | |
| 77 NetLogCaptureMode /* capture_mode */) { | |
| 78 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | |
| 79 dict->SetString("host_and_port", GetHostAndPort(*url)); | |
| 80 dict->SetInteger("net_error", net_error); | |
| 81 return std::move(dict); | |
| 82 } | |
| 83 | |
| 84 } // namespace | |
| 85 | |
| 86 //----------------------------------------------------------------------------- | 72 //----------------------------------------------------------------------------- |
| 87 | 73 |
| 88 HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority, | 74 HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority, |
| 89 HttpNetworkSession* session) | 75 HttpNetworkSession* session) |
| 90 : pending_auth_target_(HttpAuth::AUTH_NONE), | 76 : pending_auth_target_(HttpAuth::AUTH_NONE), |
| 91 io_callback_(base::Bind(&HttpNetworkTransaction::OnIOComplete, | 77 io_callback_(base::Bind(&HttpNetworkTransaction::OnIOComplete, |
| 92 base::Unretained(this))), | 78 base::Unretained(this))), |
| 93 session_(session), | 79 session_(session), |
| 94 request_(NULL), | 80 request_(NULL), |
| 95 priority_(priority), | 81 priority_(priority), |
| (...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 864 } | 850 } |
| 865 | 851 |
| 866 int HttpNetworkTransaction::DoCreateStreamComplete(int result) { | 852 int HttpNetworkTransaction::DoCreateStreamComplete(int result) { |
| 867 // If |result| is ERR_HTTPS_PROXY_TUNNEL_RESPONSE, then | 853 // If |result| is ERR_HTTPS_PROXY_TUNNEL_RESPONSE, then |
| 868 // DoCreateStreamComplete is being called from OnHttpsProxyTunnelResponse, | 854 // DoCreateStreamComplete is being called from OnHttpsProxyTunnelResponse, |
| 869 // which resets the stream request first. Therefore, we have to grab the | 855 // which resets the stream request first. Therefore, we have to grab the |
| 870 // connection attempts in *that* function instead of here in that case. | 856 // connection attempts in *that* function instead of here in that case. |
| 871 if (result != ERR_HTTPS_PROXY_TUNNEL_RESPONSE) | 857 if (result != ERR_HTTPS_PROXY_TUNNEL_RESPONSE) |
| 872 CopyConnectionAttemptsFromStreamRequest(); | 858 CopyConnectionAttemptsFromStreamRequest(); |
| 873 | 859 |
| 874 if (request_->url.SchemeIsCryptographic()) | |
| 875 RecordSSLFallbackMetrics(result); | |
| 876 | |
| 877 if (result == OK) { | 860 if (result == OK) { |
| 878 next_state_ = STATE_INIT_STREAM; | 861 next_state_ = STATE_INIT_STREAM; |
| 879 DCHECK(stream_.get()); | 862 DCHECK(stream_.get()); |
| 880 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 863 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
| 881 result = HandleCertificateRequest(result); | 864 result = HandleCertificateRequest(result); |
| 882 } else if (result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { | 865 } else if (result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { |
| 883 // Return OK and let the caller read the proxy's error page | 866 // Return OK and let the caller read the proxy's error page |
| 884 next_state_ = STATE_NONE; | 867 next_state_ = STATE_NONE; |
| 885 return OK; | 868 return OK; |
| 886 } else if (result == ERR_HTTP_1_1_REQUIRED || | 869 } else if (result == ERR_HTTP_1_1_REQUIRED || |
| (...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1471 } | 1454 } |
| 1472 } | 1455 } |
| 1473 | 1456 |
| 1474 // TODO(rch): This does not correctly handle errors when an SSL proxy is | 1457 // TODO(rch): This does not correctly handle errors when an SSL proxy is |
| 1475 // being used, as all of the errors are handled as if they were generated | 1458 // being used, as all of the errors are handled as if they were generated |
| 1476 // by the endpoint host, request_->url, rather than considering if they were | 1459 // by the endpoint host, request_->url, rather than considering if they were |
| 1477 // generated by the SSL proxy. http://crbug.com/69329 | 1460 // generated by the SSL proxy. http://crbug.com/69329 |
| 1478 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) { | 1461 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) { |
| 1479 DCHECK(request_); | 1462 DCHECK(request_); |
| 1480 HandleClientAuthError(error); | 1463 HandleClientAuthError(error); |
| 1481 | |
| 1482 // Accept deprecated cipher suites, but only on a fallback. This makes UMA | |
| 1483 // reflect servers require a deprecated cipher rather than merely prefer | |
| 1484 // it. This, however, has no security benefit until the ciphers are actually | |
| 1485 // removed. | |
| 1486 if (!server_ssl_config_.deprecated_cipher_suites_enabled && | |
| 1487 (error == ERR_SSL_VERSION_OR_CIPHER_MISMATCH || | |
| 1488 error == ERR_CONNECTION_CLOSED || error == ERR_CONNECTION_RESET)) { | |
| 1489 net_log_.AddEvent( | |
| 1490 NetLogEventType::SSL_CIPHER_FALLBACK, | |
| 1491 base::Bind(&NetLogSSLCipherFallbackCallback, &request_->url, error)); | |
| 1492 server_ssl_config_.deprecated_cipher_suites_enabled = true; | |
| 1493 ResetConnectionAndRequestForResend(); | |
| 1494 return OK; | |
| 1495 } | |
| 1496 | |
| 1497 return error; | 1464 return error; |
| 1498 } | 1465 } |
| 1499 | 1466 |
| 1500 // This method determines whether it is safe to resend the request after an | 1467 // This method determines whether it is safe to resend the request after an |
| 1501 // IO error. It can only be called in response to request header or body | 1468 // IO error. It can only be called in response to request header or body |
| 1502 // write errors or response header read errors. It should not be used in | 1469 // write errors or response header read errors. It should not be used in |
| 1503 // other cases, such as a Connect error. | 1470 // other cases, such as a Connect error. |
| 1504 int HttpNetworkTransaction::HandleIOError(int error) { | 1471 int HttpNetworkTransaction::HandleIOError(int error) { |
| 1505 // Because the peer may request renegotiation with client authentication at | 1472 // Because the peer may request renegotiation with client authentication at |
| 1506 // any time, check and handle client authentication errors. | 1473 // any time, check and handle client authentication errors. |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1571 provided_token_binding_key_.reset(); | 1538 provided_token_binding_key_.reset(); |
| 1572 referred_token_binding_key_.reset(); | 1539 referred_token_binding_key_.reset(); |
| 1573 } | 1540 } |
| 1574 | 1541 |
| 1575 void HttpNetworkTransaction::CacheNetErrorDetailsAndResetStream() { | 1542 void HttpNetworkTransaction::CacheNetErrorDetailsAndResetStream() { |
| 1576 if (stream_) | 1543 if (stream_) |
| 1577 stream_->PopulateNetErrorDetails(&net_error_details_); | 1544 stream_->PopulateNetErrorDetails(&net_error_details_); |
| 1578 stream_.reset(); | 1545 stream_.reset(); |
| 1579 } | 1546 } |
| 1580 | 1547 |
| 1581 void HttpNetworkTransaction::RecordSSLFallbackMetrics(int result) { | |
| 1582 if (result != OK) | |
| 1583 return; | |
| 1584 | |
| 1585 UMA_HISTOGRAM_BOOLEAN("Net.ConnectionUsedSSLDeprecatedCipherFallback2", | |
| 1586 server_ssl_config_.deprecated_cipher_suites_enabled); | |
| 1587 } | |
| 1588 | |
| 1589 HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const { | 1548 HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const { |
| 1590 return response_.headers.get(); | 1549 return response_.headers.get(); |
| 1591 } | 1550 } |
| 1592 | 1551 |
| 1593 bool HttpNetworkTransaction::ShouldResendRequest() const { | 1552 bool HttpNetworkTransaction::ShouldResendRequest() const { |
| 1594 bool connection_is_proven = stream_->IsConnectionReused(); | 1553 bool connection_is_proven = stream_->IsConnectionReused(); |
| 1595 bool has_received_headers = GetResponseHeaders() != NULL; | 1554 bool has_received_headers = GetResponseHeaders() != NULL; |
| 1596 | 1555 |
| 1597 // NOTE: we resend a request only if we reused a keep-alive connection. | 1556 // NOTE: we resend a request only if we reused a keep-alive connection. |
| 1598 // This automatically prevents an infinite resend loop because we'll run | 1557 // This automatically prevents an infinite resend loop because we'll run |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1700 DCHECK(stream_request_); | 1659 DCHECK(stream_request_); |
| 1701 | 1660 |
| 1702 // Since the transaction can restart with auth credentials, it may create a | 1661 // Since the transaction can restart with auth credentials, it may create a |
| 1703 // stream more than once. Accumulate all of the connection attempts across | 1662 // stream more than once. Accumulate all of the connection attempts across |
| 1704 // those streams by appending them to the vector: | 1663 // those streams by appending them to the vector: |
| 1705 for (const auto& attempt : stream_request_->connection_attempts()) | 1664 for (const auto& attempt : stream_request_->connection_attempts()) |
| 1706 connection_attempts_.push_back(attempt); | 1665 connection_attempts_.push_back(attempt); |
| 1707 } | 1666 } |
| 1708 | 1667 |
| 1709 } // namespace net | 1668 } // namespace net |
| OLD | NEW |