2004-01-19 06:41:30 +01:00
|
|
|
-- make sure LuaSocket is loaded
|
|
|
|
if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end
|
|
|
|
-- get LuaSocket namespace
|
|
|
|
local socket = _G[LUASOCKET_LIBNAME]
|
|
|
|
if not socket then error('module requires LuaSocket') end
|
|
|
|
-- create code namespace inside LuaSocket namespace
|
|
|
|
local mime = socket.mime or {}
|
|
|
|
socket.mime = mime
|
|
|
|
-- make all module globals fall into mime namespace
|
|
|
|
setmetatable(mime, { __index = _G })
|
|
|
|
setfenv(1, mime)
|
|
|
|
|
2004-01-21 02:09:50 +01:00
|
|
|
-- encode, decode and wrap algorithm tables
|
|
|
|
local et = {}
|
|
|
|
local dt = {}
|
|
|
|
local wt = {}
|
2004-01-19 06:41:30 +01:00
|
|
|
|
2004-01-21 02:09:50 +01:00
|
|
|
-- creates a function that chooses an algorithm from a given table
|
|
|
|
local function choose(table)
|
|
|
|
return function(method, ...)
|
|
|
|
local f = table[method or "nil"]
|
2004-01-24 03:47:24 +01:00
|
|
|
if not f then error("unknown method (" .. tostring(method) .. ")", 3)
|
2004-01-21 02:09:50 +01:00
|
|
|
else return f(unpack(arg)) end
|
2004-01-19 06:41:30 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2004-01-21 02:09:50 +01:00
|
|
|
-- creates a function that cicles a filter with a given initial
|
|
|
|
-- context and extra arguments
|
|
|
|
local function cicle(f, ctx, ...)
|
2004-01-19 06:41:30 +01:00
|
|
|
return function(chunk)
|
2004-01-21 02:09:50 +01:00
|
|
|
local ret
|
|
|
|
ret, ctx = f(ctx, chunk, unpack(arg))
|
|
|
|
return ret
|
2004-01-19 06:41:30 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2004-01-21 02:09:50 +01:00
|
|
|
-- function that choose the encoding, decoding or wrap algorithm
|
|
|
|
encode = choose(et)
|
|
|
|
decode = choose(dt)
|
2004-01-24 03:47:24 +01:00
|
|
|
|
|
|
|
-- the wrap filter has default parameters
|
|
|
|
local cwt = choose(wt)
|
|
|
|
function wrap(...)
|
|
|
|
if not arg[1] or type(arg[1]) ~= "string" then
|
|
|
|
table.insert(arg, 1, "base64")
|
|
|
|
end
|
|
|
|
return cwt(unpack(arg))
|
|
|
|
end
|
2004-01-21 02:09:50 +01:00
|
|
|
|
|
|
|
-- define the encoding algorithms
|
|
|
|
et['base64'] = function()
|
|
|
|
return cicle(b64, "")
|
2004-01-19 06:41:30 +01:00
|
|
|
end
|
|
|
|
|
2004-01-21 02:09:50 +01:00
|
|
|
et['quoted-printable'] = function(mode)
|
|
|
|
return cicle(qp, "", (mode == "binary") and "=0D=0A" or "\13\10")
|
|
|
|
end
|
|
|
|
|
|
|
|
-- define the decoding algorithms
|
|
|
|
dt['base64'] = function()
|
|
|
|
return cicle(unb64, "")
|
2004-01-19 06:41:30 +01:00
|
|
|
end
|
|
|
|
|
2004-01-21 02:09:50 +01:00
|
|
|
dt['quoted-printable'] = function()
|
|
|
|
return cicle(unqp, "")
|
|
|
|
end
|
|
|
|
|
|
|
|
-- define the wrap algorithms
|
2004-01-24 03:47:24 +01:00
|
|
|
wt['base64'] = function(length, marker)
|
2004-01-19 06:41:30 +01:00
|
|
|
length = length or 76
|
2004-01-24 03:47:24 +01:00
|
|
|
return cicle(wrp, length, length, marker)
|
2004-01-19 06:41:30 +01:00
|
|
|
end
|
|
|
|
|
2004-01-21 02:09:50 +01:00
|
|
|
wt['quoted-printable'] = function(length)
|
2004-01-19 06:41:30 +01:00
|
|
|
length = length or 76
|
2004-01-24 03:47:24 +01:00
|
|
|
return cicle(qpwrp, length, length)
|
2004-01-19 06:41:30 +01:00
|
|
|
end
|
|
|
|
|
2004-01-21 02:09:50 +01:00
|
|
|
-- define the end-of-line translation function
|
2004-01-19 06:41:30 +01:00
|
|
|
function canonic(marker)
|
2004-01-21 02:09:50 +01:00
|
|
|
return cicle(eol, "", marker)
|
2004-01-19 06:41:30 +01:00
|
|
|
end
|
|
|
|
|
2004-01-21 02:09:50 +01:00
|
|
|
-- chains several filters together
|
2004-01-19 06:41:30 +01:00
|
|
|
function chain(...)
|
|
|
|
local layers = table.getn(arg)
|
|
|
|
return function (chunk)
|
|
|
|
if not chunk then
|
|
|
|
local parts = {}
|
|
|
|
for i = 1, layers do
|
|
|
|
for j = i, layers do
|
|
|
|
chunk = arg[j](chunk)
|
|
|
|
end
|
|
|
|
table.insert(parts, chunk)
|
|
|
|
chunk = nil
|
|
|
|
end
|
|
|
|
return table.concat(parts)
|
|
|
|
else
|
|
|
|
for j = 1, layers do
|
|
|
|
chunk = arg[j](chunk)
|
|
|
|
end
|
|
|
|
return chunk
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return code
|