# HG changeset patch # User Paul Aurich # Date 1233681005 0 # Node ID b5052c66701c096dc455a45ec4d9dfd4a10d05ad # Parent a73791d35fcc7b475df0aada8bbd7ec489a419f8 Jabber IQ handlers should handle non-query child nodes Historically, all IQ stanzas had a query child; this is no longer the case (XMPP Ping, Entity Time, etc). Instead, have the handlers use the first child of the IQ stanza. Also reduce some of the duplication in XMPP ping code (just use the one in ping.c) diff -r a73791d35fcc -r b5052c66701c libpurple/protocols/jabber/iq.c --- a/libpurple/protocols/jabber/iq.c Tue Feb 03 16:00:40 2009 +0000 +++ b/libpurple/protocols/jabber/iq.c Tue Feb 03 17:10:05 2009 +0000 @@ -222,27 +222,6 @@ } } -static void urn_xmpp_ping_parse(JabberStream *js, xmlnode *packet) -{ - const char *type, *id, *from; - JabberIq *iq; - - type = xmlnode_get_attrib(packet, "type"); - from = xmlnode_get_attrib(packet, "from"); - id = xmlnode_get_attrib(packet, "id"); - - if(type && !strcmp(type, "get")) { - iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "urn:xmpp:ping"); - - jabber_iq_set_id(iq, id); - xmlnode_set_attrib(iq->node, "to", from); - - jabber_iq_send(iq); - } else { - /* XXX: error */ - } -} - static void jabber_iq_version_parse(JabberStream *js, xmlnode *packet) { JabberIq *iq; @@ -309,12 +288,23 @@ void jabber_iq_parse(JabberStream *js, xmlnode *packet) { JabberCallbackData *jcd; - xmlnode *query, *error, *x; + xmlnode *child, *error, *x; const char *xmlns; const char *type, *id, *from; JabberIqHandler *jih; - query = xmlnode_get_child(packet, "query"); + /* + * child will be either the first tag child or NULL if there is no child. + * Historically, we used just the 'query' subchild, but newer XEPs use + * differently named children. Grabbing the first child is (for the time + * being) sufficient. + */ + for (child = packet->child; child; child = child->next) { + if (child->type != XMLNODE_TYPE_TAG) + continue; + break; + } + type = xmlnode_get_attrib(packet, "type"); from = xmlnode_get_attrib(packet, "from"); id = xmlnode_get_attrib(packet, "id"); @@ -353,7 +343,6 @@ } /* First, lets see if a special callback got registered */ - if(!strcmp(type, "result") || !strcmp(type, "error")) { if(id && *id && (jcd = g_hash_table_lookup(js->iq_callbacks, id))) { jcd->callback(js, packet, jcd->data); @@ -363,36 +352,15 @@ } /* Apparently not, so lets see if we have a pre-defined handler */ - - if(query && (xmlns = xmlnode_get_namespace(query))) { + if(child && (xmlns = xmlnode_get_namespace(child))) { if((jih = g_hash_table_lookup(iq_handlers, xmlns))) { jih(js, packet); return; } } - if(xmlnode_get_child_with_namespace(packet, "si", "http://jabber.org/protocol/si")) { - jabber_si_parse(js, packet); - return; - } - - if(xmlnode_get_child_with_namespace(packet, "new-mail", "google:mail:notify")) { - jabber_gmail_poke(js, packet); - return; - } - purple_debug_info("jabber", "jabber_iq_parse\n"); - if(xmlnode_get_child_with_namespace(packet, "ping", "urn:xmpp:ping")) { - jabber_ping_parse(js, packet); - return; - } - - if (xmlnode_get_child_with_namespace(packet, "data", XEP_0231_NAMESPACE)) { - jabber_data_parse(js, packet); - return; - } - /* If we get here, send the default error reply mandated by XMPP-CORE */ if(!strcmp(type, "set") || !strcmp(type, "get")) { JabberIq *iq = jabber_iq_new(js, JABBER_IQ_ERROR); @@ -431,7 +399,10 @@ jabber_iq_register_handler("http://jabber.org/protocol/disco#info", jabber_disco_info_parse); jabber_iq_register_handler("http://jabber.org/protocol/disco#items", jabber_disco_items_parse); jabber_iq_register_handler("jabber:iq:register", jabber_register_parse); - jabber_iq_register_handler("urn:xmpp:ping", urn_xmpp_ping_parse); + jabber_iq_register_handler("urn:xmpp:ping", jabber_ping_parse); + jabber_iq_register_handler("http://jabber.org/protocol/si", jabber_si_parse); + jabber_iq_register_handler("google:mail:notify", jabber_gmail_poke); + jabber_iq_register_handler(XEP_0231_NAMESPACE, jabber_data_parse); } void jabber_iq_uninit(void) diff -r a73791d35fcc -r b5052c66701c libpurple/protocols/jabber/ping.c --- a/libpurple/protocols/jabber/ping.c Tue Feb 03 16:00:40 2009 +0000 +++ b/libpurple/protocols/jabber/ping.c Tue Feb 03 17:10:05 2009 +0000 @@ -32,17 +32,29 @@ void jabber_ping_parse(JabberStream *js, xmlnode *packet) { - JabberIq *iq; + const char *type, *id, *from; + + type = xmlnode_get_attrib(packet, "type"); + from = xmlnode_get_attrib(packet, "from"); + id = xmlnode_get_attrib(packet, "id"); + if (!type) { + purple_debug_warning("jabber", "jabber_ping with no type\n"); + return; + } + purple_debug_info("jabber", "jabber_ping_parse\n"); - iq = jabber_iq_new(js, JABBER_IQ_RESULT); - - xmlnode_set_attrib(iq->node, "to", xmlnode_get_attrib(packet, "from") ); + if (!strcmp(type, "get")) { + JabberIq *iq = jabber_iq_new(js, JABBER_IQ_RESULT); - jabber_iq_set_id(iq, xmlnode_get_attrib(packet, "id")); + xmlnode_set_attrib(iq->node, "to", from); + xmlnode_set_attrib(iq->node, "id", id); - jabber_iq_send(iq); + jabber_iq_send(iq); + } else if (!strcmp(type, "set")) { + /* XXX: error */ + } } static void jabber_ping_result_cb(JabberStream *js, xmlnode *packet,