mod_websocket: Fire pre-session-close event (fixes #1800)
This event was added in a7c183bb4e64 and is required to make mod_smacks know
that a session was intentionally closed and shouldn't be hibernated (see
fcea4d9e7502).
Because this was missing from mod_websocket's session.close(), mod_smacks
would always attempt to hibernate websocket sessions even if they closed
cleanly.
That mod_websocket has its own copy of session.close() is something to fix
another day (probably not in the stable branch). So for now this commit makes
the minimal change to get things working again.
Thanks to Damian and the Jitsi team for reporting.
-- Prosody IM
-- Copyright (C) 2013 Florian Zeitz
--
-- This project is MIT/X11 licensed. Please see the
-- COPYING file in the source package for more information.
--
local format, char = string.format, string.char;
local pairs, ipairs = pairs, ipairs;
local t_insert, t_concat = table.insert, table.concat;
local url_codes = {};
for i = 0, 255 do
local c = char(i);
local u = format("%%%02x", i);
url_codes[c] = u;
url_codes[u] = c;
url_codes[u:upper()] = c;
end
local function urlencode(s)
return s and (s:gsub("[^a-zA-Z0-9.~_-]", url_codes));
end
local function urldecode(s)
return s and (s:gsub("%%%x%x", url_codes));
end
local function _formencodepart(s)
return s and (urlencode(s):gsub("%%20", "+"));
end
local function formencode(form)
local result = {};
if form[1] then -- Array of ordered { name, value }
for _, field in ipairs(form) do
t_insert(result, _formencodepart(field.name).."=".._formencodepart(field.value));
end
else -- Unordered map of name -> value
for name, value in pairs(form) do
t_insert(result, _formencodepart(name).."=".._formencodepart(value));
end
end
return t_concat(result, "&");
end
local function formdecode(s)
if not s:match("=") then return urldecode(s); end
local r = {};
for k, v in s:gmatch("([^=&]*)=([^&]*)") do
k, v = k:gsub("%+", "%%20"), v:gsub("%+", "%%20");
k, v = urldecode(k), urldecode(v);
t_insert(r, { name = k, value = v });
r[k] = v;
end
return r;
end
local function contains_token(field, token)
field = ","..field:gsub("[ \t]", ""):lower()..",";
return field:find(","..token:lower()..",", 1, true) ~= nil;
end
local function normalize_path(path, is_dir)
if is_dir then
if path:sub(-1,-1) ~= "/" then path = path.."/"; end
else
if path:sub(-1,-1) == "/" then path = path:sub(1, -2); end
end
if path:sub(1,1) ~= "/" then path = "/"..path; end
return path;
end
return {
urlencode = urlencode, urldecode = urldecode;
formencode = formencode, formdecode = formdecode;
contains_token = contains_token;
normalize_path = normalize_path;
};