[Pkg-javascript-commits] [ltx] 01/469: starttls works

Jonas Smedegaard dr at jones.dk
Wed Aug 31 13:00:49 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 2d2e992077ba25a2ba4788fa18cc548c699d8960
Author: Astro <astro at spaceboyz.net>
Date:   Tue May 25 03:52:11 2010 +0200

    starttls works
---
 lib/xmpp.js            |   6 ++
 lib/xmpp/client.js     |  26 +++++++++
 lib/xmpp/connection.js | 110 +++++++++++++++++++++++++++++++++++++
 lib/xmpp/jid.js        |  23 ++++++++
 lib/xmpp/xml.js        | 146 +++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 311 insertions(+)

diff --git a/lib/xmpp.js b/lib/xmpp.js
new file mode 100644
index 0000000..6eff5c4
--- /dev/null
+++ b/lib/xmpp.js
@@ -0,0 +1,6 @@
+var Client = require('./xmpp/client').Client;
+var JID = require('./xmpp/jid').JID;
+
+exports.Client = Client;
+exports.JID = JID;
+
diff --git a/lib/xmpp/client.js b/lib/xmpp/client.js
new file mode 100644
index 0000000..569a3fd
--- /dev/null
+++ b/lib/xmpp/client.js
@@ -0,0 +1,26 @@
+var Connection = require('./connection').Connection;
+var JID = require('./jid').JID;
+var sys = require('sys');
+var puts = require('sys').puts;
+
+/**
+ * params:
+ *   jid: String (required)
+ *   password: String (required)
+ *   host: String (optional)
+ *   port: Number (optional)
+ */
+function Client(params) {
+    Connection.call(this);
+
+    this.jid = new JID(params.jid);
+    this.password = params.password;
+    this.xmlns = "jabber:client";
+    this.xmppVersion = "1.0";
+    this.streamTo = this.jid.domain;
+
+    this.connect(params.port, params.host);
+}
+
+sys.inherits(Client, Connection);
+exports.Client = Client;
diff --git a/lib/xmpp/connection.js b/lib/xmpp/connection.js
new file mode 100644
index 0000000..245bb3a
--- /dev/null
+++ b/lib/xmpp/connection.js
@@ -0,0 +1,110 @@
+var net = require('net');
+var sys = require('sys');
+var expat = require('expat');
+var puts = require('sys').puts;
+var xml = require('./xml');
+
+var NS_XMPP_TLS = 'urn:ietf:params:xml:ns:xmpp-tls';
+
+function Connection() {
+    net.Stream.call(this);
+
+    this.charset = 'UTF-8';
+    this.addListener('connect', this.startStream);
+    this.addListener('data', this.onData);
+//    this.addListener('end', this.onEnd);
+//    this.addListener('error', this.onError);
+}
+
+sys.inherits(Connection, net.Stream);
+exports.Connection = Connection;
+
+Connection.prototype.send = function(stanza) {
+    var self = this;
+    if (stanza.root)
+	stanza.root().write(function(s) {
+	    self.write(s);
+	});
+    else
+	self.write(stanza);
+};
+
+Connection.prototype.startParser = function() {
+    var self = this;
+    self.element = null;
+    self.parser = new expat.Parser(self.charset);
+
+    self.parser.addListener('startElement', function(name, attrs) {
+	if (!self.element && name == 'stream:stream') {
+	    self.streamAttrs = attrs;
+	} else {
+	    var child = new xml.Element(name, attrs);
+	    if (!self.element) {
+		/* TODO: add stream xmlns */
+		self.element = child;
+	    } else {
+		self.element = self.element.cnode(child);
+	    }
+	}
+    });
+    self.parser.addListener('endElement', function(name, attrs) {
+	if (!self.element && name == 'stream:stream') {
+	    self.close();
+	} 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;
+	    }
+	} else {
+	    self.emit('parseError');
+	    self.end();
+	}
+    });
+    self.parser.addListener('text', function(str) {
+	if (self.element)
+	    self.element.t(str);
+    });
+};
+
+Connection.prototype.startStream = function() {
+    this.startParser();
+
+    var tag = "<stream:stream xmlns='" + this.xmlns +
+	"' xmlns:stream='http://etherx.jabber.org/streams'" +
+	" to='" + this.streamTo + "'";
+    if (this.xmppVersion)
+	tag += " version='" + this.xmppVersion + "'";
+    tag += ">";
+    this.send(tag);
+};
+
+Connection.prototype.onData = function(data) {
+    if (this.parser) {
+	if (!this.parser.parse(data.toString(), false)) {
+	    this.emit('parseError');
+	    this.end();
+	}
+    }
+};
+
+/**
+ * This is not an event listener, but takes care of the authentication
+ * before 'stanza' events are emitted to the user.
+ */
+Connection.prototype.onStanza = function(stanza) {
+    puts('Stanza: ' + stanza.toString());
+
+    if (stanza.name == 'stream:features') {
+	if (stanza.getChild('starttls', NS_XMPP_TLS)) {
+	    this.send(new xml.Element('starttls', { xmlns: NS_XMPP_TLS }));
+	}
+    } else if (stanza.name == 'proceed' && stanza.getNS() == NS_XMPP_TLS) {
+	this.setSecure();
+	this.addListener('secure', this.startStream);
+    }
+
+    this.emit('stanza', this.element);
+};
diff --git a/lib/xmpp/jid.js b/lib/xmpp/jid.js
new file mode 100644
index 0000000..b5e43d3
--- /dev/null
+++ b/lib/xmpp/jid.js
@@ -0,0 +1,23 @@
+function JID(a, b, c) {
+    if (a && b == null && c == null) {
+	this.parseJID(a);
+    } else if (a && b) {
+	this.user = a;
+	this.domain = b;
+	this.resource = c;
+    }
+}
+
+JID.prototype.parseJID = function(s) {
+    if (s.indexOf('@') >= 0) {
+	this.user = s.substr(0, s.indexOf('@'));
+	s = s.substr(s.indexOf('@') + 1);
+    }
+    if (s.indexOf('/') >= 0) {
+	this.resource = s.substr(s.indexOf('/') + 1);
+	s = s.substr(0, s.indexOf('/'));
+    }
+    this.domain = s;
+}
+
+exports.JID = JID;
diff --git a/lib/xmpp/xml.js b/lib/xmpp/xml.js
new file mode 100644
index 0000000..f19a0c2
--- /dev/null
+++ b/lib/xmpp/xml.js
@@ -0,0 +1,146 @@
+/** This cheap replica of DOM/Builder puts me to shame :-) */
+function Element(name, attrs) {
+    this.name = name;
+    this.parent = null;
+    if (attrs)
+	this.attrs = attrs;
+    else
+	this.attrs = {};
+    this.children = [];
+}
+
+/*** Accessors ***/
+
+Element.prototype.getNS = function() {
+    if (this.name.indexOf(":") >= 0) {
+	var prefix = this.name.substr(0, this.name.indexOf(":"));
+	return this.findNS(prefix);
+    } else {
+	return this.findNS();
+    }
+};
+
+Element.prototype.findNS = function(prefix) {
+    if (!prefix) {
+	/* default namespace */
+	if (this.attrs.xmlns)
+	    return this.attrs.xmlns;
+	else
+	    return this.parent.findNS();
+    } else {
+	/* prefixed namespace */
+	var attr = 'xmlns:' + prefix;
+	if (this.attrs[attr])
+	    return this.attrs[attr];
+	else
+	    return this.parent.findNS(prefix);
+    }
+};
+
+/** xmlns can be null */
+Element.prototype.getChild = function(name, xmlns) {
+    return this.getChildren(name, xmlns)[0];
+};
+
+Element.prototype.getChildren = function(name, xmlns) {
+    var result = [];
+    this.children.forEach(function(child) {
+	if (child.name == name &&
+	    (!xmlns || child.getNS() == xmlns))
+	    result.push(child);
+    });
+    return result;
+};
+
+Element.prototype.getText = function() {
+    var text = "";
+    this.children.forEach(function(child) {
+	if (typeof child == 'string')
+	    text += child;
+    });
+    return text;
+};
+
+/*** Builder ***/
+
+/** returns uppermost parent */
+Element.prototype.root = function() {
+    if (this.parent)
+	return this.parent.root();
+    else
+	return this;
+};
+Element.prototype.tree = Element.prototype.root;
+
+/** just parent or itself */
+Element.prototype.up = function() {
+    if (this.parent)
+	return this.parent;
+    else
+	return this;
+};
+
+/** create child node and return it */
+Element.prototype.c = function(name, attrs) {
+    return this.cnode(new Element(name, attrs));
+};
+
+Element.prototype.cnode = function(child) {
+    this.children.push(child);
+    child.parent = this;
+    return child;
+};
+
+/** create text node and return element */
+Element.prototype.t = function(text) {
+    this.children.push(text);
+    return this;
+};
+
+/*** Serialization ***/
+
+Element.prototype.toString = function() {
+    var s = "";
+    this.write(function(c) {
+	s += c;
+    });
+    return s;
+};
+
+Element.prototype.write = function(writer) {
+    writer("<");
+    writer(this.name);
+    for(var k in this.attrs) {
+	writer(" ");
+	writer(k);
+	writer("=\"");
+	writer(escapeXml(this.attrs[k]));
+	writer("\"");
+    }
+    if (this.children.length == 0) {
+	writer("/>");
+    } else {
+	writer(">");
+	this.children.forEach(function(child) {
+	    if (typeof child == 'string')
+		writer(child);
+	    else
+		child.write(writer);
+	});
+	writer("</");
+	writer(this.name);
+	writer(">");
+    }
+};
+
+function escapeXml(s) {
+    return s.
+	replace('&', '&').
+	replace('<', '<').
+	replace('>', '>').
+	replace('"', '"').
+	replace('\'', ''');
+};
+
+exports.Element = Element;
+exports.escapeXml = escapeXml;
\ No newline at end of file

-- 
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