local stream_callbacks = {
stream_ns = xmlns_bosh, stream_tag = "body", default_ns = "jabber:client" };
-local BOSH_DEFAULT_HOLD = tonumber(module:get_option("bosh_default_hold")) or 1;
-local BOSH_DEFAULT_INACTIVITY = tonumber(module:get_option("bosh_max_inactivity")) or 60;
-local BOSH_DEFAULT_POLLING = tonumber(module:get_option("bosh_max_polling")) or 5;
-local BOSH_DEFAULT_REQUESTS = tonumber(module:get_option("bosh_max_requests")) or 2;
+local BOSH_DEFAULT_HOLD = module:get_option_number("bosh_default_hold", 1);
+local BOSH_DEFAULT_INACTIVITY = module:get_option_number("bosh_max_inactivity", 60);
+local BOSH_DEFAULT_POLLING = module:get_option_number("bosh_max_polling", 5);
+local BOSH_DEFAULT_REQUESTS = module:get_option_number("bosh_max_requests", 2);
local consider_bosh_secure = module:get_option_boolean("consider_bosh_secure");
local default_headers = { ["Content-Type"] = "text/xml; charset=utf-8" };
-local cross_domain = module:get_option("cross_domain_bosh");
+local cross_domain = module:get_option("cross_domain_bosh", false);
if cross_domain then
default_headers["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS";
default_headers["Access-Control-Allow-Headers"] = "Content-Type";
end
-- If this session now has no requests open, mark it as inactive
- if #requests == 0 and session.bosh_max_inactive and not inactive_sessions[session] then
- inactive_sessions[session] = os_time();
- (session.log or log)("debug", "BOSH session marked as inactive at %d", inactive_sessions[session]);
+ local max_inactive = session.bosh_max_inactive;
+ if max_inactive and #requests == 0 then
+ inactive_sessions[session] = os_time() + max_inactive;
+ (session.log or log)("debug", "BOSH session marked as inactive (for %ds)", max_inactive);
end
end
end
local session = sessions[request.sid];
if session then
+ -- Session was marked as inactive, since we have
+ -- a request open now, unmark it
+ if inactive_sessions[session] and #session.requests > 0 then
+ inactive_sessions[session] = nil;
+ end
+
local r = session.requests;
log("debug", "Session %s has %d out of %d requests open", request.sid, #r, session.bosh_hold);
log("debug", "and there are %d things in the send_buffer", #session.send_buffer);
request.reply_before = os_time() + session.bosh_wait;
waiting_requests[request] = true;
end
- if inactive_sessions[session] then
- -- Session was marked as inactive, since we have
- -- a request open now, unmark it
- inactive_sessions[session] = nil;
- end
end
- return true; -- Inform httpserver we shall reply later
+ if session.bosh_terminate then
+ session.log("debug", "Closing session with %d requests open", #session.requests);
+ session:close();
+ return nil;
+ else
+ return true; -- Inform httpserver we shall reply later
+ end
end
end
(session.log or log)("info", "BOSH client disconnected");
local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate",
- ["xmlns:streams"] = xmlns_streams });
+ ["xmlns:stream"] = xmlns_streams });
if reason then
local session_close_response = { headers = default_headers, body = tostring(close_reply) };
- --FIXME: Quite sure we shouldn't reply to all requests with the error
for _, held_request in ipairs(session.requests) do
held_request:send(session_close_response);
held_request:destroy();
end
function stream_callbacks.streamopened(request, attr)
- log("debug", "BOSH body open (sid: %s)", attr.sid);
- local sid = attr.sid
+ local sid = attr.sid;
+ log("debug", "BOSH body open (sid: %s)", sid or "<none>");
if not sid then
-- New session request
request.notopen = nil; -- Signals that we accept this opening tag
-- Unknown host
log("debug", "BOSH client tried to connect to unknown host: %s", tostring(attr.to));
local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate",
- ["xmlns:streams"] = xmlns_streams, condition = "host-unknown" });
+ ["xmlns:stream"] = xmlns_streams, condition = "host-unknown" });
request:send(tostring(close_reply));
return;
end
local oldest_request = r[1];
if oldest_request then
log("debug", "We have an open request, so sending on that");
- response.body = t_concat{"<body xmlns='http://jabber.org/protocol/httpbind' sid='", sid, "' xmlns:stream = 'http://etherx.jabber.org/streams'>", tostring(s), "</body>" };
+ response.body = t_concat({
+ "<body xmlns='http://jabber.org/protocol/httpbind' ",
+ session.bosh_terminate and "type='terminate' " or "",
+ "sid='", sid, "' xmlns:stream = 'http://etherx.jabber.org/streams'>",
+ tostring(s),
+ "</body>"
+ });
oldest_request:send(response);
--log("debug", "Sent");
if oldest_request.stayopen then
t_insert(session.send_buffer, tostring(s));
log("debug", "There are now %d things in the send_buffer", #session.send_buffer);
end
+ return true;
end
-- Send creation response
session.rid = rid;
end
- if attr.type == "terminate" then
- -- Client wants to end this session
- session:close();
- request.notopen = nil;
- return;
- end
-
if session.notopen then
local features = st.stanza("stream:features");
hosts[session.host].events.fire_event("stream-features", { origin = session, features = features });
session.notopen = nil;
end
+ if attr.type == "terminate" then
+ -- Client wants to end this session, which we'll do
+ -- after processing any stanzas in this request
+ session.bosh_terminate = true;
+ end
+
request.notopen = nil; -- Signals that we accept this opening tag
t_insert(session.requests, request);
request.sid = sid;
now = now - 3;
local n_dead_sessions = 0;
- for session, inactive_since in pairs(inactive_sessions) do
- if session.bosh_max_inactive then
- if now - inactive_since > session.bosh_max_inactive then
- (session.log or log)("debug", "BOSH client inactive too long, destroying session at %d", now);
- sessions[session.sid] = nil;
- inactive_sessions[session] = nil;
- n_dead_sessions = n_dead_sessions + 1;
- dead_sessions[n_dead_sessions] = session;
- end
- else
+ for session, close_after in pairs(inactive_sessions) do
+ if close_after < now then
+ (session.log or log)("debug", "BOSH client inactive too long, destroying session at %d", now);
+ sessions[session.sid] = nil;
inactive_sessions[session] = nil;
+ n_dead_sessions = n_dead_sessions + 1;
+ dead_sessions[n_dead_sessions] = session;
end
end
local function setup()
- local ports = module:get_option("bosh_ports") or { 5280 };
+ local ports = module:get_option_array("bosh_ports") or { 5280 };
httpserver.new_from_config(ports, handle_request, { base = "http-bind" });
timer.add_task(1, on_timer);
end