summaryrefslogtreecommitdiffstats
path: root/jingle/notifier
diff options
context:
space:
mode:
Diffstat (limited to 'jingle/notifier')
-rw-r--r--jingle/notifier/base/notifier_options_util.cc11
-rw-r--r--jingle/notifier/base/server_information.cc22
-rw-r--r--jingle/notifier/base/server_information.h11
-rw-r--r--jingle/notifier/base/xmpp_connection.cc7
-rw-r--r--jingle/notifier/base/xmpp_connection.h17
-rw-r--r--jingle/notifier/communicator/DEPS4
-rw-r--r--jingle/notifier/communicator/connection_options.cc16
-rw-r--r--jingle/notifier/communicator/connection_options.h53
-rw-r--r--jingle/notifier/communicator/connection_settings.cc165
-rw-r--r--jingle/notifier/communicator/connection_settings.h75
-rw-r--r--jingle/notifier/communicator/connection_settings_unittest.cc99
-rw-r--r--jingle/notifier/communicator/login.cc44
-rw-r--r--jingle/notifier/communicator/login.h20
-rw-r--r--jingle/notifier/communicator/login_settings.cc65
-rw-r--r--jingle/notifier/communicator/login_settings.h66
-rw-r--r--jingle/notifier/communicator/login_settings_unittest.cc77
-rw-r--r--jingle/notifier/communicator/single_login_attempt.cc178
-rw-r--r--jingle/notifier/communicator/single_login_attempt.h48
-rw-r--r--jingle/notifier/communicator/single_login_attempt_unittest.cc226
-rw-r--r--jingle/notifier/communicator/xmpp_connection_generator.cc190
-rw-r--r--jingle/notifier/communicator/xmpp_connection_generator.h84
-rw-r--r--jingle/notifier/communicator/xmpp_connection_generator_unittest.cc112
-rw-r--r--jingle/notifier/listener/mediator_thread_impl.cc6
23 files changed, 782 insertions, 814 deletions
diff --git a/jingle/notifier/base/notifier_options_util.cc b/jingle/notifier/base/notifier_options_util.cc
index e4b1752..9e107bc 100644
--- a/jingle/notifier/base/notifier_options_util.cc
+++ b/jingle/notifier/base/notifier_options_util.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -42,19 +42,20 @@ ServerList GetServerList(
// provided.
if (!notifier_options.xmpp_host_port.host().empty()) {
servers.push_back(
- ServerInformation(notifier_options.xmpp_host_port, false));
+ ServerInformation(notifier_options.xmpp_host_port,
+ DOES_NOT_SUPPORT_SSLTCP));
} else {
- // The default servers know how to serve over port 443 (that's the magic).
+ // The default servers support SSLTCP.
servers.push_back(
ServerInformation(
net::HostPortPair("talk.google.com",
notifier::kDefaultXmppPort),
- true));
+ SUPPORTS_SSLTCP));
servers.push_back(
ServerInformation(
net::HostPortPair("talkx.l.google.com",
notifier::kDefaultXmppPort),
- true));
+ SUPPORTS_SSLTCP));
}
return servers;
}
diff --git a/jingle/notifier/base/server_information.cc b/jingle/notifier/base/server_information.cc
index ba66507..003daca 100644
--- a/jingle/notifier/base/server_information.cc
+++ b/jingle/notifier/base/server_information.cc
@@ -1,15 +1,29 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "jingle/notifier/base/server_information.h"
+#include "base/logging.h"
+
namespace notifier {
ServerInformation::ServerInformation(
- const net::HostPortPair& server, bool special_port_magic)
- : server(server), special_port_magic(special_port_magic) {}
+ const net::HostPortPair& server, SslTcpSupport ssltcp_support)
+ : server(server), ssltcp_support(ssltcp_support) {
+ DCHECK(!server.host().empty());
+ DCHECK_GT(server.port(), 0);
+}
+
+ServerInformation::ServerInformation()
+ : ssltcp_support(DOES_NOT_SUPPORT_SSLTCP) {}
+
+ServerInformation::~ServerInformation() {}
-ServerInformation::ServerInformation() : special_port_magic(false) {}
+bool ServerInformation::Equals(const ServerInformation& other) const {
+ return
+ server.Equals(other.server) &&
+ (ssltcp_support == other.ssltcp_support);
+}
} // namespace notifier
diff --git a/jingle/notifier/base/server_information.h b/jingle/notifier/base/server_information.h
index c42b69e..c6e3ffd 100644
--- a/jingle/notifier/base/server_information.h
+++ b/jingle/notifier/base/server_information.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -13,13 +13,18 @@
namespace notifier {
+enum SslTcpSupport { DOES_NOT_SUPPORT_SSLTCP, SUPPORTS_SSLTCP };
+
struct ServerInformation {
ServerInformation(const net::HostPortPair& server,
- bool special_port_magic);
+ SslTcpSupport ssltcp_support);
ServerInformation();
+ ~ServerInformation();
+
+ bool Equals(const ServerInformation& other) const;
net::HostPortPair server;
- bool special_port_magic;
+ SslTcpSupport ssltcp_support;
};
typedef std::vector<ServerInformation> ServerList;
diff --git a/jingle/notifier/base/xmpp_connection.cc b/jingle/notifier/base/xmpp_connection.cc
index da1b5a1..6df0de8 100644
--- a/jingle/notifier/base/xmpp_connection.cc
+++ b/jingle/notifier/base/xmpp_connection.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -19,6 +19,8 @@
namespace notifier {
+XmppConnection::Delegate::~Delegate() {}
+
namespace {
buzz::AsyncSocket* CreateSocket(
@@ -47,7 +49,8 @@ buzz::AsyncSocket* CreateSocket(
XmppConnection::XmppConnection(
const buzz::XmppClientSettings& xmpp_client_settings,
const scoped_refptr<net::URLRequestContextGetter>& request_context_getter,
- Delegate* delegate, buzz::PreXmppAuth* pre_xmpp_auth)
+ Delegate* delegate,
+ buzz::PreXmppAuth* pre_xmpp_auth)
: task_pump_(new TaskPump()),
on_connect_called_(false),
delegate_(delegate) {
diff --git a/jingle/notifier/base/xmpp_connection.h b/jingle/notifier/base/xmpp_connection.h
index 886f58f..9baea68 100644
--- a/jingle/notifier/base/xmpp_connection.h
+++ b/jingle/notifier/base/xmpp_connection.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -34,8 +34,6 @@ class XmppConnection : public sigslot::has_slots<> {
public:
class Delegate {
public:
- virtual ~Delegate() {}
-
// Called (at most once) when a connection has been established.
// |base_task| can be used by the client as the parent of any Task
// it creates as long as it is valid (i.e., non-NULL).
@@ -52,22 +50,25 @@ class XmppConnection : public sigslot::has_slots<> {
// is non-NULL iff |error| == ERROR_STREAM. |stream_error| is
// valid only for the lifetime of this function.
//
- // Ideally, |error| would be set to something that is not
+ // Ideally, |error| would always be set to something that is not
// ERROR_NONE, but due to inconsistent error-handling this doesn't
// always happen.
virtual void OnError(buzz::XmppEngine::Error error, int subcode,
const buzz::XmlElement* stream_error) = 0;
+
+ protected:
+ virtual ~Delegate();
};
- // Does not take ownership of |cert_verifier|, which may not be NULL.
- // Does not take ownership of |delegate|, which may not be NULL.
- // Takes ownership of |pre_xmpp_auth|, which may be NULL.
+ // Does not take ownership of |delegate|, which must not be
+ // NULL. Takes ownership of |pre_xmpp_auth|, which may be NULL.
//
// TODO(akalin): Avoid the need for |pre_xmpp_auth|.
XmppConnection(const buzz::XmppClientSettings& xmpp_client_settings,
const scoped_refptr<net::URLRequestContextGetter>&
request_context_getter,
- Delegate* delegate, buzz::PreXmppAuth* pre_xmpp_auth);
+ Delegate* delegate,
+ buzz::PreXmppAuth* pre_xmpp_auth);
// Invalidates any weak pointers passed to the delegate by
// OnConnect(), but does not trigger a call to the delegate's
diff --git a/jingle/notifier/communicator/DEPS b/jingle/notifier/communicator/DEPS
new file mode 100644
index 0000000..fe7e23f
--- /dev/null
+++ b/jingle/notifier/communicator/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ # Need for cricket::ProtocolType.
+ "+talk/p2p/base/port.h",
+]
diff --git a/jingle/notifier/communicator/connection_options.cc b/jingle/notifier/communicator/connection_options.cc
deleted file mode 100644
index c103127..0000000
--- a/jingle/notifier/communicator/connection_options.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "jingle/notifier/communicator/connection_options.h"
-
-namespace notifier {
-
-ConnectionOptions::ConnectionOptions()
- : autodetect_proxy_(true),
- proxy_port_(0),
- use_proxy_auth_(0),
- allow_unverified_certs_(false) {
-}
-
-} // namespace notifier
diff --git a/jingle/notifier/communicator/connection_options.h b/jingle/notifier/communicator/connection_options.h
deleted file mode 100644
index 4f24b44..0000000
--- a/jingle/notifier/communicator/connection_options.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef JINGLE_NOTIFIER_COMMUNICATOR_CONNECTION_OPTIONS_H_
-#define JINGLE_NOTIFIER_COMMUNICATOR_CONNECTION_OPTIONS_H_
-
-#include <string>
-
-#include "talk/base/cryptstring.h"
-#include "talk/base/helpers.h"
-
-namespace notifier {
-
-class ConnectionOptions {
- public:
- ConnectionOptions();
-
- bool autodetect_proxy() const { return autodetect_proxy_; }
- const std::string& proxy_host() const { return proxy_host_; }
- int proxy_port() const { return proxy_port_; }
- bool use_proxy_auth() const { return use_proxy_auth_; }
- const std::string& auth_user() const { return auth_user_; }
- const talk_base::CryptString& auth_pass() const { return auth_pass_; }
- bool allow_unverified_certs() const { return allow_unverified_certs_; }
-
- void set_autodetect_proxy(bool f) { autodetect_proxy_ = f; }
- void set_proxy_host(const std::string& val) { proxy_host_ = val; }
- void set_proxy_port(int val) { proxy_port_ = val; }
- void set_use_proxy_auth(bool f) { use_proxy_auth_ = f; }
- void set_auth_user(const std::string& val) { auth_user_ = val; }
- void set_auth_pass(const talk_base::CryptString& val) { auth_pass_ = val; }
-
- // Setting this to true opens a security hole, so it is *highly* recommended
- // that you don't do this.
- void set_allow_unverified_certs(bool allow_unverified_certs) {
- allow_unverified_certs_ = allow_unverified_certs;
- }
-
- private:
- bool autodetect_proxy_;
- std::string proxy_host_;
- int proxy_port_;
- bool use_proxy_auth_;
- std::string auth_user_;
- talk_base::CryptString auth_pass_;
- bool allow_unverified_certs_;
- // Allow the copy constructor and operator=.
-};
-
-} // namespace notifier
-
-#endif // JINGLE_NOTIFIER_COMMUNICATOR_CONNECTION_OPTIONS_H_
diff --git a/jingle/notifier/communicator/connection_settings.cc b/jingle/notifier/communicator/connection_settings.cc
index d4b764c..862f905 100644
--- a/jingle/notifier/communicator/connection_settings.cc
+++ b/jingle/notifier/communicator/connection_settings.cc
@@ -1,111 +1,102 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <algorithm>
-#include <deque>
-#include <string>
-#include <vector>
+#include "jingle/notifier/communicator/connection_settings.h"
#include "base/logging.h"
-#include "jingle/notifier/communicator/connection_settings.h"
-#include "talk/base/helpers.h"
+
+// Ideally we shouldn't include anything from talk/p2p, but we need
+// the definition of ProtocolType. Don't use any functions from
+// port.h, since it won't link.
+#include "talk/p2p/base/port.h"
+
#include "talk/xmpp/xmppclientsettings.h"
namespace notifier {
-class RandomGenerator {
- public:
- int operator()(int ceiling) {
- return static_cast<int>(talk_base::CreateRandomId() % ceiling);
- }
-};
+const uint16 kSslTcpPort = 443;
+
+ConnectionSettings::ConnectionSettings(
+ const talk_base::SocketAddress& server,
+ SslTcpMode ssltcp_mode,
+ SslTcpSupport ssltcp_support)
+ : server(server),
+ ssltcp_mode(ssltcp_mode),
+ ssltcp_support(ssltcp_support) {}
-ConnectionSettings::ConnectionSettings() : protocol_(cricket::PROTO_TCP) {}
+ConnectionSettings::ConnectionSettings()
+ : ssltcp_mode(DO_NOT_USE_SSLTCP),
+ ssltcp_support(DOES_NOT_SUPPORT_SSLTCP) {}
ConnectionSettings::~ConnectionSettings() {}
-void ConnectionSettings::FillXmppClientSettings(
- buzz::XmppClientSettings* xcs) const {
- DCHECK(xcs);
- xcs->set_protocol(protocol_);
- xcs->set_server(server_);
- xcs->set_proxy(talk_base::PROXY_NONE);
- xcs->set_use_proxy_auth(false);
+bool ConnectionSettings::Equals(const ConnectionSettings& settings) const {
+ return
+ server == settings.server &&
+ ssltcp_mode == settings.ssltcp_mode &&
+ ssltcp_support == settings.ssltcp_support;
}
-ConnectionSettingsList::ConnectionSettingsList() {}
-
-ConnectionSettingsList::~ConnectionSettingsList() {}
-
-void ConnectionSettingsList::AddPermutations(const std::string& hostname,
- const std::vector<uint32>& iplist,
- uint16 port,
- bool special_port_magic,
- bool try_ssltcp_first) {
- // randomize the list. This ensures the iplist isn't always
- // evaluated in the order returned by DNS
- std::vector<uint32> iplist_random = iplist;
- RandomGenerator rg;
- std::random_shuffle(iplist_random.begin(), iplist_random.end(), rg);
-
- // Put generated addresses in a new deque, then append on the list_, since
- // there are order dependencies and AddPermutations() may be called more
- // than once.
- std::deque<ConnectionSettings> list_temp;
-
- // Permute addresses for this server. In some cases we haven't resolved the
- // to ip addresses.
- talk_base::SocketAddress server(hostname, port);
- if (iplist_random.empty()) {
- // We couldn't pre-resolve the hostname, so let's hope it will resolve
- // further down the pipeline (by a proxy, for example).
- PermuteForAddress(server, special_port_magic, try_ssltcp_first,
- &list_temp);
- } else {
- // Generate a set of possibilities for each server address.
- // Don't do permute duplicates.
- for (size_t index = 0; index < iplist_random.size(); ++index) {
- if (std::find(iplist_seen_.begin(), iplist_seen_.end(),
- iplist_random[index]) != iplist_seen_.end()) {
- continue;
- }
- iplist_seen_.push_back(iplist_random[index]);
- server.SetResolvedIP(iplist_random[index]);
- PermuteForAddress(server, special_port_magic, try_ssltcp_first,
- &list_temp);
- }
- }
+namespace {
- // Add this list to the instance list
- while (!list_temp.empty()) {
- list_.push_back(list_temp[0]);
- list_temp.pop_front();
- }
+const char* SslTcpModeToString(SslTcpMode ssltcp_mode) {
+ return (ssltcp_mode == USE_SSLTCP) ? "USE_SSLTCP" : "DO_NOT_USE_SSLTCP";
}
+const char* SslTcpSupportToString(SslTcpSupport ssltcp_support) {
+ return
+ (ssltcp_support == SUPPORTS_SSLTCP) ?
+ "SUPPORTS_SSLTCP" :
+ "DOES_NOT_SUPPORT_SSLTCP";
+}
-void ConnectionSettingsList::PermuteForAddress(
- const talk_base::SocketAddress& server,
- bool special_port_magic,
- bool try_ssltcp_first,
- std::deque<ConnectionSettings>* list_temp) {
- DCHECK(list_temp);
- *(template_.mutable_server()) = server;
-
- // Use all of the original settings
- list_temp->push_back(template_);
-
- // Try alternate port
- if (special_port_magic) {
- ConnectionSettings settings(template_);
- settings.set_protocol(cricket::PROTO_SSLTCP);
- settings.mutable_server()->SetPort(443);
- if (try_ssltcp_first) {
- list_temp->push_front(settings);
+} // namespace
+
+std::string ConnectionSettings::ToString() const {
+ return
+ server.ToString() + ":" + SslTcpModeToString(ssltcp_mode) + ":" +
+ SslTcpSupportToString(ssltcp_support);
+}
+
+void ConnectionSettings::FillXmppClientSettings(
+ buzz::XmppClientSettings* client_settings) const {
+ client_settings->set_protocol(
+ (ssltcp_mode == USE_SSLTCP) ?
+ cricket::PROTO_SSLTCP :
+ cricket::PROTO_TCP);
+ client_settings->set_server(server);
+}
+
+ConnectionSettingsList MakeConnectionSettingsList(
+ const ServerList& servers,
+ bool try_ssltcp_first) {
+ ConnectionSettingsList settings_list;
+
+ for (ServerList::const_iterator it = servers.begin();
+ it != servers.end(); ++it) {
+ const ConnectionSettings settings(
+ talk_base::SocketAddress(it->server.host(), it->server.port()),
+ DO_NOT_USE_SSLTCP, it->ssltcp_support);
+
+ if (it->ssltcp_support == SUPPORTS_SSLTCP) {
+ const ConnectionSettings settings_with_ssltcp(
+ talk_base::SocketAddress(it->server.host(), kSslTcpPort),
+ USE_SSLTCP, it->ssltcp_support);
+
+ if (try_ssltcp_first) {
+ settings_list.push_back(settings_with_ssltcp);
+ settings_list.push_back(settings);
+ } else {
+ settings_list.push_back(settings);
+ settings_list.push_back(settings_with_ssltcp);
+ }
} else {
- list_temp->push_back(settings);
+ settings_list.push_back(settings);
}
}
+
+ return settings_list;
}
+
} // namespace notifier
diff --git a/jingle/notifier/communicator/connection_settings.h b/jingle/notifier/communicator/connection_settings.h
index 91c95af..fe0f6b0 100644
--- a/jingle/notifier/communicator/connection_settings.h
+++ b/jingle/notifier/communicator/connection_settings.h
@@ -1,67 +1,58 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef JINGLE_NOTIFIER_COMMUNICATOR_CONNECTION_SETTINGS_H_
#define JINGLE_NOTIFIER_COMMUNICATOR_CONNECTION_SETTINGS_H_
-#include <deque>
#include <string>
#include <vector>
#include "base/basictypes.h"
-#include "talk/xmpp/xmppclientsettings.h"
+#include "jingle/notifier/base/server_information.h"
+#include "talk/base/socketaddress.h"
+
+namespace buzz {
+class XmppClientSettings;
+} // namespace
namespace notifier {
-class ConnectionSettings {
+// The port for SSLTCP (just the regular port for SSL).
+extern const uint16 kSslTcpPort;
+
+enum SslTcpMode { DO_NOT_USE_SSLTCP, USE_SSLTCP };
+
+struct ConnectionSettings {
public:
+ ConnectionSettings(const talk_base::SocketAddress& server,
+ SslTcpMode ssltcp_mode,
+ SslTcpSupport ssltcp_support);
ConnectionSettings();
~ConnectionSettings();
- cricket::ProtocolType protocol() { return protocol_; }
- const talk_base::SocketAddress& server() const { return server_; }
+ bool Equals(const ConnectionSettings& settings) const;
- void set_protocol(cricket::ProtocolType protocol) { protocol_ = protocol; }
- talk_base::SocketAddress* mutable_server() { return &server_; }
+ std::string ToString() const;
- void FillXmppClientSettings(buzz::XmppClientSettings* xcs) const;
+ // Fill in the connection-related fields of |client_settings|.
+ void FillXmppClientSettings(buzz::XmppClientSettings* client_settings) const;
- private:
- cricket::ProtocolType protocol_; // PROTO_TCP, PROTO_SSLTCP, etc.
- talk_base::SocketAddress server_; // Server.
- // Need copy constructor due to use in stl deque.
+ talk_base::SocketAddress server;
+ SslTcpMode ssltcp_mode;
+ SslTcpSupport ssltcp_support;
};
-class ConnectionSettingsList {
- public:
- ConnectionSettingsList();
- ~ConnectionSettingsList();
-
- int GetCount() { return list_.size(); }
- ConnectionSettings* GetSettings(size_t index) { return &list_[index]; }
-
- void ClearPermutations() {
- list_.clear();
- iplist_seen_.clear();
- }
-
- void AddPermutations(const std::string& hostname,
- const std::vector<uint32>& iplist,
- uint16 port,
- bool special_port_magic,
- bool try_ssltcp_first);
- private:
- void PermuteForAddress(const talk_base::SocketAddress& server,
- bool special_port_magic,
- bool try_ssltcp_first,
- std::deque<ConnectionSettings>* list_temp);
-
- ConnectionSettings template_;
- std::deque<ConnectionSettings> list_;
- std::vector<uint32> iplist_seen_;
- DISALLOW_COPY_AND_ASSIGN(ConnectionSettingsList);
-};
+typedef std::vector<ConnectionSettings> ConnectionSettingsList;
+
+// Given a list of servers in priority order, generate a list of
+// ConnectionSettings to try in priority order. If |try_ssltcp_first|
+// is set, for each server that supports SSLTCP, the
+// ConnectionSettings using SSLTCP will come first. If it is not set,
+// the ConnectionSettings using SSLTCP will come last.
+ConnectionSettingsList MakeConnectionSettingsList(
+ const ServerList& servers,
+ bool try_ssltcp_first);
} // namespace notifier
diff --git a/jingle/notifier/communicator/connection_settings_unittest.cc b/jingle/notifier/communicator/connection_settings_unittest.cc
new file mode 100644
index 0000000..c7e0c4c
--- /dev/null
+++ b/jingle/notifier/communicator/connection_settings_unittest.cc
@@ -0,0 +1,99 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "jingle/notifier/communicator/connection_settings.h"
+
+#include "jingle/notifier/base/server_information.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace notifier {
+
+namespace {
+
+class ConnectionSettingsTest : public ::testing::Test {
+ protected:
+ ConnectionSettingsTest() {
+ servers_.push_back(
+ ServerInformation(
+ net::HostPortPair("supports_ssltcp.com", 100),
+ SUPPORTS_SSLTCP));
+ servers_.push_back(
+ ServerInformation(
+ net::HostPortPair("does_not_support_ssltcp.com", 200),
+ DOES_NOT_SUPPORT_SSLTCP));
+ }
+
+ ServerList servers_;
+};
+
+// An empty server list should always map to an empty connection
+// settings list.
+TEST_F(ConnectionSettingsTest, Empty) {
+ EXPECT_TRUE(MakeConnectionSettingsList(ServerList(), false).empty());
+ EXPECT_TRUE(MakeConnectionSettingsList(ServerList(), true).empty());
+}
+
+// Make sure that servers that support SSLTCP get mapped to two
+// settings entries (with the SSLTCP one coming last) whereas those
+// that don't map to only one.
+TEST_F(ConnectionSettingsTest, Basic) {
+ const ConnectionSettingsList settings_list =
+ MakeConnectionSettingsList(servers_, false /* try_ssltcp_first */);
+
+ ConnectionSettingsList expected_settings_list;
+ expected_settings_list.push_back(
+ ConnectionSettings(
+ talk_base::SocketAddress("supports_ssltcp.com", 100),
+ DO_NOT_USE_SSLTCP,
+ SUPPORTS_SSLTCP));
+ expected_settings_list.push_back(
+ ConnectionSettings(
+ talk_base::SocketAddress("supports_ssltcp.com", 443),
+ USE_SSLTCP,
+ SUPPORTS_SSLTCP));
+ expected_settings_list.push_back(
+ ConnectionSettings(
+ talk_base::SocketAddress("does_not_support_ssltcp.com", 200),
+ DO_NOT_USE_SSLTCP,
+ DOES_NOT_SUPPORT_SSLTCP));
+
+ ASSERT_EQ(expected_settings_list.size(), settings_list.size());
+ for (size_t i = 0; i < settings_list.size(); ++i) {
+ EXPECT_TRUE(settings_list[i].Equals(expected_settings_list[i]));
+ }
+}
+
+// Make sure that servers that support SSLTCP get mapped to two
+// settings entries (with the SSLTCP one coming first) when
+// try_ssltcp_first is set.
+TEST_F(ConnectionSettingsTest, TrySslTcpFirst) {
+ const ConnectionSettingsList settings_list =
+ MakeConnectionSettingsList(servers_, true /* try_ssltcp_first */);
+
+ ConnectionSettingsList expected_settings_list;
+ expected_settings_list.push_back(
+ ConnectionSettings(
+ talk_base::SocketAddress("supports_ssltcp.com", 443),
+ USE_SSLTCP,
+ SUPPORTS_SSLTCP));
+ expected_settings_list.push_back(
+ ConnectionSettings(
+ talk_base::SocketAddress("supports_ssltcp.com", 100),
+ DO_NOT_USE_SSLTCP,
+ SUPPORTS_SSLTCP));
+ expected_settings_list.push_back(
+ ConnectionSettings(
+ talk_base::SocketAddress("does_not_support_ssltcp.com", 200),
+ DO_NOT_USE_SSLTCP,
+ DOES_NOT_SUPPORT_SSLTCP));
+
+ ASSERT_EQ(expected_settings_list.size(), settings_list.size());
+ for (size_t i = 0; i < settings_list.size(); ++i) {
+ EXPECT_TRUE(settings_list[i].Equals(expected_settings_list[i]));
+ }
+}
+
+} // namespace
+
+} // namespace notifier
diff --git a/jingle/notifier/communicator/login.cc b/jingle/notifier/communicator/login.cc
index bc960b5..886ea84 100644
--- a/jingle/notifier/communicator/login.cc
+++ b/jingle/notifier/communicator/login.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,9 +9,6 @@
#include "base/logging.h"
#include "base/rand_util.h"
#include "base/time.h"
-#include "jingle/notifier/communicator/connection_options.h"
-#include "jingle/notifier/communicator/login_settings.h"
-#include "jingle/notifier/communicator/single_login_attempt.h"
#include "net/base/host_port_pair.h"
#include "talk/base/common.h"
#include "talk/base/firewallsocketserver.h"
@@ -32,20 +29,17 @@ static const int kRedirectTimeoutMinutes = 5;
Login::Login(Delegate* delegate,
const buzz::XmppClientSettings& user_settings,
- const ConnectionOptions& options,
const scoped_refptr<net::URLRequestContextGetter>&
request_context_getter,
const ServerList& servers,
bool try_ssltcp_first,
const std::string& auth_mechanism)
: delegate_(delegate),
- login_settings_(new LoginSettings(user_settings,
- options,
- request_context_getter,
- servers,
- try_ssltcp_first,
- auth_mechanism)),
- redirect_port_(0) {
+ login_settings_(user_settings,
+ request_context_getter,
+ servers,
+ try_ssltcp_first,
+ auth_mechanism) {
net::NetworkChangeNotifier::AddIPAddressObserver(this);
ResetReconnectState();
}
@@ -55,25 +49,12 @@ Login::~Login() {
}
void Login::StartConnection() {
- // If there is a server redirect, use it.
- if (base::Time::Now() <
- (redirect_time_ +
- base::TimeDelta::FromMinutes(kRedirectTimeoutMinutes))) {
- // Override server/port with redirect values.
- DCHECK_NE(redirect_port_, 0);
- net::HostPortPair server_override(redirect_server_, redirect_port_);
- login_settings_->set_server_override(server_override);
- } else {
- login_settings_->clear_server_override();
- }
-
VLOG(1) << "Starting connection...";
-
- single_attempt_.reset(new SingleLoginAttempt(login_settings_.get(), this));
+ single_attempt_.reset(new SingleLoginAttempt(login_settings_, this));
}
void Login::UpdateXmppSettings(const buzz::XmppClientSettings& user_settings) {
- *(login_settings_->modifiable_user_settings()) = user_settings;
+ login_settings_.set_user_settings(user_settings);
}
void Login::OnConnect(base::WeakPtr<buzz::XmppTaskParentInterface> base_task) {
@@ -85,13 +66,8 @@ void Login::OnNeedReconnect() {
TryReconnect();
}
-void Login::OnRedirect(const std::string& redirect_server, int redirect_port) {
- DCHECK_NE(redirect_port_, 0);
-
- redirect_time_ = base::Time::Now();
- redirect_server_ = redirect_server;
- redirect_port_ = redirect_port;
-
+void Login::OnRedirect(const ServerInformation& redirect_server) {
+ login_settings_.SetRedirectServer(redirect_server);
// Drop the current connection, and start the login process again.
StartConnection();
}
diff --git a/jingle/notifier/communicator/login.h b/jingle/notifier/communicator/login.h
index d3bbfd4..d0667b1 100644
--- a/jingle/notifier/communicator/login.h
+++ b/jingle/notifier/communicator/login.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,6 +14,7 @@
#include "base/time.h"
#include "base/timer.h"
#include "jingle/notifier/base/server_information.h"
+#include "jingle/notifier/communicator/login_settings.h"
#include "jingle/notifier/communicator/single_login_attempt.h"
#include "net/base/network_change_notifier.h"
#include "talk/xmpp/xmppengine.h"
@@ -30,7 +31,6 @@ class URLRequestContextGetter;
namespace notifier {
-class ConnectionOptions;
class LoginSettings;
// Workaround for MSVS 2005 bug that fails to handle inheritance from a nested
@@ -52,11 +52,9 @@ class Login : public net::NetworkChangeNotifier::IPAddressObserver,
virtual void OnDisconnect() = 0;
};
- // Does not take ownership of |delegate|, |host_resolver|, |cert_verifier|,
- // or |server_list|, none of which may be NULL.
+ // Does not take ownership of |delegate|, which must not be NULL.
Login(Delegate* delegate,
const buzz::XmppClientSettings& user_settings,
- const ConnectionOptions& options,
const scoped_refptr<net::URLRequestContextGetter>&
request_context_getter,
const ServerList& servers,
@@ -76,8 +74,7 @@ class Login : public net::NetworkChangeNotifier::IPAddressObserver,
virtual void OnConnect(
base::WeakPtr<buzz::XmppTaskParentInterface> base_task) OVERRIDE;
virtual void OnNeedReconnect() OVERRIDE;
- virtual void OnRedirect(const std::string& redirect_server,
- int redirect_port) OVERRIDE;
+ virtual void OnRedirect(const ServerInformation& redirect_server) OVERRIDE;
private:
void OnLogoff();
@@ -94,19 +91,14 @@ class Login : public net::NetworkChangeNotifier::IPAddressObserver,
// reconnection.
void DoReconnect();
- Delegate* delegate_;
- scoped_ptr<LoginSettings> login_settings_;
+ Delegate* const delegate_;
+ LoginSettings login_settings_;
scoped_ptr<SingleLoginAttempt> single_attempt_;
// reconnection state.
base::TimeDelta reconnect_interval_;
base::OneShotTimer<Login> reconnect_timer_;
- // server redirect information
- base::Time redirect_time_;
- std::string redirect_server_;
- int redirect_port_;
-
DISALLOW_COPY_AND_ASSIGN(Login);
};
diff --git a/jingle/notifier/communicator/login_settings.cc b/jingle/notifier/communicator/login_settings.cc
index f36e739..762d96c 100644
--- a/jingle/notifier/communicator/login_settings.cc
+++ b/jingle/notifier/communicator/login_settings.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,44 +8,65 @@
#include "base/logging.h"
#include "jingle/notifier/base/server_information.h"
-#include "jingle/notifier/communicator/connection_options.h"
-#include "jingle/notifier/communicator/xmpp_connection_generator.h"
#include "net/base/cert_verifier.h"
#include "talk/base/common.h"
#include "talk/base/socketaddress.h"
-#include "talk/xmpp/xmppclientsettings.h"
namespace notifier {
LoginSettings::LoginSettings(const buzz::XmppClientSettings& user_settings,
- const ConnectionOptions& options,
const scoped_refptr<net::URLRequestContextGetter>&
request_context_getter,
- const ServerList& servers,
+ const ServerList& default_servers,
bool try_ssltcp_first,
const std::string& auth_mechanism)
- : try_ssltcp_first_(try_ssltcp_first),
- request_context_getter_(request_context_getter),
- servers_(servers),
- user_settings_(new buzz::XmppClientSettings(user_settings)),
- connection_options_(new ConnectionOptions(options)),
- auth_mechanism_(auth_mechanism) {
- DCHECK_GT(servers_.size(), 0u);
+ : user_settings_(user_settings),
+ request_context_getter_(request_context_getter),
+ default_servers_(default_servers),
+ try_ssltcp_first_(try_ssltcp_first),
+ auth_mechanism_(auth_mechanism) {
+ DCHECK_GT(default_servers_.size(), 0u);
}
-// Defined so that the destructors are executed here (and the corresponding
-// classes don't need to be included in the header file).
-LoginSettings::~LoginSettings() {
+LoginSettings::~LoginSettings() {}
+
+void LoginSettings::set_user_settings(
+ const buzz::XmppClientSettings& user_settings) {
+ user_settings_ = user_settings;
+}
+
+ServerList LoginSettings::GetServers() const {
+ return GetServersForTime(base::Time::Now());
+}
+
+namespace {
+
+// How long a redirect is valid for.
+const int kRedirectExpirationTimeMinutes = 5;
+
+} // namespace
+
+void LoginSettings::SetRedirectServer(
+ const ServerInformation& redirect_server) {
+ redirect_server_ = redirect_server;
+ redirect_expiration_ =
+ base::Time::Now() +
+ base::TimeDelta::FromMinutes(kRedirectExpirationTimeMinutes);
+}
+
+ServerList LoginSettings::GetServersForTimeForTest(base::Time now) const {
+ return GetServersForTime(now);
}
-void LoginSettings::set_server_override(
- const net::HostPortPair& server) {
- server_override_.reset(
- new ServerInformation(server, servers_[0].special_port_magic));
+base::Time LoginSettings::GetRedirectExpirationForTest() const {
+ return redirect_expiration_;
}
-void LoginSettings::clear_server_override() {
- server_override_.reset();
+ServerList LoginSettings::GetServersForTime(base::Time now) const {
+ return
+ (now < redirect_expiration_) ?
+ ServerList(1, redirect_server_) :
+ default_servers_;
}
} // namespace notifier
diff --git a/jingle/notifier/communicator/login_settings.h b/jingle/notifier/communicator/login_settings.h
index 7899cef..7ccc109 100644
--- a/jingle/notifier/communicator/login_settings.h
+++ b/jingle/notifier/communicator/login_settings.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,74 +7,68 @@
#include <string>
#include "base/memory/ref_counted.h"
+#include "base/time.h"
#include "jingle/notifier/base/server_information.h"
-#include "jingle/notifier/communicator/xmpp_connection_generator.h"
#include "net/url_request/url_request_context_getter.h"
-
-namespace buzz {
-class XmppClientSettings;
-}
+#include "talk/xmpp/xmppclientsettings.h"
namespace notifier {
-class ConnectionOptions;
class LoginSettings {
public:
LoginSettings(const buzz::XmppClientSettings& user_settings,
- const ConnectionOptions& options,
const scoped_refptr<net::URLRequestContextGetter>&
request_context_getter,
- const ServerList& servers,
+ const ServerList& default_servers,
bool try_ssltcp_first,
const std::string& auth_mechanism);
~LoginSettings();
- bool try_ssltcp_first() const {
- return try_ssltcp_first_;
+ // Copy constructor and assignment operator welcome.
+
+ const buzz::XmppClientSettings& user_settings() const {
+ return user_settings_;
}
- scoped_refptr<net::URLRequestContextGetter> request_context_getter() {
+ void set_user_settings(const buzz::XmppClientSettings& user_settings);
+
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter() const {
return request_context_getter_;
}
- ServerList servers() const {
- return
- server_override_.get() ? ServerList(1, *server_override_) : servers_;
+ bool try_ssltcp_first() const {
+ return try_ssltcp_first_;
}
- const buzz::XmppClientSettings& user_settings() const {
- return *user_settings_.get();
+ const std::string& auth_mechanism() const {
+ return auth_mechanism_;
}
- buzz::XmppClientSettings* modifiable_user_settings() {
- return user_settings_.get();
- }
+ ServerList GetServers() const;
- const ConnectionOptions& connection_options() const {
- return *connection_options_.get();
- }
+ // The redirect server will eventually expire.
+ void SetRedirectServer(const ServerInformation& redirect_server);
- void set_server_override(const net::HostPortPair& server);
- void clear_server_override();
+ ServerList GetServersForTimeForTest(base::Time now) const;
- std::string auth_mechanism() const {
- return auth_mechanism_;
- }
+ base::Time GetRedirectExpirationForTest() const;
private:
- bool try_ssltcp_first_;
+ ServerList GetServersForTime(base::Time now) const;
+ buzz::XmppClientSettings user_settings_;
scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
- const ServerList servers_;
- // Used to handle redirects
- scoped_ptr<ServerInformation> server_override_;
-
- scoped_ptr<buzz::XmppClientSettings> user_settings_;
- scoped_ptr<ConnectionOptions> connection_options_;
+ ServerList default_servers_;
+ bool try_ssltcp_first_;
std::string auth_mechanism_;
- DISALLOW_COPY_AND_ASSIGN(LoginSettings);
+ // Used to handle redirects
+ ServerInformation redirect_server_;
+ base::Time redirect_expiration_;
+
};
+
} // namespace notifier
+
#endif // JINGLE_NOTIFIER_COMMUNICATOR_LOGIN_SETTINGS_H_
diff --git a/jingle/notifier/communicator/login_settings_unittest.cc b/jingle/notifier/communicator/login_settings_unittest.cc
new file mode 100644
index 0000000..5919d1d
--- /dev/null
+++ b/jingle/notifier/communicator/login_settings_unittest.cc
@@ -0,0 +1,77 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "jingle/notifier/communicator/login_settings.h"
+
+#include <cstddef>
+
+#include "talk/xmpp/xmppclientsettings.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace notifier {
+
+namespace {
+
+const char kAuthMechanism[] = "auth_mechanism";
+
+class LoginSettingsTest : public ::testing::Test {
+ protected:
+ LoginSettingsTest() {
+ servers_.push_back(
+ ServerInformation(
+ net::HostPortPair("default.com", 100),
+ DOES_NOT_SUPPORT_SSLTCP));
+ }
+
+ ServerList servers_;
+};
+
+TEST_F(LoginSettingsTest, Basic) {
+ const LoginSettings login_settings(buzz::XmppClientSettings(),
+ NULL,
+ servers_,
+ false /* try_ssltcp_first */,
+ kAuthMechanism);
+ EXPECT_EQ(base::Time(), login_settings.GetRedirectExpirationForTest());
+ const ServerList& servers = login_settings.GetServers();
+ ASSERT_EQ(servers_.size(), servers.size());
+ for (size_t i = 0; i < servers.size(); ++i) {
+ EXPECT_TRUE(servers[i].Equals(servers_[i]));
+ }
+}
+
+TEST_F(LoginSettingsTest, Redirect) {
+ LoginSettings login_settings(buzz::XmppClientSettings(),
+ NULL,
+ servers_,
+ false /* try_ssltcp_first */,
+ kAuthMechanism);
+ const ServerInformation redirect_server(
+ net::HostPortPair("redirect.com", 200),
+ SUPPORTS_SSLTCP);
+ login_settings.SetRedirectServer(redirect_server);
+
+ {
+ const ServerList& servers =
+ login_settings.GetServersForTimeForTest(
+ login_settings.GetRedirectExpirationForTest() -
+ base::TimeDelta::FromMilliseconds(1));
+ ASSERT_EQ(servers_.size(), 1u);
+ EXPECT_TRUE(servers[0].Equals(redirect_server));
+ }
+
+ {
+ const ServerList& servers =
+ login_settings.GetServersForTimeForTest(
+ login_settings.GetRedirectExpirationForTest());
+ ASSERT_EQ(servers_.size(), servers.size());
+ for (size_t i = 0; i < servers.size(); ++i) {
+ EXPECT_TRUE(servers[i].Equals(servers_[i]));
+ }
+ }
+}
+
+} // namespace
+
+} // namespace notifier
diff --git a/jingle/notifier/communicator/single_login_attempt.cc b/jingle/notifier/communicator/single_login_attempt.cc
index 3088f6e..dfaa03a 100644
--- a/jingle/notifier/communicator/single_login_attempt.cc
+++ b/jingle/notifier/communicator/single_login_attempt.cc
@@ -1,50 +1,40 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <algorithm>
-#include <cstddef>
#include <string>
-#include <vector>
#include "jingle/notifier/communicator/single_login_attempt.h"
-#include "base/compiler_specific.h"
+#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/string_number_conversions.h"
+#include "base/string_split.h"
#include "jingle/notifier/base/const_communicator.h"
#include "jingle/notifier/base/gaia_token_pre_xmpp_auth.h"
-#include "jingle/notifier/communicator/connection_options.h"
-#include "jingle/notifier/communicator/connection_settings.h"
-#include "jingle/notifier/communicator/login_settings.h"
#include "jingle/notifier/listener/xml_element_util.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_context_getter.h"
+#include "net/base/host_port_pair.h"
#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/xmppclient.h"
-#include "talk/xmpp/xmppclientsettings.h"
#include "talk/xmpp/constants.h"
-
-namespace net {
-class NetLog;
-} // namespace net
+#include "talk/xmpp/xmppclientsettings.h"
namespace notifier {
-SingleLoginAttempt::SingleLoginAttempt(LoginSettings* login_settings,
+SingleLoginAttempt::Delegate::~Delegate() {}
+
+SingleLoginAttempt::SingleLoginAttempt(const LoginSettings& login_settings,
Delegate* delegate)
: login_settings_(login_settings),
delegate_(delegate),
- connection_generator_(
- ALLOW_THIS_IN_INITIALIZER_LIST(this),
- login_settings_->request_context_getter()->GetURLRequestContext()->
- host_resolver(),
- &login_settings_->connection_options(),
- login_settings_->try_ssltcp_first(),
- login_settings_->servers()) {
- // DNS resolution will happen at a lower layer (we are using the socket
- // pools).
- connection_generator_.SetShouldResolveDNS(false);
- connection_generator_.StartGenerating();
+ settings_list_(
+ MakeConnectionSettingsList(login_settings_.GetServers(),
+ login_settings_.try_ssltcp_first())),
+ current_settings_(settings_list_.begin()) {
+ if (settings_list_.empty()) {
+ NOTREACHED();
+ return;
+ }
+ TryConnect(*current_settings_);
}
SingleLoginAttempt::~SingleLoginAttempt() {}
@@ -54,15 +44,64 @@ void SingleLoginAttempt::OnConnect(
delegate_->OnConnect(base_task);
}
+namespace {
+
+// This function is more permissive than
+// net::HostPortPair::FromString(). If the port is missing or
+// unparseable, it assumes the default XMPP port. The hostname may be
+// empty.
+net::HostPortPair ParseRedirectText(const std::string& redirect_text) {
+ std::vector<std::string> parts;
+ base::SplitString(redirect_text, ':', &parts);
+ net::HostPortPair redirect_server;
+ redirect_server.set_port(kDefaultXmppPort);
+ if (parts.empty()) {
+ return redirect_server;
+ }
+ redirect_server.set_host(parts[0]);
+ if (parts.size() <= 1) {
+ return redirect_server;
+ }
+ // Try to parse the port, falling back to kDefaultXmppPort.
+ int port = kDefaultXmppPort;
+ if (!base::StringToInt(parts[1], &port)) {
+ port = kDefaultXmppPort;
+ }
+ if (port <= 0 || port > kuint16max) {
+ port = kDefaultXmppPort;
+ }
+ redirect_server.set_port(port);
+ return redirect_server;
+}
+
+} // namespace
+
void SingleLoginAttempt::OnError(buzz::XmppEngine::Error error, int subcode,
const buzz::XmlElement* stream_error) {
- VLOG(1) << "Error: " << error << ", subcode: " << subcode;
- if (stream_error) {
- DCHECK_EQ(error, buzz::XmppEngine::ERROR_STREAM);
- VLOG(1) << "Stream error: " << XmlElementToString(*stream_error);
- }
+ DVLOG(1) << "Error: " << error << ", subcode: " << subcode
+ << (stream_error ?
+ (", stream error: " + XmlElementToString(*stream_error)) :
+ "");
- // Check for redirection.
+ DCHECK_EQ(error == buzz::XmppEngine::ERROR_STREAM, stream_error != NULL);
+
+ // Check for redirection. We expect something like:
+ //
+ // <stream:error><see-other-host xmlns="urn:ietf:params:xml:ns:xmpp-streams"/><str:text xmlns:str="urn:ietf:params:xml:ns:xmpp-streams">talk.google.com</str:text></stream:error> [2]
+ //
+ // There are some differences from the spec [1]:
+ //
+ // - we expect a separate text element with the redirection info
+ // (which is the format Google Talk's servers use), whereas the
+ // spec puts the redirection info directly in the see-other-host
+ // element;
+ // - we check for redirection only during login, whereas the
+ // server can send down a redirection at any time according to
+ // the spec. (TODO(akalin): Figure out whether we need to handle
+ // redirection at any other point.)
+ //
+ // [1]: http://xmpp.org/internet-drafts/draft-saintandre-rfc3920bis-08.html#streams-error-conditions-see-other-host
+ // [2]: http://forums.miranda-im.org/showthread.php?24376-GoogleTalk-drops
if (stream_error) {
const buzz::XmlElement* other =
stream_error->FirstNamed(buzz::QN_XSTREAM_SEE_OTHER_HOST);
@@ -73,38 +112,45 @@ void SingleLoginAttempt::OnError(buzz::XmppEngine::Error error, int subcode,
// Yep, its a "stream:error" with "see-other-host" text,
// let's parse out the server:port, and then reconnect
// with that.
- const std::string& redirect = text->BodyText();
- size_t colon = redirect.find(":");
- int redirect_port = kDefaultXmppPort;
- std::string redirect_server;
- if (colon == std::string::npos) {
- redirect_server = redirect;
- } else {
- redirect_server = redirect.substr(0, colon);
- const std::string& port_text = redirect.substr(colon + 1);
- std::istringstream ist(port_text);
- ist >> redirect_port;
- }
- // We never allow a redirect to port 0.
- if (redirect_port == 0) {
- redirect_port = kDefaultXmppPort;
+ const net::HostPortPair& redirect_server =
+ ParseRedirectText(text->BodyText());
+ // ParseRedirectText shouldn't return a zero port.
+ DCHECK_NE(redirect_server.port(), 0u);
+ // If we don't have a host, ignore the redirection and treat
+ // it like a regular error.
+ if (!redirect_server.host().empty()) {
+ delegate_->OnRedirect(
+ ServerInformation(
+ redirect_server,
+ current_settings_->ssltcp_support));
+ // May be deleted at this point.
+ return;
}
- delegate_->OnRedirect(redirect_server, redirect_port);
- // May be deleted at this point.
- return;
}
}
}
- // Iterate to the next possible connection (still trying to connect).
- connection_generator_.UseNextConnection();
+ if (current_settings_ == settings_list_.end()) {
+ NOTREACHED();
+ return;
+ }
+
+ ++current_settings_;
+ if (current_settings_ == settings_list_.end()) {
+ VLOG(1) << "Could not connect to any XMPP server";
+ delegate_->OnNeedReconnect();
+ return;
+ }
+
+ TryConnect(*current_settings_);
}
-void SingleLoginAttempt::OnNewSettings(
+void SingleLoginAttempt::TryConnect(
const ConnectionSettings& connection_settings) {
- buzz::XmppClientSettings client_settings =
- login_settings_->user_settings();
- // Fill in the rest of the client settings.
+ DVLOG(1) << "Trying to connect to " << connection_settings.ToString();
+ // Copy the user settings and fill in the connection parameters from
+ // |connection_settings|.
+ buzz::XmppClientSettings client_settings = login_settings_.user_settings();
connection_settings.FillXmppClientSettings(&client_settings);
buzz::Jid jid(client_settings.user(), client_settings.host(),
@@ -113,20 +159,12 @@ void SingleLoginAttempt::OnNewSettings(
new GaiaTokenPreXmppAuth(
jid.Str(), client_settings.auth_cookie(),
client_settings.token_service(),
- login_settings_->auth_mechanism());
+ login_settings_.auth_mechanism());
xmpp_connection_.reset(
new XmppConnection(client_settings,
- login_settings_->request_context_getter(),
- this, pre_xmpp_auth));
-}
-
-void SingleLoginAttempt::OnExhaustedSettings(
- bool successfully_resolved_dns,
- int first_dns_error) {
- if (!successfully_resolved_dns)
- VLOG(1) << "Could not resolve DNS: " << first_dns_error;
- VLOG(1) << "Could not connect to any XMPP server";
- delegate_->OnNeedReconnect();
+ login_settings_.request_context_getter(),
+ this,
+ pre_xmpp_auth));
}
} // namespace notifier
diff --git a/jingle/notifier/communicator/single_login_attempt.h b/jingle/notifier/communicator/single_login_attempt.h
index 2bdab1f..1e0332d 100644
--- a/jingle/notifier/communicator/single_login_attempt.h
+++ b/jingle/notifier/communicator/single_login_attempt.h
@@ -1,16 +1,15 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef JINGLE_NOTIFIER_COMMUNICATOR_SINGLE_LOGIN_ATTEMPT_H_
#define JINGLE_NOTIFIER_COMMUNICATOR_SINGLE_LOGIN_ATTEMPT_H_
-#include <string>
-
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "jingle/notifier/base/xmpp_connection.h"
-#include "jingle/notifier/communicator/xmpp_connection_generator.h"
+#include "jingle/notifier/communicator/connection_settings.h"
+#include "jingle/notifier/communicator/login_settings.h"
#include "talk/xmpp/xmppengine.h"
namespace buzz {
@@ -19,30 +18,27 @@ class XmppTaskParentInterface;
namespace notifier {
-class ConnectionSettings;
-class LoginSettings;
+struct ServerInformation;
-// Handles all of the aspects of a single login attempt (across multiple ip
-// addresses) and maintainence. By containing this within one class, when
-// another login attempt is made, this class will be disposed and all of the
-// signalling for the previous login attempt will be cleaned up immediately.
-class SingleLoginAttempt : public XmppConnection::Delegate,
- public XmppConnectionGenerator::Delegate {
+// Handles all of the aspects of a single login attempt. By
+// containing this within one class, when another login attempt is
+// made, this class can be destroyed to immediately stop the previous
+// login attempt.
+class SingleLoginAttempt : public XmppConnection::Delegate {
public:
class Delegate {
public:
- virtual ~Delegate() {}
-
virtual void OnConnect(
base::WeakPtr<buzz::XmppTaskParentInterface> base_task) = 0;
virtual void OnNeedReconnect() = 0;
- virtual void OnRedirect(const std::string& redirect_server,
- int redirect_port) = 0;
+ virtual void OnRedirect(const ServerInformation& redirect_server) = 0;
+
+ protected:
+ virtual ~Delegate();
};
- // Does not take ownership of |login_settings| or |delegate|.
- // Neither may be NULL.
- SingleLoginAttempt(LoginSettings* login_settings, Delegate* delegate);
+ // Does not take ownership of |delegate|, which must not be NULL.
+ SingleLoginAttempt(const LoginSettings& login_settings, Delegate* delegate);
virtual ~SingleLoginAttempt();
@@ -53,15 +49,13 @@ class SingleLoginAttempt : public XmppConnection::Delegate,
int error_subcode,
const buzz::XmlElement* stream_error) OVERRIDE;
- // XmppConnectionGenerator::Delegate implementation.
- virtual void OnNewSettings(const ConnectionSettings& new_settings) OVERRIDE;
- virtual void OnExhaustedSettings(bool successfully_resolved_dns,
- int first_dns_error) OVERRIDE;
-
private:
- LoginSettings* login_settings_;
- Delegate* delegate_;
- XmppConnectionGenerator connection_generator_;
+ void TryConnect(const ConnectionSettings& new_settings);
+
+ const LoginSettings login_settings_;
+ Delegate* const delegate_;
+ const ConnectionSettingsList settings_list_;
+ ConnectionSettingsList::const_iterator current_settings_;
scoped_ptr<XmppConnection> xmpp_connection_;
DISALLOW_COPY_AND_ASSIGN(SingleLoginAttempt);
diff --git a/jingle/notifier/communicator/single_login_attempt_unittest.cc b/jingle/notifier/communicator/single_login_attempt_unittest.cc
new file mode 100644
index 0000000..83f81ff
--- /dev/null
+++ b/jingle/notifier/communicator/single_login_attempt_unittest.cc
@@ -0,0 +1,226 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "jingle/notifier/communicator/single_login_attempt.h"
+
+#include <cstddef>
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop.h"
+#include "jingle/notifier/base/const_communicator.h"
+#include "jingle/notifier/base/fake_base_task.h"
+#include "jingle/notifier/communicator/login_settings.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "talk/xmllite/xmlelement.h"
+#include "talk/xmpp/constants.h"
+#include "talk/xmpp/xmppengine.h"
+
+namespace buzz {
+class XmppTaskParentInterface;
+} // namespace buzz
+
+namespace notifier {
+
+namespace {
+
+enum DelegateState { IDLE, CONNECTED, NEED_RECONNECT, REDIRECTED };
+
+class FakeDelegate : public SingleLoginAttempt::Delegate {
+ public:
+ FakeDelegate() : state_(IDLE) {}
+
+ void OnConnect(base::WeakPtr<buzz::XmppTaskParentInterface> base_task) {
+ state_ = CONNECTED;
+ base_task_ = base_task;
+ }
+
+ virtual void OnNeedReconnect() {
+ state_ = NEED_RECONNECT;
+ }
+
+ virtual void OnRedirect(const ServerInformation& redirect_server) OVERRIDE {
+ state_ = REDIRECTED;
+ redirect_server_ = redirect_server;
+ }
+
+ DelegateState state() const { return state_; }
+
+ base::WeakPtr<buzz::XmppTaskParentInterface> base_task() const {
+ return base_task_;
+ }
+
+ const ServerInformation& redirect_server() const {
+ return redirect_server_;
+ }
+
+ private:
+ DelegateState state_;
+ base::WeakPtr<buzz::XmppTaskParentInterface> base_task_;
+ ServerInformation redirect_server_;
+};
+
+class SingleLoginAttemptTest : public ::testing::Test {
+ protected:
+ SingleLoginAttemptTest()
+ : login_settings_(
+ buzz::XmppClientSettings(),
+ new TestURLRequestContextGetter(base::MessageLoopProxy::current()),
+ ServerList(
+ 1,
+ ServerInformation(
+ net::HostPortPair("example.com", 100), SUPPORTS_SSLTCP)),
+ false /* try_ssltcp_first */,
+ "auth_mechanism"),
+ attempt_(login_settings_, &fake_delegate_) {}
+
+ virtual void TearDown() OVERRIDE {
+ message_loop_.RunAllPending();
+ }
+
+ void FireRedirect(buzz::XmlElement* redirect_error) {
+ attempt_.OnError(buzz::XmppEngine::ERROR_STREAM, 0, redirect_error);
+ }
+
+ private:
+ MessageLoop message_loop_;
+ const LoginSettings login_settings_;
+
+ protected:
+ SingleLoginAttempt attempt_;
+ FakeDelegate fake_delegate_;
+ FakeBaseTask fake_base_task_;
+};
+
+// Fire OnConnect and make sure the base task gets passed to the
+// delegate properly.
+TEST_F(SingleLoginAttemptTest, Basic) {
+ attempt_.OnConnect(fake_base_task_.AsWeakPtr());
+ EXPECT_EQ(CONNECTED, fake_delegate_.state());
+ EXPECT_EQ(fake_base_task_.AsWeakPtr().get(),
+ fake_delegate_.base_task().get());
+}
+
+// Fire OnErrors and make sure the delegate gets the OnNeedReconnect()
+// event.
+TEST_F(SingleLoginAttemptTest, Error) {
+ for (int i = 0; i < 2; ++i) {
+ EXPECT_EQ(IDLE, fake_delegate_.state());
+ attempt_.OnError(buzz::XmppEngine::ERROR_NONE, 0, NULL);
+ }
+ EXPECT_EQ(NEED_RECONNECT, fake_delegate_.state());
+}
+
+// Fire OnErrors but replace the last one with OnConnect, and make
+// sure the delegate still gets the OnConnect message.
+TEST_F(SingleLoginAttemptTest, ErrorThenSuccess) {
+ attempt_.OnError(buzz::XmppEngine::ERROR_NONE, 0, NULL);
+ attempt_.OnConnect(fake_base_task_.AsWeakPtr());
+ EXPECT_EQ(CONNECTED, fake_delegate_.state());
+ EXPECT_EQ(fake_base_task_.AsWeakPtr().get(),
+ fake_delegate_.base_task().get());
+}
+
+buzz::XmlElement* MakeRedirectError(const std::string& redirect_server) {
+ buzz::XmlElement* stream_error =
+ new buzz::XmlElement(buzz::QN_STREAM_ERROR, true);
+ stream_error->AddElement(
+ new buzz::XmlElement(buzz::QN_XSTREAM_SEE_OTHER_HOST, true));
+ buzz::XmlElement* text =
+ new buzz::XmlElement(buzz::QN_XSTREAM_TEXT, true);
+ stream_error->AddElement(text);
+ text->SetBodyText(redirect_server);
+ return stream_error;
+}
+
+// Fire a redirect and make sure the delegate gets the proper redirect
+// server info.
+TEST_F(SingleLoginAttemptTest, Redirect) {
+ const ServerInformation redirect_server(
+ net::HostPortPair("example.com", 1000),
+ SUPPORTS_SSLTCP);
+
+ scoped_ptr<buzz::XmlElement> redirect_error(
+ MakeRedirectError(redirect_server.server.ToString()));
+ FireRedirect(redirect_error.get());
+
+ EXPECT_EQ(REDIRECTED, fake_delegate_.state());
+ EXPECT_TRUE(fake_delegate_.redirect_server().Equals(redirect_server));
+}
+
+// Fire a redirect with the host only and make sure the delegate gets
+// the proper redirect server info with the default XMPP port.
+TEST_F(SingleLoginAttemptTest, RedirectHostOnly) {
+ const ServerInformation redirect_server(
+ net::HostPortPair("example.com", kDefaultXmppPort),
+ SUPPORTS_SSLTCP);
+
+ scoped_ptr<buzz::XmlElement> redirect_error(
+ MakeRedirectError(redirect_server.server.host()));
+ FireRedirect(redirect_error.get());
+
+ EXPECT_EQ(REDIRECTED, fake_delegate_.state());
+ EXPECT_TRUE(fake_delegate_.redirect_server().Equals(redirect_server));
+}
+
+// Fire a redirect with a zero port and make sure the delegate gets
+// the proper redirect server info with the default XMPP port.
+TEST_F(SingleLoginAttemptTest, RedirectZeroPort) {
+ const ServerInformation redirect_server(
+ net::HostPortPair("example.com", kDefaultXmppPort),
+ SUPPORTS_SSLTCP);
+
+ scoped_ptr<buzz::XmlElement> redirect_error(
+ MakeRedirectError(redirect_server.server.host() + ":0"));
+ FireRedirect(redirect_error.get());
+
+ EXPECT_EQ(REDIRECTED, fake_delegate_.state());
+ EXPECT_TRUE(fake_delegate_.redirect_server().Equals(redirect_server));
+}
+
+// Fire a redirect with an invalid port and make sure the delegate
+// gets the proper redirect server info with the default XMPP port.
+TEST_F(SingleLoginAttemptTest, RedirectInvalidPort) {
+ const ServerInformation redirect_server(
+ net::HostPortPair("example.com", kDefaultXmppPort),
+ SUPPORTS_SSLTCP);
+
+ scoped_ptr<buzz::XmlElement> redirect_error(
+ MakeRedirectError(redirect_server.server.host() + ":invalidport"));
+ FireRedirect(redirect_error.get());
+
+ EXPECT_EQ(REDIRECTED, fake_delegate_.state());
+ EXPECT_TRUE(fake_delegate_.redirect_server().Equals(redirect_server));
+}
+
+// Fire an empty redirect and make sure the delegate does not get a
+// redirect.
+TEST_F(SingleLoginAttemptTest, RedirectEmpty) {
+ scoped_ptr<buzz::XmlElement> redirect_error(MakeRedirectError(""));
+ FireRedirect(redirect_error.get());
+ EXPECT_EQ(IDLE, fake_delegate_.state());
+}
+
+// Fire a redirect with a missing text element and make sure the
+// delegate does not get a redirect.
+TEST_F(SingleLoginAttemptTest, RedirectMissingText) {
+ scoped_ptr<buzz::XmlElement> redirect_error(MakeRedirectError(""));
+ redirect_error->RemoveChildAfter(redirect_error->FirstChild());
+ FireRedirect(redirect_error.get());
+ EXPECT_EQ(IDLE, fake_delegate_.state());
+}
+
+// Fire a redirect with a missing see-other-host element and make sure
+// the delegate does not get a redirect.
+TEST_F(SingleLoginAttemptTest, RedirectMissingSeeOtherHost) {
+ scoped_ptr<buzz::XmlElement> redirect_error(MakeRedirectError(""));
+ redirect_error->RemoveChildAfter(NULL);
+ FireRedirect(redirect_error.get());
+ EXPECT_EQ(IDLE, fake_delegate_.state());
+}
+
+} // namespace
+
+} // namespace notifier
diff --git a/jingle/notifier/communicator/xmpp_connection_generator.cc b/jingle/notifier/communicator/xmpp_connection_generator.cc
deleted file mode 100644
index 3611dae0..0000000
--- a/jingle/notifier/communicator/xmpp_connection_generator.cc
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// XmppConnectionGenerator does the following algorithm:
-// proxy = ResolveProxyInformation(connection_options)
-// for server in server_list
-// get dns_addresses for server
-// connection_list = (dns_addresses X connection methods X proxy).shuffle()
-// for connection in connection_list
-// yield connection
-
-#include "jingle/notifier/communicator/xmpp_connection_generator.h"
-
-#include <vector>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "base/sys_byteorder.h"
-#include "jingle/notifier/base/server_information.h"
-#include "jingle/notifier/communicator/connection_options.h"
-#include "jingle/notifier/communicator/connection_settings.h"
-#include "net/base/net_errors.h"
-#include "talk/base/httpcommon-inl.h"
-#include "talk/base/task.h"
-#include "talk/base/thread.h"
-#include "talk/xmpp/prexmppauth.h"
-#include "talk/xmpp/xmppclientsettings.h"
-#include "talk/xmpp/xmppengine.h"
-
-namespace notifier {
-
-XmppConnectionGenerator::XmppConnectionGenerator(
- Delegate* delegate,
- net::HostResolver* host_resolver,
- const ConnectionOptions* options,
- bool try_ssltcp_first,
- const ServerList& servers)
- : delegate_(delegate),
- host_resolver_(host_resolver),
- settings_list_(new ConnectionSettingsList()),
- settings_index_(0),
- servers_(servers),
- current_server_(servers_.end()),
- try_ssltcp_first_(try_ssltcp_first),
- successfully_resolved_dns_(false),
- first_dns_error_(0),
- should_resolve_dns_(true),
- options_(options) {
- DCHECK(delegate_);
- DCHECK(host_resolver);
- DCHECK(options_);
- DCHECK_GT(servers_.size(), 0u);
-}
-
-XmppConnectionGenerator::~XmppConnectionGenerator() {
- VLOG(1) << "XmppConnectionGenerator::~XmppConnectionGenerator";
-}
-
-// Starts resolving proxy information.
-void XmppConnectionGenerator::StartGenerating() {
- VLOG(1) << "XmppConnectionGenerator::StartGenerating";
-
- // TODO(akalin): Detect proxy settings once we use Chrome sockets.
-
- // Start iterating through the connections (which are generated on demand).
- UseNextConnection();
-}
-
-namespace {
-
-const char* const PROTO_NAMES[cricket::PROTO_LAST + 1] = {
- "udp", "tcp", "ssltcp"
-};
-
-} // namespace
-
-void XmppConnectionGenerator::UseNextConnection() {
- DCHECK(settings_list_.get());
- // Loop until we can use a connection or we run out of connections
- // to try.
- while (true) {
- // Iterate to the next possible connection.
- settings_index_++;
- if (settings_index_ < settings_list_->GetCount()) {
- // We have more connection settings in the settings_list_ to
- // try, kick off the next one.
- ConnectionSettings* settings =
- settings_list_->GetSettings(settings_index_);
- VLOG(1) << "*** Attempting " << PROTO_NAMES[settings->protocol()]
- << " connection to " << settings->server().IPAsString()
- << ":" << settings->server().port();
- delegate_->OnNewSettings(*settings);
- return;
- }
-
- // Iterate to the next possible server.
- if (current_server_ == servers_.end()) {
- current_server_ = servers_.begin();
- } else {
- ++current_server_;
- }
- if (current_server_ == servers_.end()) {
- // All out of possibilities.
- VLOG(1) << "(" << buzz::XmppEngine::ERROR_SOCKET
- << ", " << first_dns_error_ << ")";
- delegate_->OnExhaustedSettings(
- successfully_resolved_dns_, first_dns_error_);
- return;
- }
-
- if (should_resolve_dns_) {
- // Resolve the server.
- const net::HostPortPair& server = current_server_->server;
- net::HostResolver::RequestInfo request_info(server);
- int status =
- host_resolver_.Resolve(
- request_info, &address_list_,
- base::Bind(&XmppConnectionGenerator::OnServerDNSResolved,
- base::Unretained(this)),
- bound_net_log_);
- if (status == net::ERR_IO_PENDING) // OnServerDNSResolved will be called.
- return;
-
- HandleServerDNSResolved(status);
- } else {
- // We are not resolving DNS here (DNS will be resolved by a lower layer).
- // Generate settings using an empty IP list (which will just use the
- // host name for the current server).
- std::vector<uint32> ip_list;
- GenerateSettingsForIPList(ip_list);
- }
- }
-}
-
-void XmppConnectionGenerator::OnServerDNSResolved(int status) {
- DCHECK_NE(status, net::ERR_IO_PENDING);
- HandleServerDNSResolved(status);
- // Reenter loop.
- UseNextConnection();
-}
-
-void XmppConnectionGenerator::HandleServerDNSResolved(int status) {
- DCHECK_NE(status, net::ERR_IO_PENDING);
- VLOG(1) << "XmppConnectionGenerator::HandleServerDNSResolved";
- // Print logging info.
- VLOG(1) << " server: " << current_server_->server.ToString()
- << ", error: " << status;
- if (status != net::OK) {
- if (first_dns_error_ == 0)
- first_dns_error_ = status;
- return;
- }
-
- // Slurp the addresses into a vector.
- std::vector<uint32> ip_list; // TODO(szym): not IPv6-safe.
- for (size_t i = 0; i < address_list_.size(); ++i) {
- const net::IPEndPoint& addr = address_list_[i];
- DCHECK_EQ(addr.GetFamily(), AF_INET);
- uint32 ip = talk_base::NetworkToHost32(
- *reinterpret_cast<const uint32*>(&addr.address()[0]));
- ip_list.push_back(ip);
- }
- successfully_resolved_dns_ = !ip_list.empty();
-
- for (size_t i = 0; i < ip_list.size(); ++i) {
- VLOG(1) << " ip " << i
- << " : " << talk_base::SocketAddress::IPToString(ip_list[i]);
- }
-
- GenerateSettingsForIPList(ip_list);
-}
-
-void XmppConnectionGenerator::GenerateSettingsForIPList(
- const std::vector<uint32>& ip_list) {
- // Build the ip list.
- DCHECK(settings_list_.get());
- settings_index_ = -1;
- settings_list_->ClearPermutations();
- settings_list_->AddPermutations(
- current_server_->server.host(),
- ip_list,
- current_server_->server.port(),
- current_server_->special_port_magic,
- try_ssltcp_first_);
-}
-
-} // namespace notifier
diff --git a/jingle/notifier/communicator/xmpp_connection_generator.h b/jingle/notifier/communicator/xmpp_connection_generator.h
deleted file mode 100644
index 9f3ad79..0000000
--- a/jingle/notifier/communicator/xmpp_connection_generator.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef JINGLE_NOTIFIER_COMMUNICATOR_XMPP_CONNECTION_GENERATOR_H_
-#define JINGLE_NOTIFIER_COMMUNICATOR_XMPP_CONNECTION_GENERATOR_H_
-
-#include <vector>
-
-#include "base/memory/scoped_ptr.h"
-#include "net/base/address_list.h"
-#include "net/base/host_resolver.h"
-#include "net/base/net_log.h"
-#include "net/base/single_request_host_resolver.h"
-#include "jingle/notifier/base/server_information.h"
-
-namespace notifier {
-
-class ConnectionOptions;
-class ConnectionSettings;
-class ConnectionSettingsList;
-
-// Resolves dns names and iterates through the various ip address and transport
-// combinations.
-class XmppConnectionGenerator {
- public:
- class Delegate {
- public:
- virtual ~Delegate() {}
-
- virtual void OnNewSettings(const ConnectionSettings& new_settings) = 0;
- virtual void OnExhaustedSettings(bool successfully_resolved_dns,
- int first_dns_error) = 0;
- };
-
- // Does not take ownership of |delegate|.
- // |try_ssltcp_first| indicates that SSLTCP is tried before
- // XMPP. Used by tests.
- // |server_list| is the list of connections to attempt in priority order.
- // |server_count| is the number of items in the server list.
- XmppConnectionGenerator(
- Delegate* delegate,
- net::HostResolver* host_resolver,
- const ConnectionOptions* options,
- bool try_ssltcp_first,
- const ServerList& servers);
- ~XmppConnectionGenerator();
-
- // Only call this once. Create a new XmppConnectionGenerator and delete the
- // current one if the process needs to start again.
- void StartGenerating();
-
- void UseNextConnection();
-
- // TODO(sanjeevr): Rip out the DNS resolution code eventually.
- void SetShouldResolveDNS(bool should_resolve_dns) {
- should_resolve_dns_ = should_resolve_dns;
- }
-
- private:
- void OnServerDNSResolved(int status);
- void HandleServerDNSResolved(int status);
- void GenerateSettingsForIPList(const std::vector<uint32>& ip_list);
-
- Delegate* delegate_;
- net::SingleRequestHostResolver host_resolver_;
- net::AddressList address_list_;
- net::BoundNetLog bound_net_log_;
- scoped_ptr<ConnectionSettingsList> settings_list_;
- int settings_index_; // The setting that is currently being used.
- const ServerList servers_;
- ServerList::const_iterator current_server_;
- bool try_ssltcp_first_; // Used when sync tests are run on chromium builders.
- bool successfully_resolved_dns_;
- int first_dns_error_;
- bool should_resolve_dns_;
- const ConnectionOptions* options_;
-
- DISALLOW_COPY_AND_ASSIGN(XmppConnectionGenerator);
-};
-
-} // namespace notifier
-
-#endif // JINGLE_NOTIFIER_COMMUNICATOR_XMPP_CONNECTION_GENERATOR_H_
diff --git a/jingle/notifier/communicator/xmpp_connection_generator_unittest.cc b/jingle/notifier/communicator/xmpp_connection_generator_unittest.cc
deleted file mode 100644
index b57a3c3..0000000
--- a/jingle/notifier/communicator/xmpp_connection_generator_unittest.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "jingle/notifier/communicator/xmpp_connection_generator.h"
-
-#include "base/basictypes.h"
-#include "base/message_loop.h"
-#include "jingle/notifier/communicator/connection_options.h"
-#include "jingle/notifier/communicator/connection_settings.h"
-#include "net/base/host_port_pair.h"
-#include "net/base/mock_host_resolver.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace notifier {
-
-namespace {
-
-using ::testing::_;
-using ::testing::InvokeWithoutArgs;
-
-class MockXmppConnectionGeneratorDelegate
- : public XmppConnectionGenerator::Delegate {
- public:
- MOCK_METHOD1(OnNewSettings, void(const ConnectionSettings&));
- MOCK_METHOD2(OnExhaustedSettings, void(bool, int));
-};
-
-const ServerInformation kXmppServers[] = {
- ServerInformation(net::HostPortPair("www.foo.com", 5222), true),
- ServerInformation(net::HostPortPair("www.bar.com", 8080), false),
- ServerInformation(net::HostPortPair("www.baz.com", 80), true),
-};
-
-class XmppConnectionGeneratorTest : public testing::Test {
- public:
- XmppConnectionGeneratorTest()
- : xmpp_connection_generator_(
- &delegate_,
- &mock_host_resolver_,
- &connection_options_,
- false /* try_ssltcp_first */,
- ServerList(kXmppServers,
- kXmppServers + arraysize(kXmppServers))) {}
-
- virtual ~XmppConnectionGeneratorTest() {}
-
- protected:
- MockXmppConnectionGeneratorDelegate delegate_;
- net::MockHostResolver mock_host_resolver_;
- ConnectionOptions connection_options_;
- XmppConnectionGenerator xmpp_connection_generator_;
-};
-
-TEST_F(XmppConnectionGeneratorTest, DnsFailure) {
- MessageLoop message_loop;
-
- EXPECT_CALL(delegate_, OnNewSettings(_)).Times(0);
- EXPECT_CALL(delegate_, OnExhaustedSettings(_, _)).
- WillOnce(InvokeWithoutArgs(&message_loop, &MessageLoop::Quit));
-
- mock_host_resolver_.rules()->AddSimulatedFailure("*");
- xmpp_connection_generator_.StartGenerating();
- message_loop.Run();
-}
-
-TEST_F(XmppConnectionGeneratorTest, DnsFailureSynchronous) {
- MessageLoop message_loop;
-
- EXPECT_CALL(delegate_, OnNewSettings(_)).Times(0);
- EXPECT_CALL(delegate_, OnExhaustedSettings(_, _)).Times(1);
-
- mock_host_resolver_.set_synchronous_mode(true);
- mock_host_resolver_.rules()->AddSimulatedFailure("*");
- xmpp_connection_generator_.StartGenerating();
-}
-
-TEST_F(XmppConnectionGeneratorTest, ConnectionFailure) {
- MessageLoop message_loop;
-
- EXPECT_CALL(delegate_, OnNewSettings(_)).
- Times(5).
- WillRepeatedly(
- InvokeWithoutArgs(
- &xmpp_connection_generator_,
- &XmppConnectionGenerator::UseNextConnection));
- EXPECT_CALL(delegate_, OnExhaustedSettings(_, _)).
- WillOnce(InvokeWithoutArgs(&message_loop, &MessageLoop::Quit));
-
- xmpp_connection_generator_.StartGenerating();
- message_loop.Run();
-}
-
-TEST_F(XmppConnectionGeneratorTest, ConnectionFailureSynchronous) {
- MessageLoop message_loop;
-
- EXPECT_CALL(delegate_, OnNewSettings(_)).
- Times(5).
- WillRepeatedly(
- InvokeWithoutArgs(
- &xmpp_connection_generator_,
- &XmppConnectionGenerator::UseNextConnection));
- EXPECT_CALL(delegate_, OnExhaustedSettings(_, _)).Times(1);
-
- mock_host_resolver_.set_synchronous_mode(true);
- xmpp_connection_generator_.StartGenerating();
-}
-
-} // namespace
-
-} // namespace notifier
diff --git a/jingle/notifier/listener/mediator_thread_impl.cc b/jingle/notifier/listener/mediator_thread_impl.cc
index ba85ac77..ea6d18d 100644
--- a/jingle/notifier/listener/mediator_thread_impl.cc
+++ b/jingle/notifier/listener/mediator_thread_impl.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,9 +14,7 @@
#include "jingle/notifier/base/const_communicator.h"
#include "jingle/notifier/base/notifier_options_util.h"
#include "jingle/notifier/base/task_pump.h"
-#include "jingle/notifier/communicator/connection_options.h"
#include "jingle/notifier/communicator/login.h"
-#include "jingle/notifier/communicator/xmpp_connection_generator.h"
#include "jingle/notifier/listener/push_notifications_listen_task.h"
#include "jingle/notifier/listener/push_notifications_send_update_task.h"
#include "jingle/notifier/listener/push_notifications_subscribe_task.h"
@@ -99,11 +97,9 @@ void MediatorThreadImpl::Core::Login(const buzz::XmppClientSettings& settings) {
BelongsToCurrentThread());
VLOG(1) << "P2P: Thread logging into talk network.";
- // TODO(sanjeevr): Pass in the URLRequestContextGetter to Login.
base_task_.reset();
login_.reset(new notifier::Login(this,
settings,
- notifier::ConnectionOptions(),
notifier_options_.request_context_getter,
GetServerList(notifier_options_),
notifier_options_.try_ssltcp_first,