Build with Lua 5.2 without LUA_COMPAT_MODULE flag.

LUASOCKET_USE_GLOBAL flag enable create global variables when load socket/mime modules.
This commit is contained in:
moteus 2013-05-27 12:45:09 +04:00
parent bd51d8c1a5
commit 920bc97629
14 changed files with 179 additions and 115 deletions

View File

@ -15,27 +15,27 @@ local socket = require("socket")
local url = require("socket.url") local url = require("socket.url")
local tp = require("socket.tp") local tp = require("socket.tp")
local ltn12 = require("ltn12") local ltn12 = require("ltn12")
module("socket.ftp") socket.ftp = {}
local _M = socket.ftp
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Program constants -- Program constants
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- timeout in seconds before the program gives up on a connection -- timeout in seconds before the program gives up on a connection
TIMEOUT = 60 _M.TIMEOUT = 60
-- default port for ftp service -- default port for ftp service
PORT = 21 _M.PORT = 21
-- this is the default anonymous password. used when no password is -- this is the default anonymous password. used when no password is
-- provided in url. should be changed to your e-mail. -- provided in url. should be changed to your e-mail.
USER = "ftp" _M.USER = "ftp"
PASSWORD = "anonymous@anonymous.org" _M.PASSWORD = "anonymous@anonymous.org"
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Low level FTP API -- Low level FTP API
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local metat = { __index = {} } local metat = { __index = {} }
function open(server, port, create) function _M.open(server, port, create)
local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT, create)) local tp = socket.try(tp.connect(server, port or _M.PORT, _M.TIMEOUT, create))
local f = base.setmetatable({ tp = tp }, metat) local f = base.setmetatable({ tp = tp }, metat)
-- make sure everything gets closed in an exception -- make sure everything gets closed in an exception
f.try = socket.newtry(function() f:close() end) f.try = socket.newtry(function() f:close() end)
@ -43,22 +43,22 @@ function open(server, port, create)
end end
function metat.__index:portconnect() function metat.__index:portconnect()
self.try(self.server:settimeout(TIMEOUT)) self.try(self.server:settimeout(_M.TIMEOUT))
self.data = self.try(self.server:accept()) self.data = self.try(self.server:accept())
self.try(self.data:settimeout(TIMEOUT)) self.try(self.data:settimeout(_M.TIMEOUT))
end end
function metat.__index:pasvconnect() function metat.__index:pasvconnect()
self.data = self.try(socket.tcp()) self.data = self.try(socket.tcp())
self.try(self.data:settimeout(TIMEOUT)) self.try(self.data:settimeout(_M.TIMEOUT))
self.try(self.data:connect(self.pasvt.ip, self.pasvt.port)) self.try(self.data:connect(self.pasvt.ip, self.pasvt.port))
end end
function metat.__index:login(user, password) function metat.__index:login(user, password)
self.try(self.tp:command("user", user or USER)) self.try(self.tp:command("user", user or _M.USER))
local code, reply = self.try(self.tp:check{"2..", 331}) local code, reply = self.try(self.tp:check{"2..", 331})
if code == 331 then if code == 331 then
self.try(self.tp:command("pass", password or PASSWORD)) self.try(self.tp:command("pass", password or _M.PASSWORD))
self.try(self.tp:check("2..")) self.try(self.tp:check("2.."))
end end
return 1 return 1
@ -87,7 +87,7 @@ function metat.__index:port(ip, port)
ip, port = self.try(self.tp:getcontrol():getsockname()) ip, port = self.try(self.tp:getcontrol():getsockname())
self.server = self.try(socket.bind(ip, 0)) self.server = self.try(socket.bind(ip, 0))
ip, port = self.try(self.server:getsockname()) ip, port = self.try(self.server:getsockname())
self.try(self.server:settimeout(TIMEOUT)) self.try(self.server:settimeout(_M.TIMEOUT))
end end
local pl = math.mod(port, 256) local pl = math.mod(port, 256)
local ph = (port - pl)/256 local ph = (port - pl)/256
@ -199,7 +199,7 @@ end
local function tput(putt) local function tput(putt)
putt = override(putt) putt = override(putt)
socket.try(putt.host, "missing hostname") socket.try(putt.host, "missing hostname")
local f = open(putt.host, putt.port, putt.create) local f = _M.open(putt.host, putt.port, putt.create)
f:greet() f:greet()
f:login(putt.user, putt.password) f:login(putt.user, putt.password)
if putt.type then f:type(putt.type) end if putt.type then f:type(putt.type) end
@ -234,7 +234,7 @@ local function sput(u, body)
return tput(putt) return tput(putt)
end end
put = socket.protect(function(putt, body) _M.put = socket.protect(function(putt, body)
if base.type(putt) == "string" then return sput(putt, body) if base.type(putt) == "string" then return sput(putt, body)
else return tput(putt) end else return tput(putt) end
end) end)
@ -242,7 +242,7 @@ end)
local function tget(gett) local function tget(gett)
gett = override(gett) gett = override(gett)
socket.try(gett.host, "missing hostname") socket.try(gett.host, "missing hostname")
local f = open(gett.host, gett.port, gett.create) local f = _M.open(gett.host, gett.port, gett.create)
f:greet() f:greet()
f:login(gett.user, gett.password) f:login(gett.user, gett.password)
if gett.type then f:type(gett.type) end if gett.type then f:type(gett.type) end
@ -260,7 +260,7 @@ local function sget(u)
return table.concat(t) return table.concat(t)
end end
command = socket.protect(function(cmdt) _M.command = socket.protect(function(cmdt)
cmdt = override(cmdt) cmdt = override(cmdt)
socket.try(cmdt.host, "missing hostname") socket.try(cmdt.host, "missing hostname")
socket.try(cmdt.command, "missing command") socket.try(cmdt.command, "missing command")
@ -273,8 +273,9 @@ command = socket.protect(function(cmdt)
return f:close() return f:close()
end) end)
get = socket.protect(function(gett) _M.get = socket.protect(function(gett)
if base.type(gett) == "string" then return sget(gett) if base.type(gett) == "string" then return sget(gett)
else return tget(gett) end else return tget(gett) end
end) end)
return _M

View File

@ -3,9 +3,11 @@
-- LuaSocket toolkit. -- LuaSocket toolkit.
-- Author: Diego Nehab -- Author: Diego Nehab
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module("socket.headers") local socket = require("socket")
socket.headers = {}
local _M = socket.headers
canonic = { _M.canonic = {
["accept"] = "Accept", ["accept"] = "Accept",
["accept-charset"] = "Accept-Charset", ["accept-charset"] = "Accept-Charset",
["accept-encoding"] = "Accept-Encoding", ["accept-encoding"] = "Accept-Encoding",
@ -98,3 +100,5 @@ canonic = {
["www-authenticate"] = "WWW-Authenticate", ["www-authenticate"] = "WWW-Authenticate",
["x-mailer"] = "X-Mailer", ["x-mailer"] = "X-Mailer",
} }
return _M

View File

@ -15,7 +15,8 @@ local string = require("string")
local headers = require("socket.headers") local headers = require("socket.headers")
local base = _G local base = _G
local table = require("table") local table = require("table")
module("socket.http") socket.http = {}
local _M = socket.http
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Program constants -- Program constants
@ -23,9 +24,9 @@ module("socket.http")
-- connection timeout in seconds -- connection timeout in seconds
TIMEOUT = 60 TIMEOUT = 60
-- default port for document retrieval -- default port for document retrieval
PORT = 80 _M.PORT = 80
-- user agent field sent in request -- user agent field sent in request
USERAGENT = socket._VERSION _M.USERAGENT = socket._VERSION
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Reads MIME headers from a connection, unfolding where needed -- Reads MIME headers from a connection, unfolding where needed
@ -105,15 +106,15 @@ end
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local metat = { __index = {} } local metat = { __index = {} }
function open(host, port, create) function _M.open(host, port, create)
-- create socket with user connect function, or with default -- create socket with user connect function, or with default
local c = socket.try((create or socket.tcp)()) local c = socket.try((create or socket.tcp)())
local h = base.setmetatable({ c = c }, metat) local h = base.setmetatable({ c = c }, metat)
-- create finalized try -- create finalized try
h.try = socket.newtry(function() h:close() end) h.try = socket.newtry(function() h:close() end)
-- set timeout before connecting -- set timeout before connecting
h.try(c:settimeout(TIMEOUT)) h.try(c:settimeout(_M.TIMEOUT))
h.try(c:connect(host, port or PORT)) h.try(c:connect(host, port or _M.PORT))
-- here everything worked -- here everything worked
return h return h
end end
@ -209,7 +210,7 @@ end
local function adjustheaders(reqt) local function adjustheaders(reqt)
-- default headers -- default headers
local lower = { local lower = {
["user-agent"] = USERAGENT, ["user-agent"] = _M.USERAGENT,
["host"] = reqt.host, ["host"] = reqt.host,
["connection"] = "close, TE", ["connection"] = "close, TE",
["te"] = "trailers" ["te"] = "trailers"
@ -229,7 +230,7 @@ end
-- default url parts -- default url parts
local default = { local default = {
host = "", host = "",
port = PORT, port = _M.PORT,
path ="/", path ="/",
scheme = "http" scheme = "http"
} }
@ -270,7 +271,7 @@ end
-- forward declarations -- forward declarations
local trequest, tredirect local trequest, tredirect
function tredirect(reqt, location) --[[local]] function tredirect(reqt, location)
local result, code, headers, status = trequest { local result, code, headers, status = trequest {
-- the RFC says the redirect URL has to be absolute, but some -- the RFC says the redirect URL has to be absolute, but some
-- servers do not respect that -- servers do not respect that
@ -288,11 +289,11 @@ function tredirect(reqt, location)
return result, code, headers, status return result, code, headers, status
end end
function trequest(reqt) --[[local]] function trequest(reqt)
-- we loop until we get what we want, or -- we loop until we get what we want, or
-- until we are sure there is no way to get it -- until we are sure there is no way to get it
local nreqt = adjustrequest(reqt) local nreqt = adjustrequest(reqt)
local h = open(nreqt.host, nreqt.port, nreqt.create) local h = _M.open(nreqt.host, nreqt.port, nreqt.create)
-- send request line and headers -- send request line and headers
h:sendrequestline(nreqt.method, nreqt.uri) h:sendrequestline(nreqt.method, nreqt.uri)
h:sendheaders(nreqt.headers) h:sendheaders(nreqt.headers)
@ -345,7 +346,9 @@ local function srequest(u, b)
return table.concat(t), code, headers, status return table.concat(t), code, headers, status
end end
request = socket.protect(function(reqt, body) _M.request = socket.protect(function(reqt, body)
if base.type(reqt) == "string" then return srequest(reqt, body) if base.type(reqt) == "string" then return srequest(reqt, body)
else return trequest(reqt) end else return trequest(reqt) end
end) end)
return _M

View File

@ -10,16 +10,19 @@
local string = require("string") local string = require("string")
local table = require("table") local table = require("table")
local base = _G local base = _G
module("ltn12") ltn12 = {}
local _M = ltn12
filter = {} local filter,source,sink,pump = {},{},{},{}
source = {}
sink = {} _M.filter = filter
pump = {} _M.source = source
_M.sink = sink
_M.pump = pump
-- 2048 seems to be better in windows... -- 2048 seems to be better in windows...
BLOCKSIZE = 2048 _M.BLOCKSIZE = 2048
_VERSION = "LTN12 1.0.2" _M._VERSION = "LTN12 1.0.2"
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Filter stuff -- Filter stuff
@ -38,7 +41,7 @@ end
-- (thanks to Wim Couwenberg) -- (thanks to Wim Couwenberg)
function filter.chain(...) function filter.chain(...)
local arg = {...} local arg = {...}
local n = #arg local n = select('#',...)
local top, index = 1, 1 local top, index = 1, 1
local retry = "" local retry = ""
return function(chunk) return function(chunk)
@ -89,7 +92,7 @@ end
function source.file(handle, io_err) function source.file(handle, io_err)
if handle then if handle then
return function() return function()
local chunk = handle:read(BLOCKSIZE) local chunk = handle:read(_M.BLOCKSIZE)
if not chunk then handle:close() end if not chunk then handle:close() end
return chunk return chunk
end end
@ -112,8 +115,8 @@ function source.string(s)
if s then if s then
local i = 1 local i = 1
return function() return function()
local chunk = string.sub(s, i, i+BLOCKSIZE-1) local chunk = string.sub(s, i, i+_M.BLOCKSIZE-1)
i = i + BLOCKSIZE i = i + _M.BLOCKSIZE
if chunk ~= "" then return chunk if chunk ~= "" then return chunk
else return nil end else return nil end
end end
@ -291,3 +294,4 @@ function pump.all(src, snk, step)
end end
end end
return _M

View File

@ -18,9 +18,6 @@
#include "lua.h" #include "lua.h"
#include "lauxlib.h" #include "lauxlib.h"
#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501)
#include "compat-5.1.h"
#endif
/*=========================================================================*\ /*=========================================================================*\
* LuaSocket includes * LuaSocket includes
@ -81,6 +78,34 @@ static int global_unload(lua_State *L) {
return 0; return 0;
} }
#if LUA_VERSION_NUM > 501
int luaL_typerror (lua_State *L, int narg, const char *tname) {
const char *msg = lua_pushfstring(L, "%s expected, got %s",
tname, luaL_typename(L, narg));
return luaL_argerror(L, narg, msg);
}
#if ! defined(LUA_COMPAT_MODULE)
void luaL_openlib(lua_State *L, const char *name, const luaL_Reg *funcs, int idx) {
if (name != NULL) {
#ifdef LUASOCKET_USE_GLOBAL
lua_getglobal(L,name);
if (lua_isnil(L,-1)) {
lua_newtable(L);
lua_setglobal(L,name);
lua_getglobal(L,name);
}
#else
lua_newtable(L);
#endif
}
luaL_setfuncs(L,funcs,0);
}
#endif
#endif
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Setup basic stuff. * Setup basic stuff.
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/

View File

@ -22,10 +22,6 @@
#define LUASOCKET_API extern #define LUASOCKET_API extern
#endif #endif
#if LUA_VERSION_NUM > 501 & !( defined LUA_COMPAT_MODULE)
# error Lua 5.2 requires LUA_COMPAT_MODULE defined for luaL_openlib
#endif
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Initializes the library. * Initializes the library.
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/

View File

@ -86,3 +86,5 @@ function Public.parse_message(message_s)
message.headers = Public.parse_headers(message.headers) message.headers = Public.parse_headers(message.headers)
return message return message
end end
return mbox

View File

@ -81,7 +81,16 @@ static UC b64unbase[256];
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
MIME_API int luaopen_mime_core(lua_State *L) MIME_API int luaopen_mime_core(lua_State *L)
{ {
#if LUA_VERSION_NUM > 501
lua_newtable(L);
#ifdef LUASOCKET_USE_GLOBAL
lua_setglobal(L,"mime");
lua_getglobal(L,"mime");
#endif
luaL_setfuncs(L,func,0);
#else
luaL_openlib(L, "mime", func, 0); luaL_openlib(L, "mime", func, 0);
#endif
/* make version string available to scripts */ /* make version string available to scripts */
lua_pushstring(L, "_VERSION"); lua_pushstring(L, "_VERSION");
lua_pushstring(L, MIME_VERSION); lua_pushstring(L, MIME_VERSION);

View File

@ -10,13 +10,16 @@
local base = _G local base = _G
local ltn12 = require("ltn12") local ltn12 = require("ltn12")
local mime = require("mime.core") local mime = require("mime.core")
local io = require("io")
local string = require("string") local string = require("string")
module("mime") local _M = mime
-- encode, decode and wrap algorithm tables -- encode, decode and wrap algorithm tables
encodet = {} local encodet, decodet, wrapt = {},{},{}
decodet = {}
wrapt = {} _M.encodet = encodet
_M.decodet = decodet
_M.wrapt = wrapt
-- creates a function that chooses a filter by name from a given table -- creates a function that chooses a filter by name from a given table
local function choose(table) local function choose(table)
@ -33,21 +36,21 @@ end
-- define the encoding filters -- define the encoding filters
encodet['base64'] = function() encodet['base64'] = function()
return ltn12.filter.cycle(b64, "") return ltn12.filter.cycle(_M.b64, "")
end end
encodet['quoted-printable'] = function(mode) encodet['quoted-printable'] = function(mode)
return ltn12.filter.cycle(qp, "", return ltn12.filter.cycle(_M.qp, "",
(mode == "binary") and "=0D=0A" or "\r\n") (mode == "binary") and "=0D=0A" or "\r\n")
end end
-- define the decoding filters -- define the decoding filters
decodet['base64'] = function() decodet['base64'] = function()
return ltn12.filter.cycle(unb64, "") return ltn12.filter.cycle(_M.unb64, "")
end end
decodet['quoted-printable'] = function() decodet['quoted-printable'] = function()
return ltn12.filter.cycle(unqp, "") return ltn12.filter.cycle(_M.unqp, "")
end end
local function format(chunk) local function format(chunk)
@ -60,26 +63,28 @@ end
-- define the line-wrap filters -- define the line-wrap filters
wrapt['text'] = function(length) wrapt['text'] = function(length)
length = length or 76 length = length or 76
return ltn12.filter.cycle(wrp, length, length) return ltn12.filter.cycle(_M.wrp, length, length)
end end
wrapt['base64'] = wrapt['text'] wrapt['base64'] = wrapt['text']
wrapt['default'] = wrapt['text'] wrapt['default'] = wrapt['text']
wrapt['quoted-printable'] = function() wrapt['quoted-printable'] = function()
return ltn12.filter.cycle(qpwrp, 76, 76) return ltn12.filter.cycle(_M.qpwrp, 76, 76)
end end
-- function that choose the encoding, decoding or wrap algorithm -- function that choose the encoding, decoding or wrap algorithm
encode = choose(encodet) _M.encode = choose(encodet)
decode = choose(decodet) _M.decode = choose(decodet)
wrap = choose(wrapt) _M.wrap = choose(wrapt)
-- define the end-of-line normalization filter -- define the end-of-line normalization filter
function normalize(marker) function _M.normalize(marker)
return ltn12.filter.cycle(eol, 0, marker) return ltn12.filter.cycle(_M.eol, 0, marker)
end end
-- high level stuffing filter -- high level stuffing filter
function stuff() function _M.stuff()
return ltn12.filter.cycle(dot, 2) return ltn12.filter.cycle(_M.dot, 2)
end end
return _M

View File

@ -17,22 +17,24 @@ local tp = require("socket.tp")
local ltn12 = require("ltn12") local ltn12 = require("ltn12")
local headers = require("socket.headers") local headers = require("socket.headers")
local mime = require("mime") local mime = require("mime")
module("socket.smtp")
socket.smtp = {}
local _M = socket.smtp
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Program constants -- Program constants
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- timeout for connection -- timeout for connection
TIMEOUT = 60 _M.TIMEOUT = 60
-- default server used to send e-mails -- default server used to send e-mails
SERVER = "localhost" _M.SERVER = "localhost"
-- default port -- default port
PORT = 25 _M.PORT = 25
-- domain used in HELO command and default sendmail -- domain used in HELO command and default sendmail
-- If we are under a CGI, try to get from environment -- If we are under a CGI, try to get from environment
DOMAIN = os.getenv("SERVER_NAME") or "localhost" _M.DOMAIN = os.getenv("SERVER_NAME") or "localhost"
-- default time zone (means we don't know) -- default time zone (means we don't know)
ZONE = "-0000" _M.ZONE = "-0000"
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- Low level SMTP API -- Low level SMTP API
@ -41,7 +43,7 @@ local metat = { __index = {} }
function metat.__index:greet(domain) function metat.__index:greet(domain)
self.try(self.tp:check("2..")) self.try(self.tp:check("2.."))
self.try(self.tp:command("EHLO", domain or DOMAIN)) self.try(self.tp:command("EHLO", domain or _M.DOMAIN))
return socket.skip(1, self.try(self.tp:check("2.."))) return socket.skip(1, self.try(self.tp:check("2..")))
end end
@ -111,9 +113,9 @@ function metat.__index:send(mailt)
self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step) self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step)
end end
function open(server, port, create) function _M.open(server, port, create)
local tp = socket.try(tp.connect(server or SERVER, port or PORT, local tp = socket.try(tp.connect(server or _M.SERVER, port or _M.PORT,
TIMEOUT, create)) _M.TIMEOUT, create))
local s = base.setmetatable({tp = tp}, metat) local s = base.setmetatable({tp = tp}, metat)
-- make sure tp is closed if we get an exception -- make sure tp is closed if we get an exception
s.try = socket.newtry(function() s.try = socket.newtry(function()
@ -221,14 +223,14 @@ end
local function adjust_headers(mesgt) local function adjust_headers(mesgt)
local lower = lower_headers(mesgt.headers) local lower = lower_headers(mesgt.headers)
lower["date"] = lower["date"] or lower["date"] = lower["date"] or
os.date("!%a, %d %b %Y %H:%M:%S ") .. (mesgt.zone or ZONE) os.date("!%a, %d %b %Y %H:%M:%S ") .. (mesgt.zone or _M.ZONE)
lower["x-mailer"] = lower["x-mailer"] or socket._VERSION lower["x-mailer"] = lower["x-mailer"] or socket._VERSION
-- this can't be overriden -- this can't be overriden
lower["mime-version"] = "1.0" lower["mime-version"] = "1.0"
return lower return lower
end end
function message(mesgt) function _M.message(mesgt)
mesgt.headers = adjust_headers(mesgt) mesgt.headers = adjust_headers(mesgt)
-- create and return message source -- create and return message source
local co = coroutine.create(function() send_message(mesgt) end) local co = coroutine.create(function() send_message(mesgt) end)
@ -242,11 +244,13 @@ end
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- High level SMTP API -- High level SMTP API
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
send = socket.protect(function(mailt) _M.send = socket.protect(function(mailt)
local s = open(mailt.server, mailt.port, mailt.create) local s = _M.open(mailt.server, mailt.port, mailt.create)
local ext = s:greet(mailt.domain) local ext = s:greet(mailt.domain)
s:auth(mailt.user, mailt.password, ext) s:auth(mailt.user, mailt.password, ext)
s:send(mailt) s:send(mailt)
s:quit() s:quit()
return s:close() return s:close()
end) end)
return _M

View File

@ -10,20 +10,21 @@ local base = _G
local string = require("string") local string = require("string")
local math = require("math") local math = require("math")
local socket = require("socket.core") local socket = require("socket.core")
module("socket")
local _M = socket
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Exported auxiliar functions -- Exported auxiliar functions
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
function connect4(address, port, laddress, lport) function _M.connect4(address, port, laddress, lport)
return socket.connect(address, port, laddress, lport, "inet") return socket.connect(address, port, laddress, lport, "inet")
end end
function connect6(address, port, laddress, lport) function _M.connect6(address, port, laddress, lport)
return socket.connect(address, port, laddress, lport, "inet6") return socket.connect(address, port, laddress, lport, "inet6")
end end
function bind(host, port, backlog) function _M.bind(host, port, backlog)
if host == "*" then host = "0.0.0.0" end if host == "*" then host = "0.0.0.0" end
local addrinfo, err = socket.dns.getaddrinfo(host); local addrinfo, err = socket.dns.getaddrinfo(host);
if not addrinfo then return nil, err end if not addrinfo then return nil, err end
@ -52,9 +53,9 @@ function bind(host, port, backlog)
return nil, err return nil, err
end end
try = newtry() _M.try = _M.newtry()
function choose(table) function _M.choose(table)
return function(name, opt1, opt2) return function(name, opt1, opt2)
if base.type(name) ~= "string" then if base.type(name) ~= "string" then
name, opt1, opt2 = "default", name, opt1 name, opt1, opt2 = "default", name, opt1
@ -69,10 +70,11 @@ end
-- Socket sources and sinks, conforming to LTN12 -- Socket sources and sinks, conforming to LTN12
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- create namespaces inside LuaSocket namespace -- create namespaces inside LuaSocket namespace
sourcet = {} local sourcet, sinkt = {}, {}
sinkt = {} _M.sourcet = sourcet
_M.sinkt = sinkt
BLOCKSIZE = 2048 _M.BLOCKSIZE = 2048
sinkt["close-when-done"] = function(sock) sinkt["close-when-done"] = function(sock)
return base.setmetatable({ return base.setmetatable({
@ -102,7 +104,7 @@ end
sinkt["default"] = sinkt["keep-open"] sinkt["default"] = sinkt["keep-open"]
sink = choose(sinkt) _M.sink = _M.choose(sinkt)
sourcet["by-length"] = function(sock, length) sourcet["by-length"] = function(sock, length)
return base.setmetatable({ return base.setmetatable({
@ -142,5 +144,6 @@ end
sourcet["default"] = sourcet["until-closed"] sourcet["default"] = sourcet["until-closed"]
source = choose(sourcet) _M.source = _M.choose(sourcet)
return _M

View File

@ -11,12 +11,14 @@ local base = _G
local string = require("string") local string = require("string")
local socket = require("socket") local socket = require("socket")
local ltn12 = require("ltn12") local ltn12 = require("ltn12")
module("socket.tp")
socket.tp = {}
local _M = socket.tp
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Program constants -- Program constants
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
TIMEOUT = 60 _M.TIMEOUT = 60
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Implementation -- Implementation
@ -109,10 +111,10 @@ function metat.__index:close()
end end
-- connect with server and return c object -- connect with server and return c object
function connect(host, port, timeout, create) function _M.connect(host, port, timeout, create)
local c, e = (create or socket.tcp)() local c, e = (create or socket.tcp)()
if not c then return nil, e end if not c then return nil, e end
c:settimeout(timeout or TIMEOUT) c:settimeout(timeout or _M.TIMEOUT)
local r, e = c:connect(host, port) local r, e = c:connect(host, port)
if not r then if not r then
c:close() c:close()
@ -121,3 +123,4 @@ function connect(host, port, timeout, create)
return base.setmetatable({c = c}, metat) return base.setmetatable({c = c}, metat)
end end
return _M

View File

@ -10,12 +10,15 @@
local string = require("string") local string = require("string")
local base = _G local base = _G
local table = require("table") local table = require("table")
module("socket.url") local socket = require("socket")
socket.url = {}
local _M = socket.url
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Module version -- Module version
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
_VERSION = "URL 1.0.2" _M._VERSION = "URL 1.0.2"
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Encodes a string into its escaped hexadecimal representation -- Encodes a string into its escaped hexadecimal representation
@ -24,7 +27,7 @@ _VERSION = "URL 1.0.2"
-- Returns -- Returns
-- escaped representation of string binary -- escaped representation of string binary
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
function escape(s) function _M.escape(s)
return (string.gsub(s, "([^A-Za-z0-9_])", function(c) return (string.gsub(s, "([^A-Za-z0-9_])", function(c)
return string.format("%%%02x", string.byte(c)) return string.format("%%%02x", string.byte(c))
end)) end))
@ -67,7 +70,7 @@ end
-- Returns -- Returns
-- escaped representation of string binary -- escaped representation of string binary
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
function unescape(s) function _M.unescape(s)
return (string.gsub(s, "%%(%x%x)", function(hex) return (string.gsub(s, "%%(%x%x)", function(hex)
return string.char(base.tonumber(hex, 16)) return string.char(base.tonumber(hex, 16))
end)) end))
@ -120,7 +123,7 @@ end
-- Obs: -- Obs:
-- the leading '/' in {/<path>} is considered part of <path> -- the leading '/' in {/<path>} is considered part of <path>
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
function parse(url, default) function _M.parse(url, default)
-- initialize default parameters -- initialize default parameters
local parsed = {} local parsed = {}
for i,v in base.pairs(default or parsed) do parsed[i] = v end for i,v in base.pairs(default or parsed) do parsed[i] = v end
@ -179,9 +182,9 @@ end
-- Returns -- Returns
-- a stringing with the corresponding URL -- a stringing with the corresponding URL
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
function build(parsed) function _M.build(parsed)
local ppath = parse_path(parsed.path or "") local ppath = _M.parse_path(parsed.path or "")
local url = build_path(ppath) local url = _M.build_path(ppath)
if parsed.params then url = url .. ";" .. parsed.params end if parsed.params then url = url .. ";" .. parsed.params end
if parsed.query then url = url .. "?" .. parsed.query end if parsed.query then url = url .. "?" .. parsed.query end
local authority = parsed.authority local authority = parsed.authority
@ -215,14 +218,14 @@ end
-- Returns -- Returns
-- corresponding absolute url -- corresponding absolute url
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
function absolute(base_url, relative_url) function _M.absolute(base_url, relative_url)
if base.type(base_url) == "table" then if base.type(base_url) == "table" then
base_parsed = base_url base_parsed = base_url
base_url = build(base_parsed) base_url = _M.build(base_parsed)
else else
base_parsed = parse(base_url) base_parsed = _M.parse(base_url)
end end
local relative_parsed = parse(relative_url) local relative_parsed = _M.parse(relative_url)
if not base_parsed then return relative_url if not base_parsed then return relative_url
elseif not relative_parsed then return base_url elseif not relative_parsed then return base_url
elseif relative_parsed.scheme then return relative_url elseif relative_parsed.scheme then return relative_url
@ -243,7 +246,7 @@ function absolute(base_url, relative_url)
relative_parsed.path) relative_parsed.path)
end end
end end
return build(relative_parsed) return _M.build(relative_parsed)
end end
end end
@ -254,13 +257,13 @@ end
-- Returns -- Returns
-- segment: a table with one entry per segment -- segment: a table with one entry per segment
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
function parse_path(path) function _M.parse_path(path)
local parsed = {} local parsed = {}
path = path or "" path = path or ""
--path = string.gsub(path, "%s", "") --path = string.gsub(path, "%s", "")
string.gsub(path, "([^/]+)", function (s) table.insert(parsed, s) end) string.gsub(path, "([^/]+)", function (s) table.insert(parsed, s) end)
for i = 1, #parsed do for i = 1, #parsed do
parsed[i] = unescape(parsed[i]) parsed[i] = _M.unescape(parsed[i])
end end
if string.sub(path, 1, 1) == "/" then parsed.is_absolute = 1 end if string.sub(path, 1, 1) == "/" then parsed.is_absolute = 1 end
if string.sub(path, -1, -1) == "/" then parsed.is_directory = 1 end if string.sub(path, -1, -1) == "/" then parsed.is_directory = 1 end
@ -275,7 +278,7 @@ end
-- Returns -- Returns
-- path: corresponding path stringing -- path: corresponding path stringing
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
function build_path(parsed, unsafe) function _M.build_path(parsed, unsafe)
local path = "" local path = ""
local n = #parsed local n = #parsed
if unsafe then if unsafe then
@ -300,3 +303,5 @@ function build_path(parsed, unsafe)
if parsed.is_absolute then path = "/" .. path end if parsed.is_absolute then path = "/" .. path end
return path return path
end end
return _M

View File

@ -1,3 +1,3 @@
require"socket" local socket = require"socket"
require"mime" local mime = require"mime"
print("Hello from " .. socket._VERSION .. " and " .. mime._VERSION .. "!") print("Hello from " .. socket._VERSION .. " and " .. mime._VERSION .. "!")