[Pkg-javascript-commits] [ltx] 116/469: connection: refactor out into StreamParser

Jonas Smedegaard dr at jones.dk
Wed Aug 31 13:01:11 UTC 2016


This is an automated email from the git hooks/post-receive script.

js pushed a commit to branch master
in repository ltx.

commit d87d6b8f66e4a8f12dd583b91ed400aa4ce1ce7d
Author: Astro <astro at spaceboyz.net>
Date:   Thu Sep 9 01:30:28 2010 +0200

    connection: refactor out into StreamParser
---
 lib/xmpp/connection.js    | 92 +++++++++++++++--------------------------------
 lib/xmpp/stream_parser.js | 80 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 109 insertions(+), 63 deletions(-)

diff --git a/lib/xmpp/connection.js b/lib/xmpp/connection.js
index 69cd73c..05a4651 100644
--- a/lib/xmpp/connection.js
+++ b/lib/xmpp/connection.js
@@ -1,7 +1,7 @@
 var net = require('net');
 var sys = require('sys');
-var expat = require('node-expat');
 var xml = require('./xml');
+var StreamParser = require('./stream_parser');
 
 var NS_XMPP_TLS = exports.NS_XMPP_TLS = 'urn:ietf:params:xml:ns:xmpp-tls';
 var NS_STREAM = exports.NS_STREAM = 'http://etherx.jabber.org/streams';
@@ -39,7 +39,6 @@ exports.makeConnection = makeConnection;
  */
 function initConnection(conn) {
     conn.charset = 'UTF-8';
-    conn.bytesParsed = 0;
 
     conn.addListener('data', conn.onData);
     conn.addListener('end', conn.onEnd);
@@ -67,63 +66,41 @@ Connection.prototype.send = function(stanza) {
     }
 };
 
