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_stream_factory_impl_job.h" | 5 #include "net/http/http_stream_factory_impl_job.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
60 namespace net { | 60 namespace net { |
61 | 61 |
62 namespace { | 62 namespace { |
63 | 63 |
64 // Experiment to preconnect only one connection if HttpServerProperties is | 64 // Experiment to preconnect only one connection if HttpServerProperties is |
65 // not supported or initialized. | 65 // not supported or initialized. |
66 const base::Feature kLimitEarlyPreconnectsExperiment{ | 66 const base::Feature kLimitEarlyPreconnectsExperiment{ |
67 "LimitEarlyPreconnects", base::FEATURE_DISABLED_BY_DEFAULT}; | 67 "LimitEarlyPreconnects", base::FEATURE_DISABLED_BY_DEFAULT}; |
68 void DoNothingAsyncCallback(int result) {} | 68 void DoNothingAsyncCallback(int result) {} |
69 void RecordChannelIDKeyMatch(SSLClientSocket* ssl_socket, | 69 void RecordChannelIDKeyMatch(SSLClientSocket* ssl_socket, |
70 const SSLInfo& ssl_info, | |
70 ChannelIDService* channel_id_service, | 71 ChannelIDService* channel_id_service, |
71 std::string host) { | 72 std::string host) { |
72 SSLInfo ssl_info; | |
73 ssl_socket->GetSSLInfo(&ssl_info); | |
74 if (!ssl_info.channel_id_sent) | 73 if (!ssl_info.channel_id_sent) |
75 return; | 74 return; |
76 std::unique_ptr<crypto::ECPrivateKey> request_key; | 75 std::unique_ptr<crypto::ECPrivateKey> request_key; |
77 ChannelIDService::Request request; | 76 ChannelIDService::Request request; |
78 int result = channel_id_service->GetOrCreateChannelID( | 77 int result = channel_id_service->GetOrCreateChannelID( |
79 host, &request_key, base::Bind(&DoNothingAsyncCallback), &request); | 78 host, &request_key, base::Bind(&DoNothingAsyncCallback), &request); |
80 // GetOrCreateChannelID only returns ERR_IO_PENDING before its first call | 79 // GetOrCreateChannelID only returns ERR_IO_PENDING before its first call |
81 // (over the lifetime of the ChannelIDService) has completed or if it is | 80 // (over the lifetime of the ChannelIDService) has completed or if it is |
82 // creating a new key. The key that is being looked up here should already | 81 // creating a new key. The key that is being looked up here should already |
83 // have been looked up before the channel ID was sent on the ssl socket, so | 82 // have been looked up before the channel ID was sent on the ssl socket, so |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
378 UMA_HISTOGRAM_ENUMERATION("Net.HttpStreamFactoryJob.Main.State", state_, | 377 UMA_HISTOGRAM_ENUMERATION("Net.HttpStreamFactoryJob.Main.State", state_, |
379 STATE_MAX); | 378 STATE_MAX); |
380 } else if (job_type_ == ALTERNATIVE) { | 379 } else if (job_type_ == ALTERNATIVE) { |
381 UMA_HISTOGRAM_ENUMERATION("Net.HttpStreamFactoryJob.Alt.NextState", | 380 UMA_HISTOGRAM_ENUMERATION("Net.HttpStreamFactoryJob.Alt.NextState", |
382 next_state_, STATE_MAX); | 381 next_state_, STATE_MAX); |
383 UMA_HISTOGRAM_ENUMERATION("Net.HttpStreamFactoryJob.Alt.State", state_, | 382 UMA_HISTOGRAM_ENUMERATION("Net.HttpStreamFactoryJob.Alt.State", state_, |
384 STATE_MAX); | 383 STATE_MAX); |
385 } | 384 } |
386 } | 385 } |
387 | 386 |
388 void HttpStreamFactoryImpl::Job::GetSSLInfo() { | 387 SSLClientSocket* HttpStreamFactoryImpl::Job::GetSSLInfo(SSLInfo* ssl_info) { |
389 DCHECK(using_ssl_); | 388 DCHECK(using_ssl_); |
390 DCHECK(!establishing_tunnel_); | 389 DCHECK(!establishing_tunnel_); |
391 DCHECK(connection_.get() && connection_->socket()); | 390 DCHECK(connection_.get() && connection_->socket()); |
392 SSLClientSocket* ssl_socket = | 391 SSLClientSocket* ssl_socket = |
393 static_cast<SSLClientSocket*>(connection_->socket()); | 392 static_cast<SSLClientSocket*>(connection_->socket()); |
394 ssl_socket->GetSSLInfo(&ssl_info_); | 393 ssl_socket->GetSSLInfo(ssl_info); |
394 return ssl_socket; | |
395 } | 395 } |
396 | 396 |
397 SpdySessionKey HttpStreamFactoryImpl::Job::GetSpdySessionKey() const { | 397 SpdySessionKey HttpStreamFactoryImpl::Job::GetSpdySessionKey() const { |
398 // In the case that we're using an HTTPS proxy for an HTTP url, | 398 // In the case that we're using an HTTPS proxy for an HTTP url, |
399 // we look for a SPDY session *to* the proxy, instead of to the | 399 // we look for a SPDY session *to* the proxy, instead of to the |
400 // origin server. | 400 // origin server. |
401 if (IsHttpsProxyAndHttpUrl()) { | 401 if (IsHttpsProxyAndHttpUrl()) { |
402 return SpdySessionKey(proxy_info_.proxy_server().host_port_pair(), | 402 return SpdySessionKey(proxy_info_.proxy_server().host_port_pair(), |
403 ProxyServer::Direct(), PRIVACY_MODE_DISABLED); | 403 ProxyServer::Direct(), PRIVACY_MODE_DISABLED); |
404 } | 404 } |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
556 if (job_type_ == PRECONNECT) { | 556 if (job_type_ == PRECONNECT) { |
557 base::ThreadTaskRunnerHandle::Get()->PostTask( | 557 base::ThreadTaskRunnerHandle::Get()->PostTask( |
558 FROM_HERE, | 558 FROM_HERE, |
559 base::Bind(&HttpStreamFactoryImpl::Job::OnPreconnectsComplete, | 559 base::Bind(&HttpStreamFactoryImpl::Job::OnPreconnectsComplete, |
560 ptr_factory_.GetWeakPtr())); | 560 ptr_factory_.GetWeakPtr())); |
561 return; | 561 return; |
562 } | 562 } |
563 | 563 |
564 if (IsCertificateError(result)) { | 564 if (IsCertificateError(result)) { |
565 // Retrieve SSL information from the socket. | 565 // Retrieve SSL information from the socket. |
566 GetSSLInfo(); | 566 SSLInfo ssl_info; |
567 GetSSLInfo(&ssl_info); | |
xunjieli
2017/05/19 22:55:25
GetSSLInfo() are called with the return value igno
Bence
2017/05/20 17:17:49
Done.
| |
567 | 568 |
568 next_state_ = STATE_WAITING_USER_ACTION; | 569 next_state_ = STATE_WAITING_USER_ACTION; |
569 base::ThreadTaskRunnerHandle::Get()->PostTask( | 570 base::ThreadTaskRunnerHandle::Get()->PostTask( |
570 FROM_HERE, | 571 FROM_HERE, |
571 base::Bind(&HttpStreamFactoryImpl::Job::OnCertificateErrorCallback, | 572 base::Bind(&HttpStreamFactoryImpl::Job::OnCertificateErrorCallback, |
572 ptr_factory_.GetWeakPtr(), result, ssl_info_)); | 573 ptr_factory_.GetWeakPtr(), result, ssl_info)); |
573 return; | 574 return; |
574 } | 575 } |
575 | 576 |
576 switch (result) { | 577 switch (result) { |
577 case ERR_PROXY_AUTH_REQUESTED: { | 578 case ERR_PROXY_AUTH_REQUESTED: { |
578 UMA_HISTOGRAM_BOOLEAN("Net.ProxyAuthRequested.HasConnection", | 579 UMA_HISTOGRAM_BOOLEAN("Net.ProxyAuthRequested.HasConnection", |
579 connection_.get() != NULL); | 580 connection_.get() != NULL); |
580 if (!connection_.get()) { | 581 if (!connection_.get()) { |
581 base::ThreadTaskRunnerHandle::Get()->PostTask( | 582 base::ThreadTaskRunnerHandle::Get()->PostTask( |
582 FROM_HERE, | 583 FROM_HERE, |
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1124 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462811 is fixed. | 1125 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462811 is fixed. |
1125 tracked_objects::ScopedTracker tracking_profile( | 1126 tracked_objects::ScopedTracker tracking_profile( |
1126 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1127 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
1127 "462811 HttpStreamFactoryImpl::Job::DoCreateStream")); | 1128 "462811 HttpStreamFactoryImpl::Job::DoCreateStream")); |
1128 DCHECK(connection_->socket() || existing_spdy_session_.get() || using_quic_); | 1129 DCHECK(connection_->socket() || existing_spdy_session_.get() || using_quic_); |
1129 DCHECK(!IsQuicAlternative()); | 1130 DCHECK(!IsQuicAlternative()); |
1130 | 1131 |
1131 next_state_ = STATE_CREATE_STREAM_COMPLETE; | 1132 next_state_ = STATE_CREATE_STREAM_COMPLETE; |
1132 | 1133 |
1133 if (using_ssl_ && connection_->socket()) { | 1134 if (using_ssl_ && connection_->socket()) { |
1134 SSLClientSocket* ssl_socket = | 1135 SSLInfo ssl_info; |
1135 static_cast<SSLClientSocket*>(connection_->socket()); | 1136 SSLClientSocket* ssl_socket = GetSSLInfo(&ssl_info); |
1136 RecordChannelIDKeyMatch(ssl_socket, session_->params().channel_id_service, | 1137 RecordChannelIDKeyMatch(ssl_socket, ssl_info, |
1138 session_->params().channel_id_service, | |
1137 destination_.HostForURL()); | 1139 destination_.HostForURL()); |
1138 } | 1140 } |
1139 | 1141 |
1140 // We only set the socket motivation if we're the first to use | 1142 // We only set the socket motivation if we're the first to use |
1141 // this socket. Is there a race for two SPDY requests? We really | 1143 // this socket. Is there a race for two SPDY requests? We really |
1142 // need to plumb this through to the connect level. | 1144 // need to plumb this through to the connect level. |
1143 if (connection_->socket() && !connection_->is_reused()) | 1145 if (connection_->socket() && !connection_->is_reused()) |
1144 SetSocketMotivation(); | 1146 SetSocketMotivation(); |
1145 | 1147 |
1146 if (!using_spdy_) { | 1148 if (!using_spdy_) { |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1381 } | 1383 } |
1382 | 1384 |
1383 should_reconsider_proxy_ = true; | 1385 should_reconsider_proxy_ = true; |
1384 return error; | 1386 return error; |
1385 } | 1387 } |
1386 | 1388 |
1387 int HttpStreamFactoryImpl::Job::HandleCertificateError(int error) { | 1389 int HttpStreamFactoryImpl::Job::HandleCertificateError(int error) { |
1388 DCHECK(using_ssl_); | 1390 DCHECK(using_ssl_); |
1389 DCHECK(IsCertificateError(error)); | 1391 DCHECK(IsCertificateError(error)); |
1390 | 1392 |
1391 SSLClientSocket* ssl_socket = | 1393 SSLInfo ssl_info; |
1392 static_cast<SSLClientSocket*>(connection_->socket()); | 1394 GetSSLInfo(&ssl_info); |
1393 ssl_socket->GetSSLInfo(&ssl_info_); | |
1394 | 1395 |
1395 if (!ssl_info_.cert) { | 1396 if (!ssl_info.cert) { |
1396 // If the server's certificate could not be parsed, there is no way | 1397 // If the server's certificate could not be parsed, there is no way |
1397 // to gracefully recover this, so just pass the error up. | 1398 // to gracefully recover this, so just pass the error up. |
1398 return error; | 1399 return error; |
1399 } | 1400 } |
1400 | 1401 |
1401 // Add the bad certificate to the set of allowed certificates in the | 1402 // Add the bad certificate to the set of allowed certificates in the |
1402 // SSL config object. This data structure will be consulted after calling | 1403 // SSL config object. This data structure will be consulted after calling |
1403 // RestartIgnoringLastError(). And the user will be asked interactively | 1404 // RestartIgnoringLastError(). And the user will be asked interactively |
1404 // before RestartIgnoringLastError() is ever called. | 1405 // before RestartIgnoringLastError() is ever called. |
1405 server_ssl_config_.allowed_bad_certs.emplace_back(ssl_info_.cert, | 1406 server_ssl_config_.allowed_bad_certs.emplace_back(ssl_info.cert, |
1406 ssl_info_.cert_status); | 1407 ssl_info.cert_status); |
1407 | 1408 |
1408 int load_flags = request_info_.load_flags; | 1409 int load_flags = request_info_.load_flags; |
1409 if (session_->params().ignore_certificate_errors) | 1410 if (session_->params().ignore_certificate_errors) |
1410 load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS; | 1411 load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS; |
1411 if (ssl_socket->IgnoreCertError(error, load_flags)) | 1412 if (SSLClientSocket::IgnoreCertError(error, load_flags)) |
xunjieli
2017/05/19 22:55:25
nice!
Bence
2017/05/20 17:17:49
An MSVC error message helped me realize that: when
| |
1412 return OK; | 1413 return OK; |
1413 return error; | 1414 return error; |
1414 } | 1415 } |
1415 | 1416 |
1416 ClientSocketPoolManager::SocketGroupType | 1417 ClientSocketPoolManager::SocketGroupType |
1417 HttpStreamFactoryImpl::Job::GetSocketGroup() const { | 1418 HttpStreamFactoryImpl::Job::GetSocketGroup() const { |
1418 std::string scheme = origin_url_.scheme(); | 1419 std::string scheme = origin_url_.scheme(); |
1419 if (scheme == url::kHttpsScheme || scheme == url::kWssScheme) | 1420 if (scheme == url::kHttpsScheme || scheme == url::kWssScheme) |
1420 return ClientSocketPoolManager::SSL_GROUP; | 1421 return ClientSocketPoolManager::SSL_GROUP; |
1421 | 1422 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1504 bool enable_ip_based_pooling, | 1505 bool enable_ip_based_pooling, |
1505 NetLog* net_log) { | 1506 NetLog* net_log) { |
1506 return base::MakeUnique<HttpStreamFactoryImpl::Job>( | 1507 return base::MakeUnique<HttpStreamFactoryImpl::Job>( |
1507 delegate, job_type, session, request_info, priority, proxy_info, | 1508 delegate, job_type, session, request_info, priority, proxy_info, |
1508 server_ssl_config, proxy_ssl_config, destination, origin_url, | 1509 server_ssl_config, proxy_ssl_config, destination, origin_url, |
1509 AlternativeService(), alternative_proxy_server, enable_ip_based_pooling, | 1510 AlternativeService(), alternative_proxy_server, enable_ip_based_pooling, |
1510 net_log); | 1511 net_log); |
1511 } | 1512 } |
1512 | 1513 |
1513 } // namespace net | 1514 } // namespace net |
OLD | NEW |