-
Notifications
You must be signed in to change notification settings - Fork 127
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
370 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
|
||
local stats = require "util.statistics".new(); | ||
local config = require "core.configmanager"; | ||
local log = require "util.logger".init("stats"); | ||
local timer = require "util.timer"; | ||
local fire_event = prosody.events.fire_event; | ||
|
||
local stats_config = config.get("*", "statistics_interval"); | ||
local stats_interval = tonumber(stats_config); | ||
if stats_config and not stats_interval then | ||
log("error", "Invalid 'statistics_interval' setting, statistics will be disabled"); | ||
end | ||
|
||
local measure, collect; | ||
local latest_stats = {}; | ||
local changed_stats = {}; | ||
local stats_extra = {}; | ||
|
||
if stats_interval then | ||
log("debug", "Statistics collection is enabled every %d seconds", stats_interval); | ||
function measure(type, name) | ||
local f = assert(stats[type], "unknown stat type: "..type); | ||
return f(name); | ||
end | ||
|
||
local mark_collection_start = measure("times", "stats.collection"); | ||
local mark_processing_start = measure("times", "stats.processing"); | ||
|
||
function collect() | ||
local mark_collection_done = mark_collection_start(); | ||
changed_stats, stats_extra = {}, {}; | ||
for stat_name, getter in pairs(stats.get_stats()) do | ||
local type, value, extra = getter(); | ||
local old_value = latest_stats[stat_name]; | ||
latest_stats[stat_name] = value; | ||
if value ~= old_value then | ||
changed_stats[stat_name] = value; | ||
end | ||
if extra then | ||
stats_extra[stat_name] = extra; | ||
end | ||
end | ||
mark_collection_done(); | ||
local mark_processing_done = mark_processing_start(); | ||
fire_event("stats-updated", { stats = latest_stats, changed_stats = changed_stats, stats_extra = stats_extra }); | ||
mark_processing_done(); | ||
return stats_interval; | ||
end | ||
|
||
timer.add_task(stats_interval, collect); | ||
else | ||
log("debug", "Statistics collection is disabled"); | ||
-- nop | ||
function measure() | ||
return measure; | ||
end | ||
function collect() | ||
end | ||
end | ||
|
||
return { | ||
measure = measure; | ||
collect = collect; | ||
get_stats = function () | ||
return latest_stats, changed_stats, stats_extra; | ||
end; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
-- XEP-0280: Message Carbons implementation for Prosody | ||
-- Copyright (C) 2011 Kim Alvefur | ||
-- | ||
-- This file is MIT/X11 licensed. | ||
|
||
local st = require "util.stanza"; | ||
local jid_bare = require "util.jid".bare; | ||
local xmlns_carbons = "urn:xmpp:carbons:2"; | ||
local xmlns_forward = "urn:xmpp:forward:0"; | ||
local full_sessions, bare_sessions = full_sessions, bare_sessions; | ||
|
||
local function toggle_carbons(event) | ||
local origin, stanza = event.origin, event.stanza; | ||
local state = stanza.tags[1].name; | ||
module:log("debug", "%s %sd carbons", origin.full_jid, state); | ||
origin.want_carbons = state == "enable" and stanza.tags[1].attr.xmlns; | ||
return origin.send(st.reply(stanza)); | ||
end | ||
module:hook("iq-set/self/"..xmlns_carbons..":disable", toggle_carbons); | ||
module:hook("iq-set/self/"..xmlns_carbons..":enable", toggle_carbons); | ||
|
||
local function message_handler(event, c2s) | ||
local origin, stanza = event.origin, event.stanza; | ||
local orig_type = stanza.attr.type; | ||
local orig_from = stanza.attr.from; | ||
local orig_to = stanza.attr.to; | ||
|
||
if not (orig_type == nil | ||
or orig_type == "normal" | ||
or orig_type == "chat") then | ||
return -- No carbons for messages of type error or headline | ||
end | ||
|
||
-- Stanza sent by a local client | ||
local bare_jid = jid_bare(orig_from); | ||
local target_session = origin; | ||
local top_priority = false; | ||
local user_sessions = bare_sessions[bare_jid]; | ||
|
||
-- Stanza about to be delivered to a local client | ||
if not c2s then | ||
bare_jid = jid_bare(orig_to); | ||
target_session = full_sessions[orig_to]; | ||
user_sessions = bare_sessions[bare_jid]; | ||
if not target_session and user_sessions then | ||
-- The top resources will already receive this message per normal routing rules, | ||
-- so we are going to skip them in order to avoid sending duplicated messages. | ||
local top_resources = user_sessions.top_resources; | ||
top_priority = top_resources and top_resources[1].priority | ||
end | ||
end | ||
|
||
if not user_sessions then | ||
module:log("debug", "Skip carbons for offline user"); | ||
return -- No use in sending carbons to an offline user | ||
end | ||
|
||
if stanza:get_child("private", xmlns_carbons) then | ||
if not c2s then | ||
stanza:maptags(function(tag) | ||
if not ( tag.attr.xmlns == xmlns_carbons and tag.name == "private" ) then | ||
return tag; | ||
end | ||
end); | ||
end | ||
module:log("debug", "Message tagged private, ignoring"); | ||
return | ||
elseif stanza:get_child("no-copy", "urn:xmpp:hints") then | ||
module:log("debug", "Message has no-copy hint, ignoring"); | ||
return | ||
elseif stanza:get_child("x", "http://jabber.org/protocol/muc#user") then | ||
module:log("debug", "MUC PM, ignoring"); | ||
return | ||
end | ||
|
||
-- Create the carbon copy and wrap it as per the Stanza Forwarding XEP | ||
local copy = st.clone(stanza); | ||
copy.attr.xmlns = "jabber:client"; | ||
local carbon = st.message{ from = bare_jid, type = orig_type, } | ||
:tag(c2s and "sent" or "received", { xmlns = xmlns_carbons }) | ||
:tag("forwarded", { xmlns = xmlns_forward }) | ||
:add_child(copy):reset(); | ||
|
||
user_sessions = user_sessions and user_sessions.sessions; | ||
for _, session in pairs(user_sessions) do | ||
-- Carbons are sent to resources that have enabled it | ||
if session.want_carbons | ||
-- but not the resource that sent the message, or the one that it's directed to | ||
and session ~= target_session | ||
-- and isn't among the top resources that would receive the message per standard routing rules | ||
and (c2s or session.priority ~= top_priority) then | ||
carbon.attr.to = session.full_jid; | ||
module:log("debug", "Sending carbon to %s", session.full_jid); | ||
session.send(carbon); | ||
end | ||
end | ||
end | ||
|
||
local function c2s_message_handler(event) | ||
return message_handler(event, true) | ||
end | ||
|
||
-- Stanzas sent by local clients | ||
module:hook("pre-message/host", c2s_message_handler, 1); | ||
module:hook("pre-message/bare", c2s_message_handler, 1); | ||
module:hook("pre-message/full", c2s_message_handler, 1); | ||
-- Stanzas to local clients | ||
module:hook("message/bare", message_handler, 1); | ||
module:hook("message/full", message_handler, 1); | ||
|
||
module:add_feature(xmlns_carbons); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,25 @@ | ||
local s_char = string.char; | ||
local s_format = string.format; | ||
local s_gsub = string.gsub; | ||
|
||
local function char_to_hex(c) | ||
return ("%02x"):format(c:byte()) | ||
end | ||
local char_to_hex = {}; | ||
local hex_to_char = {}; | ||
|
||
local function hex_to_char(h) | ||
return s_char(tonumber(h, 16)); | ||
do | ||
local char, hex; | ||
for i = 0,255 do | ||
char, hex = s_char(i), s_format("%02x", i); | ||
char_to_hex[char] = hex; | ||
hex_to_char[hex] = char; | ||
end | ||
end | ||
|
||
local function to(s) | ||
return s:gsub(".", char_to_hex); | ||
return (s_gsub(s, ".", char_to_hex)); | ||
end | ||
|
||
local function from(s) | ||
return s:gsub("..", hex_to_char); | ||
return (s_gsub(s, "..", hex_to_char)); | ||
end | ||
|
||
return { to = to, from = from } |
Oops, something went wrong.