+// TODO: stream attrs, streamStart
+
 Connection.prototype.startParser = function() {
     var self = this;
-    self.setEncoding('utf8');
-    self.element = null;
-    self.parser = new expat.Parser(self.charset);
-
-    self.parser.addListener('startElement', function(name, attrs) {
-	// TODO: refuse anything but <stream:stream>
-	if (!self.element && name == 'stream:stream') {
-	    self.streamAttrs = attrs;
-	    /* We need those xmlns often, store them extra */
-	    self.streamNsAttrs = {};
-	    for(var k in attrs) {
-		if (k == 'xmlns' ||
-		    k.substr(0, 6) == 'xmlns:')
-		    self.streamNsAttrs[k] = attrs[k];
-	    }
-
-	    /* Notify in case we don't wait for <stream:features/> (Component)
-	     */
-	    self.emit('streamStart', attrs);
-	} else {
-	    var child = new xml.Element(name, attrs);
-	    if (!self.element) {
-		/* A new stanza */
-		self.element = self.addStreamNs(child);
-		self.bytesParsedOnStanzaBegin = self.bytesParsed;
-	    } else {
-		/* A child element of a stanza */
-		self.element = self.element.cnode(child);
-	    }
+    this.parser = new StreamParser.StreamParser(this.charset);
+
+    this.parser.addListener('start', function(attrs) {
+	self.streamAttrs = attrs;
+	/* We need those xmlns often, store them extra */
+	self.streamNsAttrs = {};
+	for(var k in attrs) {
+	if (k == 'xmlns' ||
+	    k.substr(0, 6) == 'xmlns:')
+		self.streamNsAttrs[k] = attrs[k];
 	}
+
+	/* Notify in case we don't wait for <stream:features/> (Component)
+	 */
+	self.emit('streamStart', attrs);
     });
-    self.parser.addListener('endElement', function(name, attrs) {
-	if (!self.element && name == 'stream:stream') {
-	    self.end();
-	} else if (self.element && name == self.element.name) {
-	    if (self.element.parent)
-		self.element = self.element.parent;
-	    else {
-		/* Stanza complete */
-		self.onStanza(self.element);
-		self.element = null;
-		delete self.bytesParsedOnStanzaBegin;
-	    }
-	} else {
-	    self.error('xml-not-well-formed', 'XML parse error');
-	}
+    this.parser.addListener('stanza', function(stanza) {
+	self.onStanza(self.addStreamNs(stanza));
     });
-    self.parser.addListener('text', function(str) {
-	if (self.element)
-	    self.element.t(str);
+    this.parser.addListener('error', function(e) {
+	if (e.message)
+	    self.error(e.message);
+	else
+	    self.error('internal-server-error', e.toString());
+    });
+    this.parser.addListener('end', function() {
+	self.end();
     });
 };
 
 Connection.prototype.stopParser = function() {
-    delete this.element;
     delete this.parser;
 };
 
@@ -132,19 +109,8 @@ Connection.prototype.startStream = function() {
 };
 
 Connection.prototype.onData = function(data) {
-    if (this.parser) {
-	if (this.bytesParsedOnStanzaBegin && this.maxStanzaSize &&
-	    this.bytesParsed > this.bytesParsedOnStanzaBegin + this.maxStanzaSize) {
-
-	    this.error('policy-violation', 'Maximum stanza size exceeded');
-	    return;
-	}
-	this.bytesParsed += data.length;
-
-	if (!this.parser.parse(data, false)) {
-	    this.error('xml-not-well-formed', 'XML parse error');
-	}
-    }
+    if (this.parser)
+	this.parser.write(data);
 };
 
 /**
diff --git a/lib/xmpp/stream_parser.js b/lib/xmpp/stream_parser.js
new file mode 100644
index 0000000..4d788d1
--- /dev/null
+++ b/lib/xmpp/stream_parser.js
@@ -0,0 +1,80 @@
+var sys = require('sys');
+var EventEmitter = require('events').EventEmitter;
+var expat = require('node-expat');
+var xml = require('./xml');
+
+function StreamParser(charset) {
+    var self = this;
+    this.parser = new expat.Parser(charset);
+    this.bytesParsedOnStanzaBegin = 0;
+
+    this.parser.addListener('startElement', function(name, attrs) {
+	// TODO: refuse anything but <stream:stream>
+	if (!self.element && name == 'stream:stream') {
+	    self.emit('start', attrs);
+	} else {
+	    var child = new xml.Element(name, attrs);
+	    if (!self.element) {
+		/* A new stanza */
+		self.element = child;
+		self.bytesParsedOnStanzaBegin = self.bytesParsed;
+	    } else {
+		/* A child element of a stanza */
+		self.element = self.element.cnode(child);
+	    }
+	}
+    });
+    this.parser.addListener('endElement', function(name, attrs) {
+	if (!self.element && name == 'stream:stream') {
+	    self.end();
+	} else if (self.element && name == self.element.name) {
+	    if (self.element.parent)
+		self.element = self.element.parent;
+	    else {
+		/* Stanza complete */
+		self.emit('stanza', self.element);
+		delete self.element;
+		delete self.bytesParsedOnStanzaBegin;
+	    }
+	} else {
+	    self.error('xml-not-well-formed', 'XML parse error');
+	}
+    });
+    this.parser.addListener('text', function(str) {
+	if (self.element)
+	    self.element.t(str);
+    });
+}
+sys.inherits(StreamParser, EventEmitter);
+exports.StreamParser = StreamParser;
+
+StreamParser.prototype.write = function(data) {
+    if (this.parser) {
+	if (this.bytesParsedOnStanzaBegin && this.maxStanzaSize &&
+	    this.bytesParsed > this.bytesParsedOnStanzaBegin + this.maxStanzaSize) {
+
+	    this.error('policy-violation', 'Maximum stanza size exceeded');
+	    return;
+	}
+	this.bytesParsed += data.length;
+
+	if (!this.parser.parse(data, this.final ? true : false)) {
+	    this.error('xml-not-well-formed', 'XML parse error');
+	}
+    }
+};
+
+StreamParser.prototype.end = function(data) {
+    if (data) {
+	this.final = true;
+	this.write(data);
+    }
+
+    delete this.parser;
+    this.emit('end');
+};
+
+// TODO: support error condition & text
+StreamParser.prototype.error = function(reason) {
+    this.emit('error', new Error(reason));
+};

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/ltx.git



More information about the Pkg-javascript-commits mailing list