Break client-specific code into verse.client module

Tue, 04 Aug 2009 18:25:56 +0100

author
Matthew Wild <mwild1@gmail.com>
date
Tue, 04 Aug 2009 18:25:56 +0100
changeset 1
7c8d0a2fc004
parent 0
caf260adc453
child 2
9e9f3be09131

Break client-specific code into verse.client module

client.lua file | annotate | diff | comparison | revisions
init.lua file | annotate | diff | comparison | revisions
squishy file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client.lua	Tue Aug 04 18:25:56 2009 +0100
@@ -0,0 +1,56 @@
+local verse = require "verse2";
+local stream = verse.stream_mt;
+
+local jid_split = require "jid".split;
+local lxp = require "lxp";
+local st = require "util.stanza";
+local init_xmlhandlers = require "xmlhandlers";
+
+
+local stream_callbacks = { stream_tag = "http://etherx.jabber.org/streams|stream", 
+		default_ns = "jabber:client" };
+	
+function stream_callbacks.streamopened(stream, attr)
+	if not stream:event("opened") then
+		stream.notopen = nil;
+	end
+	return true;
+end
+
+function stream_callbacks.streamclosed(stream)
+	return stream:event("closed");
+end
+
+function stream_callbacks.handlestanza(stream, stanza)
+	return stream:event("stanza", stanza);
+end
+
+local function reset_stream(stream)
+	-- Reset stream
+	local parser = lxp.new(init_xmlhandlers(stream, stream_callbacks), "|");
+	stream.parser = parser;
+	
+	stream.notopen = true;
+	
+	function stream.data(conn, data)
+		local ok, err = parser:parse(data);
+		if ok then return; end
+		stream:debug("debug", "Received invalid XML (%s) %d bytes: %s", tostring(err), #data, data:sub(1, 300):gsub("[\r\n]+", " "));
+		stream:close("xml-not-well-formed");
+	end
+	
+	return true;
+end
+
+function stream:connect_client(jid, pass)
+	self.jid, self.password = jid, pass;
+	self.username, self.host, self.resource = jid_split(jid);
+	
+	reset_stream(self);	
+	self:hook("incoming-raw", function (data) return self.data(self.conn, data); end);
+	
+	-- Initialise connection
+	self:connect(self.connect_host or self.host, self.connect_port or 5222);
+	self:send(st.stanza("stream:stream", { to = self.host, ["xmlns:stream"]='http://etherx.jabber.org/streams' }):top_tag());
+end
+
--- a/init.lua	Tue Aug 04 00:10:45 2009 +0100
+++ b/init.lua	Tue Aug 04 18:25:56 2009 +0100
@@ -1,40 +1,82 @@
 
 
 local server = require "server";
+local events = require "events";
 local xmlhandlers = require "xmlhandlers";
-local jid = require "jid";
-local jid_split = jid.split;
+local st = require "util.stanza";
 
 module("verse", package.seeall);
 local verse = _M;
 
 local stream = {};
 stream.__index = stream;
+stream_mt = stream;
 
 function verse.new()
-	return setmetatable({}, stream);
+	local t = {};
+	t.id = tostring(t):match("%x*$");
+	t.logger = logger.init(t.id);
+	t.events = events.new();
+	return setmetatable(t, stream);
 end
 
 function verse.loop()
 	return server.loop();
 end
 
-function stream:connect(jid, pass)
-	self.jid, self.password = jid, pass;
-	self.username, self.host, self.resource = jid_split(jid);
-	local conn, err = server.addclient(self.connect_host or self.host, tonumber(self.connect_port) or 5222, new_listener(self), "*a");
+function stream:connect(connect_host, connect_port)
+	connect_host = connect_host or "localhost";
+	connect_port = tonumber(connect_port) or 5222;
 	
+	-- Create and initiate connection
+	local conn = socket.tcp()
+	conn:settimeout(0);
+	local success, err = conn:connect(connect_host, connect_port);
+	
+	if not success and err ~= "timeout" then
+		self:warn("connect() to %s:%d failed: %s", connect_host, connect_port, err);
+		return false, err;
+	end
+
+	--local conn, err = server.addclient(self.connect_host or self.host, tonumber(self.connect_port) or 5222, new_listener(self), "*a");
+	local conn = server.wrapclient(conn, connect_host, connect_port, new_listener(self), "*a"); --, hosts[from_host].ssl_ctx, false );
 	if not conn then
 		return nil, err;
 	end
 	
 	self.conn = conn;
+	local w, t = conn.write, tostring;
+	self.send = function (_, data) return w(t(data)); end
+end
+
+-- Logging functions
+function stream:debug(...)
+	return self.logger("debug", ...);
+end
+
+function stream:warn(...)
+	return self.logger("warn", ...);
 end
 
+function stream:error(...)
+	return self.logger("error", ...);
+end
+
+-- Event handling
+function stream:event(name, ...)
+	return self.events.fire_event(name, ...);
+end
+
+function stream:hook(name, callback)
+	return self.events.add_handler(name, callback);
+end
+
+-- Listener factory
 function new_listener(stream)
 	local conn_listener = {};
 	
 	function conn_listener.incoming(conn, data)
+		stream:debug("Data");
 		if not stream.connected then
 			stream.connected = true;
 			stream.send = function (stream, data) stream:debug("Sending data: "..tostring(data)); return conn.write(tostring(data)); end;
--- a/squishy	Tue Aug 04 00:10:45 2009 +0100
+++ b/squishy	Tue Aug 04 18:25:56 2009 +0100
@@ -12,6 +12,9 @@
 Module "server"			"net/server.lua"
 Module "xmlhandlers"		"core/xmlhandlers.lua"
 Module "jid"			"util/jid.lua"
+Module "events"			"util/events.lua"
+
+Module "verse2.client" "client.lua"
 
 -- Main verse file
 Main "init.lua"

mercurial