源战役客户端
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 

256 行
8.6 KiB

-- -----------------------------------------------------------------------------
-- -- SMTP client support for the Lua language.
-- -- LuaSocket toolkit.
-- -- Author: Diego Nehab
-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------
-- -- Declare module and import dependencies
-- -----------------------------------------------------------------------------
-- local base = _G
-- local coroutine = require("coroutine")
-- local string = require("string")
-- local math = require("math")
-- local os = require("os")
-- local socket = require("socket")
-- local tp = require("socket.tp")
-- local ltn12 = require("ltn12")
-- local headers = require("socket.headers")
-- local mime = require("mime")
-- socket.smtp = {}
-- local _M = socket.smtp
-- -----------------------------------------------------------------------------
-- -- Program constants
-- -----------------------------------------------------------------------------
-- -- timeout for connection
-- _M.TIMEOUT = 60
-- -- default server used to send e-mails
-- _M.SERVER = "localhost"
-- -- default port
-- _M.PORT = 25
-- -- domain used in HELO command and default sendmail
-- -- If we are under a CGI, try to get from environment
-- _M.DOMAIN = os.getenv("SERVER_NAME") or "localhost"
-- -- default time zone (means we don't know)
-- _M.ZONE = "-0000"
-- ---------------------------------------------------------------------------
-- -- Low level SMTP API
-- -----------------------------------------------------------------------------
-- local metat = { __index = {} }
-- function metat.__index:greet(domain)
-- self.try(self.tp:check("2.."))
-- self.try(self.tp:command("EHLO", domain or _M.DOMAIN))
-- return socket.skip(1, self.try(self.tp:check("2..")))
-- end
-- function metat.__index:mail(from)
-- self.try(self.tp:command("MAIL", "FROM:" .. from))
-- return self.try(self.tp:check("2.."))
-- end
-- function metat.__index:rcpt(to)
-- self.try(self.tp:command("RCPT", "TO:" .. to))
-- return self.try(self.tp:check("2.."))
-- end
-- function metat.__index:data(src, step)
-- self.try(self.tp:command("DATA"))
-- self.try(self.tp:check("3.."))
-- self.try(self.tp:source(src, step))
-- self.try(self.tp:send("\r\n.\r\n"))
-- return self.try(self.tp:check("2.."))
-- end
-- function metat.__index:quit()
-- self.try(self.tp:command("QUIT"))
-- return self.try(self.tp:check("2.."))
-- end
-- function metat.__index:close()
-- return self.tp:close()
-- end
-- function metat.__index:login(user, password)
-- self.try(self.tp:command("AUTH", "LOGIN"))
-- self.try(self.tp:check("3.."))
-- self.try(self.tp:send(mime.b64(user) .. "\r\n"))
-- self.try(self.tp:check("3.."))
-- self.try(self.tp:send(mime.b64(password) .. "\r\n"))
-- return self.try(self.tp:check("2.."))
-- end
-- function metat.__index:plain(user, password)
-- local auth = "PLAIN " .. mime.b64("\0" .. user .. "\0" .. password)
-- self.try(self.tp:command("AUTH", auth))
-- return self.try(self.tp:check("2.."))
-- end
-- function metat.__index:auth(user, password, ext)
-- if not user or not password then return 1 end
-- if string.find(ext, "AUTH[^\n]+LOGIN") then
-- return self:login(user, password)
-- elseif string.find(ext, "AUTH[^\n]+PLAIN") then
-- return self:plain(user, password)
-- else
-- self.try(nil, "authentication not supported")
-- end
-- end
-- -- send message or throw an exception
-- function metat.__index:send(mailt)
-- self:mail(mailt.from)
-- if base.type(mailt.rcpt) == "table" then
-- for i,v in base.ipairs(mailt.rcpt) do
-- self:rcpt(v)
-- end
-- else
-- self:rcpt(mailt.rcpt)
-- end
-- self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step)
-- end
-- function _M.open(server, port, create)
-- local tp = socket.try(tp.connect(server or _M.SERVER, port or _M.PORT,
-- _M.TIMEOUT, create))
-- local s = base.setmetatable({tp = tp}, metat)
-- -- make sure tp is closed if we get an exception
-- s.try = socket.newtry(function()
-- s:close()
-- end)
-- return s
-- end
-- -- convert headers to lowercase
-- local function lower_headers(headers)
-- local lower = {}
-- for i,v in base.pairs(headers or lower) do
-- lower[string.lower(i)] = v
-- end
-- return lower
-- end
-- ---------------------------------------------------------------------------
-- -- Multipart message source
-- -----------------------------------------------------------------------------
-- -- returns a hopefully unique mime boundary
-- local seqno = 0
-- local function newboundary()
-- seqno = seqno + 1
-- return string.format('%s%05d==%05u', os.date('%d%m%Y%H%M%S'),
-- math.random(0, 99999), seqno)
-- end
-- -- send_message forward declaration
-- local send_message
-- -- yield the headers all at once, it's faster
-- local function send_headers(tosend)
-- local canonic = headers.canonic
-- local h = "\r\n"
-- for f,v in base.pairs(tosend) do
-- h = (canonic[f] or f) .. ': ' .. v .. "\r\n" .. h
-- end
-- coroutine.yield(h)
-- end
-- -- yield multipart message body from a multipart message table
-- local function send_multipart(mesgt)
-- -- make sure we have our boundary and send headers
-- local bd = newboundary()
-- local headers = lower_headers(mesgt.headers or {})
-- headers['content-type'] = headers['content-type'] or 'multipart/mixed'
-- headers['content-type'] = headers['content-type'] ..
-- '; boundary="' .. bd .. '"'
-- send_headers(headers)
-- -- send preamble
-- if mesgt.body.preamble then
-- coroutine.yield(mesgt.body.preamble)
-- coroutine.yield("\r\n")
-- end
-- -- send each part separated by a boundary
-- for i, m in base.ipairs(mesgt.body) do
-- coroutine.yield("\r\n--" .. bd .. "\r\n")
-- send_message(m)
-- end
-- -- send last boundary
-- coroutine.yield("\r\n--" .. bd .. "--\r\n\r\n")
-- -- send epilogue
-- if mesgt.body.epilogue then
-- coroutine.yield(mesgt.body.epilogue)
-- coroutine.yield("\r\n")
-- end
-- end
-- -- yield message body from a source
-- local function send_source(mesgt)
-- -- make sure we have a content-type
-- local headers = lower_headers(mesgt.headers or {})
-- headers['content-type'] = headers['content-type'] or
-- 'text/plain; charset="iso-8859-1"'
-- send_headers(headers)
-- -- send body from source
-- while true do
-- local chunk, err = mesgt.body()
-- if err then coroutine.yield(nil, err)
-- elseif chunk then coroutine.yield(chunk)
-- else break end
-- end
-- end
-- -- yield message body from a string
-- local function send_string(mesgt)
-- -- make sure we have a content-type
-- local headers = lower_headers(mesgt.headers or {})
-- headers['content-type'] = headers['content-type'] or
-- 'text/plain; charset="iso-8859-1"'
-- send_headers(headers)
-- -- send body from string
-- coroutine.yield(mesgt.body)
-- end
-- -- message source
-- function send_message(mesgt)
-- if base.type(mesgt.body) == "table" then send_multipart(mesgt)
-- elseif base.type(mesgt.body) == "function" then send_source(mesgt)
-- else send_string(mesgt) end
-- end
-- -- set defaul headers
-- local function adjust_headers(mesgt)
-- local lower = lower_headers(mesgt.headers)
-- lower["date"] = lower["date"] or
-- os.date("!%a, %d %b %Y %H:%M:%S ") .. (mesgt.zone or _M.ZONE)
-- lower["x-mailer"] = lower["x-mailer"] or socket._VERSION
-- -- this can't be overriden
-- lower["mime-version"] = "1.0"
-- return lower
-- end
-- function _M.message(mesgt)
-- mesgt.headers = adjust_headers(mesgt)
-- -- create and return message source
-- local co = coroutine.create(function() send_message(mesgt) end)
-- return function()
-- local ret, a, b = coroutine.resume(co)
-- if ret then return a, b
-- else return nil, a end
-- end
-- end
-- ---------------------------------------------------------------------------
-- -- High level SMTP API
-- -----------------------------------------------------------------------------
-- _M.send = socket.protect(function(mailt)
-- local s = _M.open(mailt.server, mailt.port, mailt.create)
-- local ext = s:greet(mailt.domain)
-- s:auth(mailt.user, mailt.password, ext)
-- s:send(mailt)
-- s:quit()
-- return s:close()
-- end)
-- return _M