diff options
author | Florent Le Coz <louiz@louiz.org> | 2014-04-15 04:11:27 +0200 |
---|---|---|
committer | Florent Le Coz <louiz@louiz.org> | 2014-04-15 04:11:27 +0200 |
commit | 7f74f62e56483bae6796be82d279c5180642d53b (patch) | |
tree | d0e98105c52531ae0df3931175e8b185c50e187e | |
parent | 020325dbb071f1735bceb80de9f982aefcd2de47 (diff) | |
parent | c64bb0bde9dbf572bd4d3bbaf478ec812a2f12d6 (diff) | |
download | biboumi-7f74f62e56483bae6796be82d279c5180642d53b.tar.gz biboumi-7f74f62e56483bae6796be82d279c5180642d53b.tar.bz2 biboumi-7f74f62e56483bae6796be82d279c5180642d53b.tar.xz biboumi-7f74f62e56483bae6796be82d279c5180642d53b.zip |
Merge branch 'master' into dummy_chan
-rw-r--r-- | CMakeLists.txt | 15 | ||||
-rw-r--r-- | src/bridge/bridge.cpp | 4 | ||||
-rw-r--r-- | src/test.cpp | 2 | ||||
-rw-r--r-- | src/xmpp/xmpp_component.cpp | 128 | ||||
-rw-r--r-- | src/xmpp/xmpp_component.hpp | 3 | ||||
-rw-r--r-- | src/xmpp/xmpp_parser.cpp | 5 | ||||
-rw-r--r-- | src/xmpp/xmpp_stanza.cpp | 4 | ||||
-rw-r--r-- | src/xmpp/xmpp_stanza.hpp | 11 |
8 files changed, 77 insertions, 95 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 21e7fa6..85c4138 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,6 @@ set(${PROJECT_NAME}_VERSION_MAJOR 0) set(${PROJECT_NAME}_VERSION_MINOR 1) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pedantic -Wall -Wextra") -# set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address") # Define a __FILENAME__ macro to get the filename of each file, instead of # the full path as in __FILE__ @@ -42,13 +41,17 @@ endif() # ## Documentation # +set(MAN_PAGE ${CMAKE_CURRENT_BINARY_DIR}/doc/${PROJECT_NAME}.1) +set(DOC_PAGE ${CMAKE_CURRENT_SOURCE_DIR}/doc/${PROJECT_NAME}.1.md) find_program(RONN_EXECUTABLE NAMES ronn DOC "The ronn software, to build the man page from the markdown documentation") if(RONN_EXECUTABLE) set(WITH_DOC true) - add_custom_target(doc - ${RONN_EXECUTABLE} --roff ${CMAKE_CURRENT_BINARY_DIR}/doc/${PROJECT_NAME}.1.md - COMMENT "Generate the man page" VERBATIM) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/) + add_custom_command(OUTPUT ${MAN_PAGE} + COMMAND ${RONN_EXECUTABLE} --roff < ${DOC_PAGE} > ${MAN_PAGE} + DEPENDS ${DOC_PAGE}) + add_custom_target(doc DEPENDS ${MAN_PAGE}) endif() # @@ -98,7 +101,7 @@ file(GLOB source_xmpp src/xmpp/*.[hc]pp) add_library(xmpp STATIC ${source_xmpp}) target_link_libraries(xmpp bridge network utils logger - ${EXPAT_LIBRARIES} pthread) + ${EXPAT_LIBRARIES}) if(LIBIDN_FOUND) target_link_libraries(xmpp ${LIBIDN_LIBRARIES}) endif() @@ -146,5 +149,5 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.cmake ${CMAKE_CURRENT_BI install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) if(WITH_DOC) - install(FILES doc/${PROJECT_NAME}.1 DESTINATION man/man1) + install(FILES ${MAN_PAGE} DESTINATION man/man1) endif()
\ No newline at end of file diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index f4d4814..da10e28 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -208,7 +208,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) @@ -240,7 +240,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/test.cpp b/src/test.cpp index b421941..e66c4ad 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -88,7 +88,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 e558e46..8e8cc91 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, ""); }); @@ -310,41 +307,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"); @@ -367,27 +353,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") @@ -398,18 +384,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; @@ -419,6 +395,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; + } } } } @@ -458,11 +440,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 */ 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; 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 @@ -9,13 +9,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 nullptr) @@ -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"; */ |