break;
end
end
-
+
-- If this session now has no requests open, mark it as inactive
local max_inactive = session.bosh_max_inactive;
if max_inactive and #requests == 0 then
if cross_domain and event.request.headers.origin then
set_cross_domain_headers(response);
end
-
+
-- stream:feed() calls the stream_callbacks, so all stanzas in
-- the body are processed in this next line before it returns.
-- In particular, the streamopened() stream callback is where
module:log("warn", "Error parsing BOSH payload")
return 400;
end
-
+
-- Stanzas (if any) in the request have now been processed, and
-- we take care of the high-level BOSH logic here, including
-- giving a response or putting the request "on hold".
session.send_buffer = {};
session.send(resp);
end
-
+
if not response.finished then
-- We're keeping this request open, to respond later
log("debug", "Have nothing to say, so leaving request unanswered for now");
waiting_requests[response] = os_time() + session.bosh_wait;
end
end
-
+
if session.bosh_terminate then
session.log("debug", "Closing session with %d requests open", #session.requests);
session:close();
local function bosh_close_stream(session, reason)
(session.log or log)("info", "BOSH client disconnected");
-
+
local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate",
["xmlns:stream"] = xmlns_streams });
-
+
if reason then
close_reply.attr.condition = "remote-stream-error";
if not sid then
-- New session request
context.notopen = nil; -- Signals that we accept this opening tag
-
+
-- TODO: Sanity checks here (rid, to, known host, etc.)
if not hosts[attr.to] then
-- Unknown host
response:send(tostring(close_reply));
return;
end
-
+
-- New session
sid = new_uuid();
local session = {
ip = get_ip_from_request(request);
};
sessions[sid] = session;
-
+
local filter = initialize_filters(session);
-
+
session.log("debug", "BOSH session created for request from %s", session.ip);
log("info", "New BOSH session, assigned it sid '%s'", sid);
end
request.sid = sid;
end
-
+
local session = sessions[sid];
if not session then
-- Unknown sid
context.notopen = nil;
return;
end
-
+
if session.rid then
local rid = tonumber(attr.rid);
local diff = rid - session.rid;
end
session.rid = rid;
end
-
+
if attr.type == "terminate" then
-- Client wants to end this session, which we'll do
-- after processing any stanzas in this request
response:send();
return;
end
-
+
local session = sessions[context.sid];
if error == "stream-error" then -- Remote stream error, we close normally
session:close();
end
end
end
-
+
now = now - 3;
local n_dead_sessions = 0;
for session, close_after in pairs(inactive_sessions) do