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>& gcm_network_session, |
| 49 const scoped_refptr<net::HttpNetworkSession>& http_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 |