[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