client.lua

changeset 411
db462d4feb44
parent 400
0db9cb909cf1
child 430
b1f7214c6ec2
equal deleted inserted replaced
410:6171ef2a4025 411:db462d4feb44
20 20
21 local stream_callbacks = { 21 local stream_callbacks = {
22 stream_ns = xmlns_stream, 22 stream_ns = xmlns_stream,
23 stream_tag = "stream", 23 stream_tag = "stream",
24 default_ns = "jabber:client" }; 24 default_ns = "jabber:client" };
25 25
26 function stream_callbacks.streamopened(stream, attr) 26 function stream_callbacks.streamopened(stream, attr)
27 stream.stream_id = attr.id; 27 stream.stream_id = attr.id;
28 if not stream:event("opened", attr) then 28 if not stream:event("opened", attr) then
29 stream.notopen = nil; 29 stream.notopen = nil;
30 end 30 end
74 end 74 end
75 75
76 function stream:connect_client(jid, pass) 76 function stream:connect_client(jid, pass)
77 self.jid, self.password = jid, pass; 77 self.jid, self.password = jid, pass;
78 self.username, self.host, self.resource = jid_split(jid); 78 self.username, self.host, self.resource = jid_split(jid);
79 79
80 -- Required XMPP features 80 -- Required XMPP features
81 self:add_plugin("tls"); 81 self:add_plugin("tls");
82 self:add_plugin("sasl"); 82 self:add_plugin("sasl");
83 self:add_plugin("bind"); 83 self:add_plugin("bind");
84 self:add_plugin("session"); 84 self:add_plugin("session");
85 85
86 function self.data(conn, data) 86 function self.data(conn, data)
87 local ok, err = self.stream:feed(data); 87 local ok, err = self.stream:feed(data);
88 if ok then return; end 88 if ok then return; end
89 self:debug("Received invalid XML (%s) %d bytes: %s", tostring(err), #data, data:sub(1, 300):gsub("[\r\n]+", " ")); 89 self:debug("Received invalid XML (%s) %d bytes: %s", tostring(err), #data, data:sub(1, 300):gsub("[\r\n]+", " "));
90 self:close("xml-not-well-formed"); 90 self:close("xml-not-well-formed");
91 end 91 end
92 92
93 self:hook("connected", function () self:reopen(); end); 93 self:hook("connected", function () self:reopen(); end);
94 self:hook("incoming-raw", function (data) return self.data(self.conn, data); end); 94 self:hook("incoming-raw", function (data) return self.data(self.conn, data); end);
95 95
96 self.curr_id = 0; 96 self.curr_id = 0;
97 97
98 self.tracked_iqs = {}; 98 self.tracked_iqs = {};
99 self:hook("stanza", function (stanza) 99 self:hook("stanza", function (stanza)
100 local id, type = stanza.attr.id, stanza.attr.type; 100 local id, type = stanza.attr.id, stanza.attr.type;
101 if id and stanza.name == "iq" and (type == "result" or type == "error") and self.tracked_iqs[id] then 101 if id and stanza.name == "iq" and (type == "result" or type == "error") and self.tracked_iqs[id] then
102 self.tracked_iqs[id](stanza); 102 self.tracked_iqs[id](stanza);
103 self.tracked_iqs[id] = nil; 103 self.tracked_iqs[id] = nil;
104 return true; 104 return true;
105 end 105 end
106 end); 106 end);
107 107
108 self:hook("stanza", function (stanza) 108 self:hook("stanza", function (stanza)
109 local ret; 109 local ret;
110 if stanza.attr.xmlns == nil or stanza.attr.xmlns == "jabber:client" then 110 if stanza.attr.xmlns == nil or stanza.attr.xmlns == "jabber:client" then
111 if stanza.name == "iq" and (stanza.attr.type == "get" or stanza.attr.type == "set") then 111 if stanza.name == "iq" and (stanza.attr.type == "get" or stanza.attr.type == "set") then
112 local xmlns = stanza.tags[1] and stanza.tags[1].attr.xmlns; 112 local xmlns = stanza.tags[1] and stanza.tags[1].attr.xmlns;
130 self:hook("outgoing", function (data) 130 self:hook("outgoing", function (data)
131 if data.name then 131 if data.name then
132 self:event("stanza-out", data); 132 self:event("stanza-out", data);
133 end 133 end
134 end); 134 end);
135 135
136 self:hook("stanza-out", function (stanza) 136 self:hook("stanza-out", function (stanza)
137 if not stanza.attr.xmlns then 137 if not stanza.attr.xmlns then
138 self:event(stanza.name.."-out", stanza); 138 self:event(stanza.name.."-out", stanza);
139 end 139 end
140 end); 140 end);
141 141
142 local function stream_ready() 142 local function stream_ready()
143 self:event("ready"); 143 self:event("ready");
144 end 144 end
145 self:hook("session-success", stream_ready, -1) 145 self:hook("session-success", stream_ready, -1)
146 self:hook("bind-success", stream_ready, -1); 146 self:hook("bind-success", stream_ready, -1);
153 self.closed = true; 153 self.closed = true;
154 else 154 else
155 return self:close(reason); 155 return self:close(reason);
156 end 156 end
157 end 157 end
158 158
159 local function start_connect() 159 local function start_connect()
160 -- Initialise connection 160 -- Initialise connection
161 self:connect(self.connect_host or self.host, self.connect_port or 5222); 161 self:connect(self.connect_host or self.host, self.connect_port or 5222);
162 end 162 end
163 163
164 if not (self.connect_host or self.connect_port) then 164 if not (self.connect_host or self.connect_port) then
165 -- Look up SRV records 165 -- Look up SRV records
166 adns.lookup(function (answer) 166 adns.lookup(function (answer)
167 if answer then 167 if answer then
168 local srv_hosts = {}; 168 local srv_hosts = {};
169 self.srv_hosts = srv_hosts; 169 self.srv_hosts = srv_hosts;
170 for _, record in ipairs(answer) do 170 for _, record in ipairs(answer) do
171 table.insert(srv_hosts, record.srv); 171 table.insert(srv_hosts, record.srv);
172 end 172 end
173 table.sort(srv_hosts, compare_srv_priorities); 173 table.sort(srv_hosts, compare_srv_priorities);
174 174
175 local srv_choice = srv_hosts[1]; 175 local srv_choice = srv_hosts[1];
176 self.srv_choice = 1; 176 self.srv_choice = 1;
177 if srv_choice then 177 if srv_choice then
178 self.connect_host, self.connect_port = srv_choice.target, srv_choice.port; 178 self.connect_host, self.connect_port = srv_choice.target, srv_choice.port;
179 self:debug("Best record found, will connect to %s:%d", self.connect_host or self.host, self.connect_port or 5222); 179 self:debug("Best record found, will connect to %s:%d", self.connect_host or self.host, self.connect_port or 5222);
180 end 180 end
181 181
182 self:hook("disconnected", function () 182 self:hook("disconnected", function ()
183 if self.srv_hosts and self.srv_choice < #self.srv_hosts then 183 if self.srv_hosts and self.srv_choice < #self.srv_hosts then
184 self.srv_choice = self.srv_choice + 1; 184 self.srv_choice = self.srv_choice + 1;
185 local srv_choice = srv_hosts[self.srv_choice]; 185 local srv_choice = srv_hosts[self.srv_choice];
186 self.connect_host, self.connect_port = srv_choice.target, srv_choice.port; 186 self.connect_host, self.connect_port = srv_choice.target, srv_choice.port;
187 start_connect(); 187 start_connect();
188 return true; 188 return true;
189 end 189 end
190 end, 1000); 190 end, 1000);
191 191
192 self:hook("connected", function () 192 self:hook("connected", function ()
193 self.srv_hosts = nil; 193 self.srv_hosts = nil;
194 end, 1000); 194 end, 1000);
195 end 195 end
196 start_connect(); 196 start_connect();

mercurial