Communi: Handle and forward socket errors. Fixes for example situation when user tries to join the room on server which does not exist.

This commit is contained in:
HanzZ 2013-02-12 09:30:24 +01:00
parent fd4946efe4
commit 58fbe0d388
6 changed files with 48 additions and 6 deletions

View file

@ -95,7 +95,7 @@ MyIrcSession *IRCNetworkPlugin::createSession(const std::string &user, const std
void IRCNetworkPlugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
if (!m_servers.empty()) {
// legacy name is users nickname
// legacy name is user's nickname
if (m_sessions[user] != NULL) {
LOG4CXX_WARN(logger, user << ": Already logged in.");
return;
@ -154,6 +154,10 @@ void IRCNetworkPlugin::handleMessageSendRequest(const std::string &user, const s
}
std::string target = getTargetName(legacyName);
// We are sending PM message. On XMPP side, user is sending PM using the particular channel,
// for example #room@irc.freenode.org/hanzz. On IRC side, we are forwarding this message
// just to "hanzz". Therefore we have to somewhere store, that message from "hanzz" should
// be mapped to #room@irc.freenode.org/hanzz.
if (legacyName.find("/") != std::string::npos) {
m_sessions[session]->addPM(target, legacyName.substr(0, legacyName.find("@")));
}

View file

@ -70,7 +70,31 @@ void MyIrcSession::on_connected() {
}
void MyIrcSession::on_socketError(QAbstractSocket::SocketError error) {
on_disconnected();
std::string reason;
switch(error) {
case QAbstractSocket::ConnectionRefusedError: reason = "The connection was refused by the peer (or timed out)."; break;
case QAbstractSocket::RemoteHostClosedError: reason = "The remote host closed the connection."; break;
case QAbstractSocket::HostNotFoundError: reason = "The host address was not found."; break;
case QAbstractSocket::SocketAccessError: reason = "The socket operation failed because the application lacked the required privileges."; break;
case QAbstractSocket::SocketResourceError: reason = "The local system ran out of resources."; break;
case QAbstractSocket::SocketTimeoutError: reason = "The socket operation timed out."; break;
case QAbstractSocket::DatagramTooLargeError: reason = "The datagram was larger than the operating system's limit."; break;
case QAbstractSocket::NetworkError: reason = "An error occurred with the network."; break;
case QAbstractSocket::SslHandshakeFailedError: reason = "The SSL/TLS handshake failed, so the connection was closed"; break;
case QAbstractSocket::UnknownSocketError: reason = "An unidentified error occurred."; break;
default: reason= "Unknown error."; break;
};
if (!suffix.empty()) {
for(AutoJoinMap::iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) {
np->handleParticipantChanged(user, TO_UTF8(nickName()), it->second->getChannel() + suffix, pbnetwork::PARTICIPANT_FLAG_ROOM_NOT_FOUND, pbnetwork::STATUS_NONE, reason);
}
}
else {
np->handleDisconnected(user, 0, reason);
np->tryNextServer();
}
m_connected = false;
}
void MyIrcSession::on_disconnected() {

View file

@ -69,8 +69,6 @@ public:
MyIrcSession(const std::string &user, IRCNetworkPlugin *np, const std::string &suffix = "", QObject* parent = 0);
virtual ~MyIrcSession();
std::string suffix;
int rooms;
void addAutoJoinChannel(const std::string &channel, const std::string &password) {
m_autoJoin[channel] = boost::make_shared<AutoJoinChannel>(channel, password, 12 + m_autoJoin.size());
@ -81,6 +79,10 @@ public:
removeIRCBuddies(channel);
}
// We are sending PM message. On XMPP side, user is sending PM using the particular channel,
// for example #room@irc.freenode.org/hanzz. On IRC side, we are forwarding this message
// just to "hanzz". Therefore we have to somewhere store, that message from "hanzz" should
// be mapped to #room@irc.freenode.org/hanzz.
void addPM(const std::string &name, const std::string &room) {
m_pms[name] = room;
}
@ -120,6 +122,9 @@ public:
void on_messageReceived(IrcMessage *message);
void on_numericMessageReceived(IrcMessage *message);
std::string suffix;
int rooms;
protected Q_SLOTS:
void on_connected();
void on_disconnected();

View file

@ -40,7 +40,8 @@ class Conversation {
PARTICIPANT_FLAG_BANNED = 4,
PARTICIPANT_FLAG_NOT_AUTHORIZED = 8,
PARTICIPANT_FLAG_ME = 16,
PARTICIPANT_FLAG_KICKED = 32
PARTICIPANT_FLAG_KICKED = 32,
PARTICIPANT_FLAG_ROOM_NOT_FOUD = 64
} ParticipantFlag;
typedef struct _Participant {

View file

@ -95,6 +95,7 @@ enum ParticipantFlag {
PARTICIPANT_FLAG_NOT_AUTHORIZED = 8;
PARTICIPANT_FLAG_ME = 16;
PARTICIPANT_FLAG_KICKED = 32;
PARTICIPANT_FLAG_ROOM_NOT_FOUND = 64;
}
message Participant {

View file

@ -257,7 +257,14 @@ Swift::Presence::ref Conversation::generatePresence(const std::string &nick, int
delete p;
presence->setType(Swift::Presence::Error);
presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::MUCPayload()));
presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::ErrorPayload(Swift::ErrorPayload::NotAuthorized, Swift::ErrorPayload::Auth)));
presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::ErrorPayload(Swift::ErrorPayload::NotAuthorized, Swift::ErrorPayload::Auth, statusMessage)));
return presence;
}
else if (flag & PARTICIPANT_FLAG_ROOM_NOT_FOUD) {
delete p;
presence->setType(Swift::Presence::Error);
presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::MUCPayload()));
presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::ErrorPayload(Swift::ErrorPayload::ItemNotFound, Swift::ErrorPayload::Cancel, statusMessage)));
return presence;
}
else {