plugins/mod_bosh.lua

changeset 866
8958fe4b2391
parent 816
c031ead9896d
child 947
84202314ab7f
equal deleted inserted replaced
865:2dce34e9182d 866:8958fe4b2391
19 local BOSH_DEFAULT_HOLD = tonumber(config.get("*", "core", "bosh_default_hold")) or 1; 19 local BOSH_DEFAULT_HOLD = tonumber(config.get("*", "core", "bosh_default_hold")) or 1;
20 local BOSH_DEFAULT_INACTIVITY = tonumber(config.get("*", "core", "bosh_max_inactivity")) or 60; 20 local BOSH_DEFAULT_INACTIVITY = tonumber(config.get("*", "core", "bosh_max_inactivity")) or 60;
21 local BOSH_DEFAULT_POLLING = tonumber(config.get("*", "core", "bosh_max_polling")) or 5; 21 local BOSH_DEFAULT_POLLING = tonumber(config.get("*", "core", "bosh_max_polling")) or 5;
22 local BOSH_DEFAULT_REQUESTS = tonumber(config.get("*", "core", "bosh_max_requests")) or 2; 22 local BOSH_DEFAULT_REQUESTS = tonumber(config.get("*", "core", "bosh_max_requests")) or 2;
23 local BOSH_DEFAULT_MAXPAUSE = tonumber(config.get("*", "core", "bosh_max_pause")) or 300; 23 local BOSH_DEFAULT_MAXPAUSE = tonumber(config.get("*", "core", "bosh_max_pause")) or 300;
24
25 local default_headers = { ["Content-Type"] = "text/xml; charset=utf-8" };
24 26
25 local t_insert, t_remove, t_concat = table.insert, table.remove, table.concat; 27 local t_insert, t_remove, t_concat = table.insert, table.remove, table.concat;
26 local os_time = os.time; 28 local os_time = os.time;
27 29
28 local sessions = {}; 30 local sessions = {};
98 end 100 end
99 101
100 102
101 local function bosh_reset_stream(session) session.notopen = true; end 103 local function bosh_reset_stream(session) session.notopen = true; end
102 104
103 local session_close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate" }); 105 local session_close_reply = { headers = default_headers, body = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate" }) };
104 local function bosh_close_stream(session, reason) 106 local function bosh_close_stream(session, reason)
105 (session.log or log)("info", "BOSH client disconnected"); 107 (session.log or log)("info", "BOSH client disconnected");
106 session_close_reply.attr.condition = reason; 108 session_close_reply.attr.condition = reason;
107 local session_close_reply = tostring(session_close_reply); 109 local session_close_reply = tostring(session_close_reply);
108 for _, held_request in ipairs(session.requests) do 110 for _, held_request in ipairs(session.requests) do
122 124
123 -- TODO: Sanity checks here (rid, to, known host, etc.) 125 -- TODO: Sanity checks here (rid, to, known host, etc.)
124 if not hosts[attr.to] then 126 if not hosts[attr.to] then
125 -- Unknown host 127 -- Unknown host
126 session_close_reply.attr.condition = "host-unknown"; 128 session_close_reply.attr.condition = "host-unknown";
127 request:send(tostring(session_close_reply)); 129 request:send{ headers = default_headers, body = tostring(session_close_reply) };
128 request.notopen = nil 130 request.notopen = nil
129 return; 131 return;
130 end 132 end
131 133
132 -- New session 134 -- New session
135 bosh_hold = BOSH_DEFAULT_HOLD, bosh_max_inactive = BOSH_DEFAULT_INACTIVITY, 137 bosh_hold = BOSH_DEFAULT_HOLD, bosh_max_inactive = BOSH_DEFAULT_INACTIVITY,
136 requests = { }, send_buffer = {}, reset_stream = bosh_reset_stream, close = bosh_close_stream, dispatch_stanza = core_process_stanza }; 138 requests = { }, send_buffer = {}, reset_stream = bosh_reset_stream, close = bosh_close_stream, dispatch_stanza = core_process_stanza };
137 sessions[sid] = session; 139 sessions[sid] = session;
138 log("info", "New BOSH session, assigned it sid '%s'", sid); 140 log("info", "New BOSH session, assigned it sid '%s'", sid);
139 local r, send_buffer = session.requests, session.send_buffer; 141 local r, send_buffer = session.requests, session.send_buffer;
140 local response = { } 142 local response = { headers = default_headers }
141 function session.send(s) 143 function session.send(s)
142 log("debug", "Sending BOSH data: %s", tostring(s)); 144 log("debug", "Sending BOSH data: %s", tostring(s));
143 local oldest_request = r[1]; 145 local oldest_request = r[1];
144 while oldest_request and oldest_request.destroyed do 146 while oldest_request and oldest_request.destroyed do
145 t_remove(r, 1); 147 t_remove(r, 1);
177 --xmpp:version='1.0' xmlns:xmpp='urn:xmpp:xbosh' 179 --xmpp:version='1.0' xmlns:xmpp='urn:xmpp:xbosh'
178 local response = st.stanza("body", { xmlns = xmlns_bosh, 180 local response = st.stanza("body", { xmlns = xmlns_bosh,
179 inactivity = tostring(BOSH_DEFAULT_INACTIVITY), polling = tostring(BOSH_DEFAULT_POLLING), requests = tostring(BOSH_DEFAULT_REQUESTS), hold = tostring(session.bosh_hold), maxpause = "120", 181 inactivity = tostring(BOSH_DEFAULT_INACTIVITY), polling = tostring(BOSH_DEFAULT_POLLING), requests = tostring(BOSH_DEFAULT_REQUESTS), hold = tostring(session.bosh_hold), maxpause = "120",
180 sid = sid, ver = '1.6', from = session.host, secure = 'true', ["xmpp:version"] = "1.0", 182 sid = sid, ver = '1.6', from = session.host, secure = 'true', ["xmpp:version"] = "1.0",
181 ["xmlns:xmpp"] = "urn:xmpp:xbosh", ["xmlns:stream"] = "http://etherx.jabber.org/streams" }):add_child(features); 183 ["xmlns:xmpp"] = "urn:xmpp:xbosh", ["xmlns:stream"] = "http://etherx.jabber.org/streams" }):add_child(features);
182 request:send(tostring(response)); 184 request:send{ headers = default_headers, body = tostring(response) };
183 185
184 request.sid = sid; 186 request.sid = sid;
185 return; 187 return;
186 end 188 end
187 189
188 local session = sessions[sid]; 190 local session = sessions[sid];
189 if not session then 191 if not session then
190 -- Unknown sid 192 -- Unknown sid
191 log("info", "Client tried to use sid '%s' which we don't know about", sid); 193 log("info", "Client tried to use sid '%s' which we don't know about", sid);
192 request:send(tostring(st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", condition = "item-not-found" }))); 194 request:send{ headers = default_headers, body = tostring(st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", condition = "item-not-found" })) };
193 request.notopen = nil; 195 request.notopen = nil;
194 return; 196 return;
195 end 197 end
196 198
197 if attr.type == "terminate" then 199 if attr.type == "terminate" then

mercurial