Send and receive messages
Also correctly respond to PING with the id, escape some XML content, but not always
This commit is contained in:
@@ -1,18 +0,0 @@
|
||||
#ifndef Stanza
|
||||
# define Stanza
|
||||
|
||||
class Stanza
|
||||
{
|
||||
public:
|
||||
explicit Stanza();
|
||||
~Stanza();
|
||||
private:
|
||||
Stanza(const Stanza&) = delete;
|
||||
Stanza(Stanza&&) = delete;
|
||||
Stanza& operator=(const Stanza&) = delete;
|
||||
Stanza& operator=(Stanza&&) = delete;
|
||||
};
|
||||
|
||||
#endif // Stanza
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ XmppComponent::XmppComponent(const std::string& hostname, const std::string& sec
|
||||
std::bind(&XmppComponent::handle_handshake, this,std::placeholders::_1));
|
||||
this->stanza_handlers.emplace("presence",
|
||||
std::bind(&XmppComponent::handle_presence, this,std::placeholders::_1));
|
||||
this->stanza_handlers.emplace("message",
|
||||
std::bind(&XmppComponent::handle_message, this,std::placeholders::_1));
|
||||
}
|
||||
|
||||
XmppComponent::~XmppComponent()
|
||||
@@ -151,6 +153,20 @@ void XmppComponent::handle_presence(const Stanza& stanza)
|
||||
bridge->join_irc_channel(iid, to.resource);
|
||||
}
|
||||
|
||||
void XmppComponent::handle_message(const Stanza& stanza)
|
||||
{
|
||||
Bridge* bridge = this->get_user_bridge(stanza["from"]);
|
||||
Jid to(stanza["to"]);
|
||||
Iid iid(to.local);
|
||||
XmlNode* body = stanza.get_child("body");
|
||||
if (stanza["type"] == "groupchat")
|
||||
{
|
||||
if (to.resource.empty())
|
||||
if (body && !body->get_inner().empty())
|
||||
bridge->send_channel_message(iid, body->get_inner());
|
||||
}
|
||||
}
|
||||
|
||||
Bridge* XmppComponent::get_user_bridge(const std::string& user_jid)
|
||||
{
|
||||
try
|
||||
@@ -239,3 +255,17 @@ void XmppComponent::send_topic(const std::string& from, const std::string& topic
|
||||
message.close();
|
||||
this->send_stanza(message);
|
||||
}
|
||||
|
||||
void XmppComponent::send_muc_message(const std::string& muc_name, const std::string& nick, const std::string body_str, const std::string& jid_to)
|
||||
{
|
||||
Stanza message("message");
|
||||
message["to"] = jid_to;
|
||||
message["from"] = muc_name + "@" + this->served_hostname + "/" + nick;
|
||||
message["type"] = "groupchat";
|
||||
XmlNode body("body");
|
||||
body.set_inner(body_str);
|
||||
body.close();
|
||||
message.add_child(std::move(body));
|
||||
message.close();
|
||||
this->send_stanza(message);
|
||||
}
|
||||
|
||||
@@ -71,11 +71,16 @@ public:
|
||||
* Send the MUC topic to the user
|
||||
*/
|
||||
void send_topic(const std::string& from, const std::string& topic, const std::string& to);
|
||||
/**
|
||||
* Send a (non-private) message to the MUC
|
||||
*/
|
||||
void send_muc_message(const std::string& muc_name, const std::string& nick, const std::string body_str, const std::string& jid_to);
|
||||
/**
|
||||
* Handle the various stanza types
|
||||
*/
|
||||
void handle_handshake(const Stanza& stanza);
|
||||
void handle_presence(const Stanza& stanza);
|
||||
void handle_message(const Stanza& stanza);
|
||||
|
||||
private:
|
||||
/**
|
||||
|
||||
@@ -2,6 +2,26 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
std::string xml_escape(const std::string& data)
|
||||
{
|
||||
std::string res;
|
||||
buffer.reserve(data.size());
|
||||
for(size_t pos = 0; pos != data.size(); ++pos)
|
||||
{
|
||||
switch(data[pos])
|
||||
{
|
||||
case '&': buffer += "&"; break;
|
||||
case '\"': buffer += """; break;
|
||||
case '\'': buffer += "'"; break;
|
||||
case '<': buffer += "<"; break;
|
||||
case '>': buffer += ">"; break;
|
||||
default: buffer += data[pos]; break;
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
XmlNode::XmlNode(const std::string& name, XmlNode* parent):
|
||||
name(name),
|
||||
parent(parent),
|
||||
@@ -40,7 +60,22 @@ void XmlNode::set_tail(const std::string& data)
|
||||
|
||||
void XmlNode::set_inner(const std::string& data)
|
||||
{
|
||||
this->inner = data;
|
||||
this->inner = xml_escape(data);
|
||||
}
|
||||
|
||||
std::string XmlNode::get_inner() const
|
||||
{
|
||||
return this->inner;
|
||||
}
|
||||
|
||||
XmlNode* XmlNode::get_child(const std::string& name) const
|
||||
{
|
||||
for (auto& child: this->children)
|
||||
{
|
||||
if (child->name == name)
|
||||
return child;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void XmlNode::add_child(XmlNode* child)
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <expatpp.h>
|
||||
|
||||
std::string xml_escape(const std::string& data);
|
||||
|
||||
/**
|
||||
* Raised on operator[] when the attribute does not exist
|
||||
*/
|
||||
@@ -51,8 +53,18 @@ public:
|
||||
void set_tail(const std::string& data);
|
||||
/**
|
||||
* Set the content of the inner, that is the text inside this node
|
||||
* TODO: escape it here.
|
||||
*/
|
||||
void set_inner(const std::string& data);
|
||||
/**
|
||||
* Get the content of inner
|
||||
* TODO: unescape it here.
|
||||
*/
|
||||
std::string get_inner() const;
|
||||
/**
|
||||
* Get a pointer to the first child element with that name
|
||||
*/
|
||||
XmlNode* get_child(const std::string& name) const;
|
||||
void add_child(XmlNode* child);
|
||||
void add_child(XmlNode&& child);
|
||||
XmlNode* get_last_child() const;
|
||||
|
||||
Reference in New Issue
Block a user