From a20c60a0d84f2f22777e3831cac1315302b7a095 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Thu, 10 Apr 2014 20:11:17 +0200 Subject: Messages coming from the IRC server are of type "chat" --- src/bridge/bridge.cpp | 4 ++-- src/xmpp/xmpp_component.cpp | 4 +++- src/xmpp/xmpp_component.hpp | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index 9b7908a..277f696 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -188,7 +188,7 @@ void Bridge::send_message(const Iid& iid, const std::string& nick, const std::st this->make_xmpp_body(body), this->user_jid); else this->xmpp->send_message(iid.chan + "%" + iid.server, - this->make_xmpp_body(body), this->user_jid); + this->make_xmpp_body(body), this->user_jid, "chat"); } void Bridge::send_muc_leave(Iid&& iid, std::string&& nick, const std::string& message, const bool self) @@ -220,7 +220,7 @@ void Bridge::send_xmpp_message(const std::string& from, const std::string& autho body = std::string("[") + author + std::string("] ") + msg; else body = msg; - this->xmpp->send_message(from, this->make_xmpp_body(body), this->user_jid); + this->xmpp->send_message(from, this->make_xmpp_body(body), this->user_jid, "chat"); } void Bridge::send_user_join(const std::string& hostname, diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp index 2799a21..85a83de 100644 --- a/src/xmpp/xmpp_component.cpp +++ b/src/xmpp/xmpp_component.cpp @@ -457,11 +457,13 @@ void* XmppComponent::get_receive_buffer(const size_t size) const return this->parser.get_buffer(size); } -void XmppComponent::send_message(const std::string& from, Xmpp::body&& body, const std::string& to) +void XmppComponent::send_message(const std::string& from, Xmpp::body&& body, const std::string& to, const std::string& type) { XmlNode node("message"); node["to"] = to; node["from"] = from + "@" + this->served_hostname; + if (!type.empty()) + node["type"] = type; XmlNode body_node("body"); body_node.set_inner(std::get<0>(body)); body_node.close(); diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp index 5a5d3d8..3e13086 100644 --- a/src/xmpp/xmpp_component.hpp +++ b/src/xmpp/xmpp_component.hpp @@ -81,7 +81,8 @@ public: /** * Send a message from from@served_hostname, with the given body */ - void send_message(const std::string& from, Xmpp::body&& body, const std::string& to); + void send_message(const std::string& from, Xmpp::body&& body, + const std::string& to, const std::string& type); /** * Send a join from a new participant */ -- cgit v1.2.3 From f00f5c3ffbc72652568c75de6e48e41b3275fb0a Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Fri, 11 Apr 2014 23:06:13 +0200 Subject: Do not use exceptions for missing tags, improvement in code simplicity --- src/test.cpp | 2 +- src/xmpp/xmpp_component.cpp | 124 +++++++++++++++++++------------------------- src/xmpp/xmpp_stanza.cpp | 4 +- src/xmpp/xmpp_stanza.hpp | 11 +--- 4 files changed, 58 insertions(+), 83 deletions(-) (limited to 'src') diff --git a/src/test.cpp b/src/test.cpp index b95b379..7a2051f 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -87,7 +87,7 @@ int main() { std::cout << stanza.to_string() << std::endl; assert(stanza.get_name() == "stream_ns:stanza"); - assert(stanza["b"] == "c"); + assert(stanza.get_tag("b") == "c"); assert(stanza.get_inner() == "inner"); assert(stanza.get_tail() == ""); assert(stanza.get_child("stream_ns:child1") != nullptr); diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp index 85a83de..606be10 100644 --- a/src/xmpp/xmpp_component.cpp +++ b/src/xmpp/xmpp_component.cpp @@ -135,11 +135,8 @@ void XmppComponent::clean() void XmppComponent::on_remote_stream_open(const XmlNode& node) { log_debug("XMPP DOCUMENT OPEN: " << node.to_string()); - try - { - this->stream_id = node["id"]; - } - catch (const AttributeNotFound& e) + this->stream_id = node.get_tag("id"); + if (this->stream_id.empty()) { log_error("Error: no attribute 'id' found"); this->send_stream_error("bad-format", "missing 'id' attribute"); @@ -255,27 +252,27 @@ void XmppComponent::handle_handshake(const Stanza& stanza) void XmppComponent::handle_presence(const Stanza& stanza) { - std::string from; - std::string id; - try { - id = stanza["id"]; - from = stanza["from"]; - } catch (const AttributeNotFound&) {} + std::string from = stanza.get_tag("from"); + std::string id = stanza.get_tag("id"); + std::string to_str = stanza.get_tag("to"); + std::string type = stanza.get_tag("type"); + + // Check for mandatory tags if (from.empty()) - return; - utils::ScopeGuard malformed_stanza_error([&](){ + { + log_warning("Received an invalid presence stanza: tag 'from' is missing."); + return; + } + if (to_str.empty()) + { this->send_stanza_error("presence", from, this->served_hostname, id, - "modify", "bad-request", ""); - }); - Bridge* bridge = this->get_user_bridge(stanza["from"]); - Jid to(stanza["to"]); + "modify", "bad-request", "Missing 'to' tag"); + return; + } + + Bridge* bridge = this->get_user_bridge(from); + Jid to(to_str); Iid iid(to.local); - std::string type; - try { - type = stanza["type"]; - } - catch (const AttributeNotFound&) {} - malformed_stanza_error.disable(); // An error stanza is sent whenever we exit this function without // disabling this scopeguard. If error_type and error_name are not @@ -286,7 +283,7 @@ void XmppComponent::handle_presence(const Stanza& stanza) std::string error_type("cancel"); std::string error_name("internal-server-error"); utils::ScopeGuard stanza_error([&](){ - this->send_stanza_error("presence", stanza["from"], stanza["to"], id, + this->send_stanza_error("presence", from, to_str, id, error_type, error_name, ""); }); @@ -309,41 +306,30 @@ void XmppComponent::handle_presence(const Stanza& stanza) { // An user wants to join an invalid IRC channel, return a presence error to him if (type.empty()) - this->send_invalid_room_error(to.local, to.resource, stanza["from"]); + this->send_invalid_room_error(to.local, to.resource, from); } stanza_error.disable(); } void XmppComponent::handle_message(const Stanza& stanza) { - std::string from; - std::string id; - try { - id = stanza["id"]; - from = stanza["from"]; - } catch (const AttributeNotFound&) {} + std::string from = stanza.get_tag("from"); + std::string id = stanza.get_tag("id"); + std::string to_str = stanza.get_tag("to"); + std::string type = stanza.get_tag("type"); + if (from.empty()) return; - utils::ScopeGuard malformed_stanza_error([&](){ - this->send_stanza_error("message", from, this->served_hostname, id, - "modify", "bad-request", ""); - }); - Bridge* bridge = this->get_user_bridge(stanza["from"]); - Jid to(stanza["to"]); - Iid iid(to.local); - std::string type; - try { - type = stanza["type"]; - } - catch (const AttributeNotFound&) { + if (type.empty()) type = "normal"; - } - malformed_stanza_error.disable(); + Bridge* bridge = this->get_user_bridge(from); + Jid to(to_str); + Iid iid(to.local); std::string error_type("cancel"); std::string error_name("internal-server-error"); utils::ScopeGuard stanza_error([&](){ - this->send_stanza_error("message", stanza["from"], stanza["to"], id, + this->send_stanza_error("message", from, to_str, id, error_type, error_name, ""); }); XmlNode* body = stanza.get_child(COMPONENT_NS":body"); @@ -366,27 +352,27 @@ void XmppComponent::handle_message(const Stanza& stanza) void XmppComponent::handle_iq(const Stanza& stanza) { - std::string id; - std::string from; - try { - id = stanza["id"]; - from = stanza["from"]; - } catch (const AttributeNotFound&) {} + std::string id = stanza.get_tag("id"); + std::string from = stanza.get_tag("from"); + std::string to_str = stanza.get_tag("to"); + std::string type = stanza.get_tag("type"); + if (from.empty()) return; - utils::ScopeGuard malformed_stanza_error([&](){ + if (id.empty() || to_str.empty() || type.empty()) + { this->send_stanza_error("iq", from, this->served_hostname, id, "modify", "bad-request", ""); - }); - Bridge* bridge = this->get_user_bridge(stanza["from"]); - Jid to(stanza["to"]); - std::string type = stanza["type"]; - malformed_stanza_error.disable(); + return; + } + + Bridge* bridge = this->get_user_bridge(from); + Jid to(from); std::string error_type("cancel"); std::string error_name("internal-server-error"); utils::ScopeGuard stanza_error([&](){ - this->send_stanza_error("iq", stanza["from"], stanza["to"], id, + this->send_stanza_error("iq", from, to_str, id, error_type, error_name, ""); }); if (type == "set") @@ -397,18 +383,8 @@ void XmppComponent::handle_iq(const Stanza& stanza) const XmlNode* child = query->get_child(MUC_ADMIN_NS":item"); if (child) { - std::string nick; - std::string role; - try { - nick = (*child)["nick"]; - role = (*child)["role"]; - } - catch (const AttributeNotFound&) - { - error_type = "modify"; - error_name = "bad-request"; - return; - } + std::string nick = child->get_tag("nick"); + std::string role = child->get_tag("role"); if (!nick.empty() && role == "none") { std::string reason; @@ -418,6 +394,12 @@ void XmppComponent::handle_iq(const Stanza& stanza) Iid iid(to.local); bridge->send_irc_kick(iid, nick, reason); } + else + { + error_type = "cancel"; + error_name = "feature-not-implemented"; + return; + } } } } diff --git a/src/xmpp/xmpp_stanza.cpp b/src/xmpp/xmpp_stanza.cpp index 23b2d25..948e5f5 100644 --- a/src/xmpp/xmpp_stanza.cpp +++ b/src/xmpp/xmpp_stanza.cpp @@ -216,7 +216,7 @@ bool XmlNode::has_children() const return !this->children.empty(); } -const std::string& XmlNode::operator[](const std::string& name) const +const std::string XmlNode::get_tag(const std::string& name) const { try { @@ -225,7 +225,7 @@ const std::string& XmlNode::operator[](const std::string& name) const } catch (const std::out_of_range& e) { - throw AttributeNotFound(); + return ""; } } diff --git a/src/xmpp/xmpp_stanza.hpp b/src/xmpp/xmpp_stanza.hpp index d9bf81d..1c63b86 100644 --- a/src/xmpp/xmpp_stanza.hpp +++ b/src/xmpp/xmpp_stanza.hpp @@ -8,13 +8,6 @@ std::string xml_escape(const std::string& data); std::string xml_unescape(const std::string& data); -/** - * Raised on operator[] when the attribute does not exist - */ -class AttributeNotFound: public std::exception -{ -}; - /** * Represent an XML node. It has * - A parent XML node (in the case of the first-level nodes, the parent is @@ -103,10 +96,10 @@ public: */ bool has_children() const; /** - * Gets the value for the given attribute, raises AttributeNotFound if the + * Gets the value for the given attribute, returns an empty string if the * node as no such attribute. */ - const std::string& operator[](const std::string& name) const; + const std::string get_tag(const std::string& name) const; /** * Use this to set an attribute's value, like node["id"] = "12"; */ -- cgit v1.2.3 From d2a7fd129a8d4bac6959425bdfab21095bed082b Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Fri, 11 Apr 2014 23:34:42 +0200 Subject: Do not print an error message from expat if the error was "parsing finished" --- src/xmpp/xmpp_parser.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/xmpp/xmpp_parser.cpp b/src/xmpp/xmpp_parser.cpp index 536d9da..6bb0d28 100644 --- a/src/xmpp/xmpp_parser.cpp +++ b/src/xmpp/xmpp_parser.cpp @@ -55,7 +55,8 @@ XmppParser::~XmppParser() int XmppParser::feed(const char* data, const int len, const bool is_final) { int res = XML_Parse(this->parser, data, len, is_final); - if (res == 0) + if (res == XML_STATUS_ERROR && + (XML_GetErrorCode(this->parser) != XML_ERROR_FINISHED)) log_error("Xml_Parse encountered an error: " << XML_ErrorString(XML_GetErrorCode(this->parser))) return res; @@ -64,7 +65,7 @@ int XmppParser::feed(const char* data, const int len, const bool is_final) int XmppParser::parse(const int len, const bool is_final) { int res = XML_ParseBuffer(this->parser, len, is_final); - if (res == 0) + if (res == XML_STATUS_ERROR) log_error("Xml_Parsebuffer encountered an error: " << XML_ErrorString(XML_GetErrorCode(this->parser))); return res; -- cgit v1.2.3