plugins/mod_bosh.lua
changeset 9994 f122972b77b2
parent 9803 7259a61bacc8
child 10115 0f335815244f
equal deleted inserted replaced
9993:026f9594f661 9994:f122972b77b2
    53 local t_insert, t_remove, t_concat = table.insert, table.remove, table.concat;
    53 local t_insert, t_remove, t_concat = table.insert, table.remove, table.concat;
    54 
    54 
    55 -- All sessions, and sessions that have no requests open
    55 -- All sessions, and sessions that have no requests open
    56 local sessions = module:shared("sessions");
    56 local sessions = module:shared("sessions");
    57 
    57 
       
    58 local measure_active = module:measure("active_sessions", "amount");
       
    59 local measure_inactive = module:measure("inactive_sessions", "amount");
       
    60 local report_bad_host = module:measure("bad_host", "rate");
       
    61 local report_bad_sid = module:measure("bad_sid", "rate");
       
    62 local report_new_sid = module:measure("new_sid", "rate");
       
    63 local report_timeout = module:measure("timeout", "rate");
       
    64 
       
    65 module:hook("stats-update", function ()
       
    66 	local active = 0;
       
    67 	local inactive = 0;
       
    68 	for _, session in pairs(sessions) do
       
    69 		if #session.requests > 0 then
       
    70 			active = active + 1;
       
    71 		else
       
    72 			inactive = inactive + 1;
       
    73 		end
       
    74 	end
       
    75 	measure_active(active);
       
    76 	measure_inactive(inactive);
       
    77 end);
       
    78 
    58 -- Used to respond to idle sessions (those with waiting requests)
    79 -- Used to respond to idle sessions (those with waiting requests)
    59 function on_destroy_request(request)
    80 function on_destroy_request(request)
    60 	log("debug", "Request destroyed: %s", tostring(request));
    81 	log("debug", "Request destroyed: %s", tostring(request));
    61 	local session = sessions[request.context.sid];
    82 	local session = sessions[request.context.sid];
    62 	if session then
    83 	if session then
    72 		local max_inactive = session.bosh_max_inactive;
    93 		local max_inactive = session.bosh_max_inactive;
    73 		if max_inactive and #requests == 0 then
    94 		if max_inactive and #requests == 0 then
    74 			if session.inactive_timer then
    95 			if session.inactive_timer then
    75 				session.inactive_timer:stop();
    96 				session.inactive_timer:stop();
    76 			end
    97 			end
    77 			session.inactive_timer = module:add_timer(max_inactive, check_inactive, session, request.context,
    98 			session.inactive_timer = module:add_timer(max_inactive, session_timeout, session, request.context,
    78 				"BOSH client silent for over "..max_inactive.." seconds");
    99 				"BOSH client silent for over "..max_inactive.." seconds");
    79 			(session.log or log)("debug", "BOSH session marked as inactive (for %ds)", max_inactive);
   100 			(session.log or log)("debug", "BOSH session marked as inactive (for %ds)", max_inactive);
    80 		end
   101 		end
    81 		if session.bosh_wait_timer then
   102 		if session.bosh_wait_timer then
    82 			session.bosh_wait_timer:stop();
   103 			session.bosh_wait_timer:stop();
    83 			session.bosh_wait_timer = nil;
   104 			session.bosh_wait_timer = nil;
    84 		end
   105 		end
    85 	end
   106 	end
    86 end
   107 end
    87 
   108 
    88 function check_inactive(now, session, context, reason) -- luacheck: ignore 212/now
   109 function session_timeout(now, session, context, reason) -- luacheck: ignore 212/now
    89 	if not session.destroyed then
   110 	if not session.destroyed then
       
   111 		report_timeout();
    90 		sessions[context.sid] = nil;
   112 		sessions[context.sid] = nil;
    91 		sm_destroy_session(session, reason);
   113 		sm_destroy_session(session, reason);
    92 	end
   114 	end
    93 end
   115 end
    94 
   116 
   184 		-- A response has been sent already, or we're ignoring this request
   206 		-- A response has been sent already, or we're ignoring this request
   185 		-- (e.g. so a different instance of the module can handle it)
   207 		-- (e.g. so a different instance of the module can handle it)
   186 		return;
   208 		return;
   187 	end
   209 	end
   188 	module:log("warn", "Unable to associate request with a session (incomplete request?)");
   210 	module:log("warn", "Unable to associate request with a session (incomplete request?)");
       
   211 	report_bad_sid();
   189 	local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate",
   212 	local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate",
   190 		["xmlns:stream"] = xmlns_streams, condition = "item-not-found" });
   213 		["xmlns:stream"] = xmlns_streams, condition = "item-not-found" });
   191 	return tostring(close_reply) .. "\n";
   214 	return tostring(close_reply) .. "\n";
   192 end
   215 end
   193 
   216 
   251 
   274 
   252 		local to_host = nameprep(attr.to);
   275 		local to_host = nameprep(attr.to);
   253 		local wait = tonumber(attr.wait);
   276 		local wait = tonumber(attr.wait);
   254 		if not to_host then
   277 		if not to_host then
   255 			log("debug", "BOSH client tried to connect to invalid host: %s", tostring(attr.to));
   278 			log("debug", "BOSH client tried to connect to invalid host: %s", tostring(attr.to));
       
   279 			report_bad_host();
   256 			local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate",
   280 			local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate",
   257 				["xmlns:stream"] = xmlns_streams, condition = "improper-addressing" });
   281 				["xmlns:stream"] = xmlns_streams, condition = "improper-addressing" });
   258 			response:send(tostring(close_reply));
   282 			response:send(tostring(close_reply));
   259 			return;
   283 			return;
   260 		end
   284 		end
   288 
   312 
   289 		local filter = initialize_filters(session);
   313 		local filter = initialize_filters(session);
   290 
   314 
   291 		session.log("debug", "BOSH session created for request from %s", session.ip);
   315 		session.log("debug", "BOSH session created for request from %s", session.ip);
   292 		log("info", "New BOSH session, assigned it sid '%s'", sid);
   316 		log("info", "New BOSH session, assigned it sid '%s'", sid);
       
   317 		report_new_sid();
   293 
   318 
   294 		module:fire_event("bosh-session", { session = session, request = request });
   319 		module:fire_event("bosh-session", { session = session, request = request });
   295 
   320 
   296 		-- Send creation response
   321 		-- Send creation response
   297 		local creating_session = true;
   322 		local creating_session = true;
   342 
   367 
   343 	local session = sessions[sid];
   368 	local session = sessions[sid];
   344 	if not session then
   369 	if not session then
   345 		-- Unknown sid
   370 		-- Unknown sid
   346 		log("info", "Client tried to use sid '%s' which we don't know about", sid);
   371 		log("info", "Client tried to use sid '%s' which we don't know about", sid);
       
   372 		report_bad_sid();
   347 		response:send(tostring(st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", condition = "item-not-found" })));
   373 		response:send(tostring(st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", condition = "item-not-found" })));
   348 		context.notopen = nil;
   374 		context.notopen = nil;
   349 		return;
   375 		return;
   350 	end
   376 	end
   351 
   377