This source file includes following definitions.
- current_settings_
- OnConnect
- ParseRedirectText
- OnError
- TryConnect
#include <string>
#include "jingle/notifier/communicator/single_login_attempt.h"
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "jingle/notifier/base/const_communicator.h"
#include "jingle/notifier/base/gaia_token_pre_xmpp_auth.h"
#include "jingle/notifier/listener/xml_element_util.h"
#include "net/base/host_port_pair.h"
#include "talk/xmllite/xmlelement.h"
#include "talk/xmpp/constants.h"
#include "talk/xmpp/xmppclientsettings.h"
namespace notifier {
SingleLoginAttempt::Delegate::~Delegate() {}
SingleLoginAttempt::SingleLoginAttempt(const LoginSettings& login_settings,
Delegate* delegate)
: login_settings_(login_settings),
delegate_(delegate),
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() {}
void SingleLoginAttempt::OnConnect(
base::WeakPtr<buzz::XmppTaskParentInterface> base_task) {
DVLOG(1) << "Connected to " << current_settings_->ToString();
delegate_->OnConnect(base_task);
}
namespace {
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;
}
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;
}
}
void SingleLoginAttempt::OnError(buzz::XmppEngine::Error error, int subcode,
const buzz::XmlElement* stream_error) {
DVLOG(1) << "Error: " << error << ", subcode: " << subcode
<< (stream_error
? (", stream error: " + XmlElementToString(*stream_error))
: std::string());
DCHECK_EQ(error == buzz::XmppEngine::ERROR_STREAM, stream_error != NULL);
if (stream_error) {
const buzz::XmlElement* other =
stream_error->FirstNamed(buzz::QN_XSTREAM_SEE_OTHER_HOST);
if (other) {
const buzz::XmlElement* text =
stream_error->FirstNamed(buzz::QN_XSTREAM_TEXT);
if (text) {
const net::HostPortPair& redirect_server =
ParseRedirectText(text->BodyText());
DCHECK_NE(redirect_server.port(), 0u);
if (!redirect_server.host().empty()) {
delegate_->OnRedirect(
ServerInformation(
redirect_server,
current_settings_->ssltcp_support));
return;
}
}
}
}
if (error == buzz::XmppEngine::ERROR_UNAUTHORIZED) {
DVLOG(1) << "Credentials rejected";
delegate_->OnCredentialsRejected();
return;
}
if (current_settings_ == settings_list_.end()) {
NOTREACHED();
return;
}
++current_settings_;
if (current_settings_ == settings_list_.end()) {
DVLOG(1) << "Could not connect to any XMPP server";
delegate_->OnSettingsExhausted();
return;
}
TryConnect(*current_settings_);
}
void SingleLoginAttempt::TryConnect(
const ConnectionSettings& connection_settings) {
DVLOG(1) << "Trying to connect to " << connection_settings.ToString();
buzz::XmppClientSettings client_settings = login_settings_.user_settings();
connection_settings.FillXmppClientSettings(&client_settings);
buzz::Jid jid(client_settings.user(), client_settings.host(),
buzz::STR_EMPTY);
buzz::PreXmppAuth* pre_xmpp_auth =
new GaiaTokenPreXmppAuth(
jid.Str(), client_settings.auth_token(),
client_settings.token_service(),
login_settings_.auth_mechanism());
xmpp_connection_.reset(
new XmppConnection(client_settings,
login_settings_.request_context_getter(),
this,
pre_xmpp_auth));
}
}