changeset 62:b1e75cdbb0ad

Don’t allow more than one iq handler to respond, and respond with an service-unavailable when not handled.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Wed, 01 Feb 2012 18:37:57 +0100
parents d1ba6f0e2a92
children 20da4fb67977
files lightstring.js plugins/feature-not-implemented.js
diffstat 2 files changed, 30 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/lightstring.js
+++ b/lightstring.js
@@ -44,6 +44,18 @@ var Lightstring = {
       close: function() {
         return "</stream:stream>";
       }
+    },
+    errors: {
+      iq: function(type, error) {
+        return "<iq to='" + stanza.DOM.getAttributeNS(null, 'from') + "'" +
+                  " id='" + stanza.DOM.getAttributeNS(null, 'id') + "'" +
+                  " type='error'>" +
+                 "<error type='" + type + "'>" +
+                   "<" + error + " xmlns='" + Lightstring.namespaces['xmpp_stanzas'] + "'/>" + //TODO: allow text content.
+                    //TODO: allow text and payload.
+                 "</error>" +
+               "</iq>";
+      }
     }
   },
   plugins: {},
@@ -429,8 +441,24 @@ Lightstring.Connection.prototype = {
     if (!handlers)
       return;
 
-    for (var i = 0; i < handlers.length; i++)
-      handlers[i].call(this, aData);
+    if (aData.localName !== 'iq') {
+      for (var i = 0; i < handlers.length; i++)
+        handlers[i].call(this, aData);
+
+      return;
+    }
+
+    var ret;
+    for (var i = 0; i < handlers.length; i++) {
+      ret = handlers[i].call(this, aData);
+      if (typeof ret !== 'boolean')
+        return; //TODO: emit a big error!
+
+      if (ret)
+        return;
+    }
+
+    conn.send(Lightstring.stanzas.errors.iq('cancel', 'service-unavailable'));
   },
   /**
    * @function Register an event handler.
deleted file mode 100644
--- a/plugins/feature-not-implemented.js
+++ /dev/null
@@ -1,53 +0,0 @@
-'use strict';
-
-/**
-  Copyright (c) 2012, Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
-
-  Permission to use, copy, modify, and/or distribute this software for any
-  purpose with or without fee is hereby granted, provided that the above
-  copyright notice and this permission notice appear in all copies.
-
-  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-Lightstring.plugins['feature-not-implemented'] = {
-  namespaces: {
-    xmpp_stanzas: 'urn:ietf:params:xml:ns:xmpp-stanzas'
-  },
-  handlers: {
-    'iq': function callback(stanza) {
-      var type = stanza.DOM.getAttributeNS(null, 'type');
-      if (type !== 'get' && type !== 'set')
-        return;
-
-      var handlers = conn.handlers;
-      var events = [handlers['iq']];
-
-      var payload = stanza.DOM.firstChild;
-      if (payload)
-        events.push('iq/' + payload.namespaceURI + ':' + payload.localName);
-
-      var only = events.every(function(handler) {
-        for (var i in handler)
-          if (callback !== handler[i])
-            return false;
-        return true;
-      });
-
-      if (only)
-        conn.send("<iq to='" + stanza.DOM.getAttributeNS(null, 'from') + "'" +
-                     " id='" + stanza.DOM.getAttributeNS(null, 'id') + "'" +
-                     " type='error'>" +
-                    "<error type='cancel'>" +
-                      "<feature-not-implemented xmlns='" + Lightstring.NS.xmpp_stanzas + "'/>" +
-                    "</error>" +
-                  "</iq>");
-    }
-  }
-};