| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "google_apis/gcm/engine/connection_factory_impl.h" | 5 #include "google_apis/gcm/engine/connection_factory_impl.h" |
| 6 | 6 |
| 7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
| 8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 9 #include "base/metrics/sparse_histogram.h" | 9 #include "base/metrics/sparse_histogram.h" |
| 10 #include "google_apis/gcm/engine/connection_handler_impl.h" | 10 #include "google_apis/gcm/engine/connection_handler_impl.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 return !login_time.is_null() && | 38 return !login_time.is_null() && |
| 39 now_ticks - login_time <= | 39 now_ticks - login_time <= |
| 40 base::TimeDelta::FromSeconds(kConnectionResetWindowSecs); | 40 base::TimeDelta::FromSeconds(kConnectionResetWindowSecs); |
| 41 } | 41 } |
| 42 | 42 |
| 43 } // namespace | 43 } // namespace |
| 44 | 44 |
| 45 ConnectionFactoryImpl::ConnectionFactoryImpl( | 45 ConnectionFactoryImpl::ConnectionFactoryImpl( |
| 46 const std::vector<GURL>& mcs_endpoints, | 46 const std::vector<GURL>& mcs_endpoints, |
| 47 const net::BackoffEntry::Policy& backoff_policy, | 47 const net::BackoffEntry::Policy& backoff_policy, |
| 48 scoped_refptr<net::HttpNetworkSession> network_session, | 48 const scoped_refptr<net::HttpNetworkSession>& http_network_session, |
| 49 const scoped_refptr<net::HttpNetworkSession>& gcm_network_session, |
| 49 net::NetLog* net_log, | 50 net::NetLog* net_log, |
| 50 GCMStatsRecorder* recorder) | 51 GCMStatsRecorder* recorder) |
| 51 : mcs_endpoints_(mcs_endpoints), | 52 : mcs_endpoints_(mcs_endpoints), |
| 52 next_endpoint_(0), | 53 next_endpoint_(0), |
| 53 last_successful_endpoint_(0), | 54 last_successful_endpoint_(0), |
| 54 backoff_policy_(backoff_policy), | 55 backoff_policy_(backoff_policy), |
| 55 network_session_(network_session), | 56 gcm_network_session_(gcm_network_session), |
| 57 http_network_session_(http_network_session), |
| 56 bound_net_log_( | 58 bound_net_log_( |
| 57 net::BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)), | 59 net::BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)), |
| 58 pac_request_(NULL), | 60 pac_request_(NULL), |
| 59 connecting_(false), | 61 connecting_(false), |
| 60 waiting_for_backoff_(false), | 62 waiting_for_backoff_(false), |
| 61 waiting_for_network_online_(false), | 63 waiting_for_network_online_(false), |
| 62 logging_in_(false), | 64 logging_in_(false), |
| 63 recorder_(recorder), | 65 recorder_(recorder), |
| 64 listener_(NULL), | 66 listener_(NULL), |
| 65 weak_ptr_factory_(this) { | 67 weak_ptr_factory_(this) { |
| 66 DCHECK_GE(mcs_endpoints_.size(), 1U); | 68 DCHECK_GE(mcs_endpoints_.size(), 1U); |
| 69 DCHECK(!http_network_session_.get() || |
| 70 (gcm_network_session_.get() != http_network_session_.get())); |
| 67 } | 71 } |
| 68 | 72 |
| 69 ConnectionFactoryImpl::~ConnectionFactoryImpl() { | 73 ConnectionFactoryImpl::~ConnectionFactoryImpl() { |
| 70 CloseSocket(); | 74 CloseSocket(); |
| 71 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); | 75 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); |
| 72 if (pac_request_) { | 76 if (pac_request_) { |
| 73 network_session_->proxy_service()->CancelPacRequest(pac_request_); | 77 gcm_network_session_->proxy_service()->CancelPacRequest(pac_request_); |
| 74 pac_request_ = NULL; | 78 pac_request_ = NULL; |
| 75 } | 79 } |
| 76 } | 80 } |
| 77 | 81 |
| 78 void ConnectionFactoryImpl::Initialize( | 82 void ConnectionFactoryImpl::Initialize( |
| 79 const BuildLoginRequestCallback& request_builder, | 83 const BuildLoginRequestCallback& request_builder, |
| 80 const ConnectionHandler::ProtoReceivedCallback& read_callback, | 84 const ConnectionHandler::ProtoReceivedCallback& read_callback, |
| 81 const ConnectionHandler::ProtoSentCallback& write_callback) { | 85 const ConnectionHandler::ProtoSentCallback& write_callback) { |
| 82 DCHECK(!connection_handler_); | 86 DCHECK(!connection_handler_); |
| 83 | 87 |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 void ConnectionFactoryImpl::ConnectImpl() { | 277 void ConnectionFactoryImpl::ConnectImpl() { |
| 274 DCHECK(!IsEndpointReachable()); | 278 DCHECK(!IsEndpointReachable()); |
| 275 DCHECK(!socket_handle_.socket()); | 279 DCHECK(!socket_handle_.socket()); |
| 276 | 280 |
| 277 if (waiting_for_network_online_) | 281 if (waiting_for_network_online_) |
| 278 return; | 282 return; |
| 279 | 283 |
| 280 connecting_ = true; | 284 connecting_ = true; |
| 281 GURL current_endpoint = GetCurrentEndpoint(); | 285 GURL current_endpoint = GetCurrentEndpoint(); |
| 282 recorder_->RecordConnectionInitiated(current_endpoint.host()); | 286 recorder_->RecordConnectionInitiated(current_endpoint.host()); |
| 283 int status = network_session_->proxy_service()->ResolveProxy( | 287 RebuildNetworkSessionAuthCache(); |
| 288 int status = gcm_network_session_->proxy_service()->ResolveProxy( |
| 284 current_endpoint, | 289 current_endpoint, |
| 285 net::LOAD_NORMAL, | 290 net::LOAD_NORMAL, |
| 286 &proxy_info_, | 291 &proxy_info_, |
| 287 base::Bind(&ConnectionFactoryImpl::OnProxyResolveDone, | 292 base::Bind(&ConnectionFactoryImpl::OnProxyResolveDone, |
| 288 weak_ptr_factory_.GetWeakPtr()), | 293 weak_ptr_factory_.GetWeakPtr()), |
| 289 &pac_request_, | 294 &pac_request_, |
| 290 NULL, | 295 NULL, |
| 291 bound_net_log_); | 296 bound_net_log_); |
| 292 if (status != net::ERR_IO_PENDING) | 297 if (status != net::ERR_IO_PENDING) |
| 293 OnProxyResolveDone(status); | 298 OnProxyResolveDone(status); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 | 423 |
| 419 if (status != net::OK) { | 424 if (status != net::OK) { |
| 420 // Failed to resolve proxy. Retry later. | 425 // Failed to resolve proxy. Retry later. |
| 421 OnConnectDone(status); | 426 OnConnectDone(status); |
| 422 return; | 427 return; |
| 423 } | 428 } |
| 424 | 429 |
| 425 DVLOG(1) << "Resolved proxy with PAC:" << proxy_info_.ToPacString(); | 430 DVLOG(1) << "Resolved proxy with PAC:" << proxy_info_.ToPacString(); |
| 426 | 431 |
| 427 net::SSLConfig ssl_config; | 432 net::SSLConfig ssl_config; |
| 428 network_session_->ssl_config_service()->GetSSLConfig(&ssl_config); | 433 gcm_network_session_->ssl_config_service()->GetSSLConfig(&ssl_config); |
| 429 status = net::InitSocketHandleForTlsConnect( | 434 status = net::InitSocketHandleForTlsConnect( |
| 430 net::HostPortPair::FromURL(GetCurrentEndpoint()), | 435 net::HostPortPair::FromURL(GetCurrentEndpoint()), |
| 431 network_session_.get(), | 436 gcm_network_session_.get(), |
| 432 proxy_info_, | 437 proxy_info_, |
| 433 ssl_config, | 438 ssl_config, |
| 434 ssl_config, | 439 ssl_config, |
| 435 net::PRIVACY_MODE_DISABLED, | 440 net::PRIVACY_MODE_DISABLED, |
| 436 bound_net_log_, | 441 bound_net_log_, |
| 437 &socket_handle_, | 442 &socket_handle_, |
| 438 base::Bind(&ConnectionFactoryImpl::OnConnectDone, | 443 base::Bind(&ConnectionFactoryImpl::OnConnectDone, |
| 439 weak_ptr_factory_.GetWeakPtr())); | 444 weak_ptr_factory_.GetWeakPtr())); |
| 440 if (status != net::ERR_IO_PENDING) | 445 if (status != net::ERR_IO_PENDING) |
| 441 OnConnectDone(status); | 446 OnConnectDone(status); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 // Note that if the host resolving was done by the SOCKS5 proxy, we can't | 492 // Note that if the host resolving was done by the SOCKS5 proxy, we can't |
| 488 // differentiate between a proxy-side "host not found" versus a proxy-side | 493 // differentiate between a proxy-side "host not found" versus a proxy-side |
| 489 // "address unreachable" error, and will report both of these failures as | 494 // "address unreachable" error, and will report both of these failures as |
| 490 // ERR_ADDRESS_UNREACHABLE. | 495 // ERR_ADDRESS_UNREACHABLE. |
| 491 return net::ERR_ADDRESS_UNREACHABLE; | 496 return net::ERR_ADDRESS_UNREACHABLE; |
| 492 default: | 497 default: |
| 493 return error; | 498 return error; |
| 494 } | 499 } |
| 495 | 500 |
| 496 net::SSLConfig ssl_config; | 501 net::SSLConfig ssl_config; |
| 497 network_session_->ssl_config_service()->GetSSLConfig(&ssl_config); | 502 gcm_network_session_->ssl_config_service()->GetSSLConfig(&ssl_config); |
| 498 if (proxy_info_.is_https() && ssl_config.send_client_cert) { | 503 if (proxy_info_.is_https() && ssl_config.send_client_cert) { |
| 499 network_session_->ssl_client_auth_cache()->Remove( | 504 gcm_network_session_->ssl_client_auth_cache()->Remove( |
| 500 proxy_info_.proxy_server().host_port_pair()); | 505 proxy_info_.proxy_server().host_port_pair()); |
| 501 } | 506 } |
| 502 | 507 |
| 503 int status = network_session_->proxy_service()->ReconsiderProxyAfterError( | 508 int status = gcm_network_session_->proxy_service()->ReconsiderProxyAfterError( |
| 504 GetCurrentEndpoint(), net::LOAD_NORMAL, error, &proxy_info_, | 509 GetCurrentEndpoint(), net::LOAD_NORMAL, error, &proxy_info_, |
| 505 base::Bind(&ConnectionFactoryImpl::OnProxyResolveDone, | 510 base::Bind(&ConnectionFactoryImpl::OnProxyResolveDone, |
| 506 weak_ptr_factory_.GetWeakPtr()), | 511 weak_ptr_factory_.GetWeakPtr()), |
| 507 &pac_request_, | 512 &pac_request_, |
| 508 NULL, | 513 NULL, |
| 509 bound_net_log_); | 514 bound_net_log_); |
| 510 if (status == net::OK || status == net::ERR_IO_PENDING) { | 515 if (status == net::OK || status == net::ERR_IO_PENDING) { |
| 511 CloseSocket(); | 516 CloseSocket(); |
| 512 } else { | 517 } else { |
| 513 // If ReconsiderProxyAfterError() failed synchronously, it means | 518 // If ReconsiderProxyAfterError() failed synchronously, it means |
| 514 // there was nothing left to fall-back to, so fail the transaction | 519 // there was nothing left to fall-back to, so fail the transaction |
| 515 // with the last connection error we got. | 520 // with the last connection error we got. |
| 516 status = error; | 521 status = error; |
| 517 } | 522 } |
| 518 | 523 |
| 519 // If there is new proxy info, post OnProxyResolveDone to retry it. Otherwise, | 524 // If there is new proxy info, post OnProxyResolveDone to retry it. Otherwise, |
| 520 // if there was an error falling back, fail synchronously. | 525 // if there was an error falling back, fail synchronously. |
| 521 if (status == net::OK) { | 526 if (status == net::OK) { |
| 522 base::MessageLoop::current()->PostTask( | 527 base::MessageLoop::current()->PostTask( |
| 523 FROM_HERE, | 528 FROM_HERE, |
| 524 base::Bind(&ConnectionFactoryImpl::OnProxyResolveDone, | 529 base::Bind(&ConnectionFactoryImpl::OnProxyResolveDone, |
| 525 weak_ptr_factory_.GetWeakPtr(), status)); | 530 weak_ptr_factory_.GetWeakPtr(), status)); |
| 526 status = net::ERR_IO_PENDING; | 531 status = net::ERR_IO_PENDING; |
| 527 } | 532 } |
| 528 return status; | 533 return status; |
| 529 } | 534 } |
| 530 | 535 |
| 531 void ConnectionFactoryImpl::ReportSuccessfulProxyConnection() { | 536 void ConnectionFactoryImpl::ReportSuccessfulProxyConnection() { |
| 532 if (network_session_ && network_session_->proxy_service()) | 537 if (gcm_network_session_ && gcm_network_session_->proxy_service()) |
| 533 network_session_->proxy_service()->ReportSuccess(proxy_info_); | 538 gcm_network_session_->proxy_service()->ReportSuccess(proxy_info_); |
| 534 } | 539 } |
| 535 | 540 |
| 536 void ConnectionFactoryImpl::CloseSocket() { | 541 void ConnectionFactoryImpl::CloseSocket() { |
| 537 // The connection handler needs to be reset, else it'll attempt to keep using | 542 // The connection handler needs to be reset, else it'll attempt to keep using |
| 538 // the destroyed socket. | 543 // the destroyed socket. |
| 539 if (connection_handler_) | 544 if (connection_handler_) |
| 540 connection_handler_->Reset(); | 545 connection_handler_->Reset(); |
| 541 | 546 |
| 542 if (socket_handle_.socket() && socket_handle_.socket()->IsConnected()) | 547 if (socket_handle_.socket() && socket_handle_.socket()->IsConnected()) |
| 543 socket_handle_.socket()->Disconnect(); | 548 socket_handle_.socket()->Disconnect(); |
| 544 socket_handle_.Reset(); | 549 socket_handle_.Reset(); |
| 545 } | 550 } |
| 546 | 551 |
| 552 void ConnectionFactoryImpl::RebuildNetworkSessionAuthCache() { |
| 553 if (!http_network_session_ || !http_network_session_->http_auth_cache()) |
| 554 return; |
| 555 |
| 556 gcm_network_session_->http_auth_cache()->UpdateAllFrom( |
| 557 *http_network_session_->http_auth_cache()); |
| 558 } |
| 559 |
| 547 } // namespace gcm | 560 } // namespace gcm |
| OLD | NEW |