Committing with require.

This commit is contained in:
Diego Nehab 2004-05-28 06:16:43 +00:00
parent bf738a0336
commit 694edcc3c1
13 changed files with 153 additions and 80 deletions

View File

@ -1,3 +1,5 @@
require("ltn12")
require("mime")
local source = ltn12.source.file(io.stdin) local source = ltn12.source.file(io.stdin)
local sink = ltn12.sink.file(io.stdout) local sink = ltn12.sink.file(io.stdout)
local convert local convert

View File

@ -8,12 +8,11 @@ function get_status(sock, valid)
local line, err = sock:receive() local line, err = sock:receive()
local code, par local code, par
if not line then sock:close() return err end if not line then sock:close() return err end
_, _, code = string.find(line, "^(%d%d%d)") code = socket.skip(2, string.find(line, "^(%d%d%d)"))
code = tonumber(code) code = tonumber(code)
if code ~= valid then return code end if code ~= valid then return code end
if code == 150 then if code == 150 then
_,_,_, par = string.find(line, "^(%d%d%d) (%d*)") par = tonumber(socket.skip(2, string.find(line, "^%d%d%d (%d*)"))
par = tonumber(par)
end end
return nil, par return nil, par
end end

View File

@ -8,7 +8,7 @@ local server = arg[3] or "http://freedb.freedb.org/~cddb/cddb.cgi"
function parse(body) function parse(body)
local lines = string.gfind(body, "(.-)\r\n") local lines = string.gfind(body, "(.-)\r\n")
local status = lines() local status = lines()
local _, _, code, message = string.find(status, "(%d%d%d) (.*)") local code, message = socket.skip(2, string.find(status, "(%d%d%d) (.*)"))
if tonumber(code) ~= 210 then if tonumber(code) ~= 210 then
return nil, code, message return nil, code, message
end end
@ -16,7 +16,7 @@ function parse(body)
for l in lines do for l in lines do
local c = string.sub(l, 1, 1) local c = string.sub(l, 1, 1)
if c ~= '#' and c ~= '.' then if c ~= '#' and c ~= '.' then
local _, _, key, value = string.find(l, "(.-)=(.*)") local key, value = socket.skip(2, string.find(l, "(.-)=(.*)"))
value = string.gsub(value, "\\n", "\n") value = string.gsub(value, "\\n", "\n")
value = string.gsub(value, "\\\\", "\\") value = string.gsub(value, "\\\\", "\\")
value = string.gsub(value, "\\t", "\t") value = string.gsub(value, "\\t", "\t")

View File

@ -10,6 +10,11 @@ if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end
-- get LuaSocket namespace -- get LuaSocket namespace
local socket = _G[LUASOCKET_LIBNAME] local socket = _G[LUASOCKET_LIBNAME]
if not socket then error('module requires LuaSocket') end if not socket then error('module requires LuaSocket') end
-- require other modules
require("ltn12")
require("url")
-- create namespace inside LuaSocket namespace -- create namespace inside LuaSocket namespace
socket.ftp = socket.ftp or {} socket.ftp = socket.ftp or {}
-- make all module globals fall into namespace -- make all module globals fall into namespace
@ -25,6 +30,7 @@ TIMEOUT = 60
PORT = 21 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"
EMAIL = "anonymous@anonymous.org" EMAIL = "anonymous@anonymous.org"
-- block size used in transfers -- block size used in transfers
BLOCKSIZE = 2048 BLOCKSIZE = 2048
@ -48,21 +54,20 @@ local function pasv(pasvt)
end end
function metat.__index:login(user, password) function metat.__index:login(user, password)
socket.try(self.tp:command("USER", user)) socket.try(self.tp:command("user", user or USER))
local code, reply = socket.try(self.tp:check{"2..", 331}) local code, reply = socket.try(self.tp:check{"2..", 331})
if code == 331 then if code == 331 then
socket.try(password, reply) socket.try(self.tp:command("pass", password or EMAIL))
socket.try(self.tp:command("PASS", password))
socket.try(self.tp:check("2..")) socket.try(self.tp:check("2.."))
end end
return 1 return 1
end end
function metat.__index:pasv() function metat.__index:pasv()
socket.try(self.tp:command("PASV")) socket.try(self.tp:command("pasv"))
local code, reply = socket.try(self.tp:check("2..")) local code, reply = socket.try(self.tp:check("2.."))
local _, _, a, b, c, d, p1, p2 = local pattern = "(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
string.find(reply, "(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)") local a, b, c, d, p1, p2 = socket.skip(2, string.find(reply, pattern))
socket.try(a and b and c and d and p1 and p2, reply) socket.try(a and b and c and d and p1 and p2, reply)
self.pasvt = { self.pasvt = {
ip = string.format("%d.%d.%d.%d", a, b, c, d), ip = string.format("%d.%d.%d.%d", a, b, c, d),
@ -97,7 +102,7 @@ function metat.__index:send(sendt)
local data local data
socket.try(self.pasvt or self.portt, "need port or pasv first") socket.try(self.pasvt or self.portt, "need port or pasv first")
if self.pasvt then data = socket.try(pasv(self.pasvt)) end if self.pasvt then data = socket.try(pasv(self.pasvt)) end
socket.try(self.tp:command(sendt.command, sendt.argument)) socket.try(self.tp:command(sendt.command or "stor", sendt.argument))
local code, reply = socket.try(self.tp:check{"2..", "1.."}) local code, reply = socket.try(self.tp:check{"2..", "1.."})
if self.portt then data = socket.try(port(self.portt)) end if self.portt then data = socket.try(port(self.portt)) end
local step = sendt.step or ltn12.pump.step local step = sendt.step or ltn12.pump.step
@ -124,7 +129,7 @@ function metat.__index:receive(recvt)
local data local data
socket.try(self.pasvt or self.portt, "need port or pasv first") socket.try(self.pasvt or self.portt, "need port or pasv first")
if self.pasvt then data = socket.try(pasv(self.pasvt)) end if self.pasvt then data = socket.try(pasv(self.pasvt)) end
socket.try(self.tp:command(recvt.command, recvt.argument)) socket.try(self.tp:command(recvt.command or "retr", recvt.argument))
local code = socket.try(self.tp:check{"1..", "2.."}) local code = socket.try(self.tp:check{"1..", "2.."})
if self.portt then data = socket.try(port(self.portt)) end if self.portt then data = socket.try(port(self.portt)) end
local source = socket.source("until-closed", data) local source = socket.source("until-closed", data)
@ -140,13 +145,13 @@ function metat.__index:receive(recvt)
end end
function metat.__index:cwd(dir) function metat.__index:cwd(dir)
socket.try(self.tp:command("CWD", dir)) socket.try(self.tp:command("cwd", dir))
socket.try(self.tp:check(250)) socket.try(self.tp:check(250))
return 1 return 1
end end
function metat.__index:type(type) function metat.__index:type(type)
socket.try(self.tp:command("TYPE", type)) socket.try(self.tp:command("type", type))
socket.try(self.tp:check(200)) socket.try(self.tp:check(200))
return 1 return 1
end end
@ -158,7 +163,7 @@ function metat.__index:greet()
end end
function metat.__index:quit() function metat.__index:quit()
socket.try(self.tp:command("QUIT")) socket.try(self.tp:command("quit"))
socket.try(self.tp:check("2..")) socket.try(self.tp:check("2.."))
return 1 return 1
end end
@ -171,11 +176,69 @@ end
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- High level FTP API -- High level FTP API
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local function tput(putt)
function put(putt) local ftp = socket.ftp.open(putt.host, putt.port)
ftp:greet()
ftp:login(putt.user, putt.password)
if putt.type then ftp:type(putt.type) end
ftp:pasv()
ftp:send(putt)
ftp:quit()
return ftp:close()
end end
function get(gett) local default = {
path = "/",
scheme = "ftp"
}
local function parse(url)
local putt = socket.try(socket.url.parse(url, default))
socket.try(putt.scheme == "ftp", "invalid scheme '" .. putt.scheme .. "'")
socket.try(putt.host, "invalid host")
local pat = "^type=(.)$"
if putt.params then
putt.type = socket.skip(2, string.find(putt.params, pat))
socket.try(putt.type == "a" or putt.type == "i")
end
-- skip first backslash in path
putt.argument = string.sub(putt.path, 2)
return putt
end end
local function sput(url, body)
local putt = parse(url)
putt.source = ltn12.source.string(body)
return tput(putt)
end
put = socket.protect(function(putt, body)
if type(putt) == "string" then return sput(putt, body)
else return tput(putt) end
end)
local function tget(gett)
local ftp = socket.ftp.open(gett.host, gett.port)
ftp:greet()
ftp:login(gett.user, gett.password)
if gett.type then ftp:type(gett.type) end
ftp:pasv()
ftp:receive(gett)
ftp:quit()
return ftp:close()
end
local function sget(url, body)
local gett = parse(url)
local t = {}
gett.sink = ltn12.sink.table(t)
tget(gett)
return table.concat(t)
end
get = socket.protect(function(gett)
if type(gett) == "string" then return sget(gett, body)
else return tget(gett) end
end)
return ftp return ftp

View File

@ -10,6 +10,12 @@ if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end
-- get LuaSocket namespace -- get LuaSocket namespace
local socket = _G[LUASOCKET_LIBNAME] local socket = _G[LUASOCKET_LIBNAME]
if not socket then error('module requires LuaSocket') end if not socket then error('module requires LuaSocket') end
-- require other modules
require("ltn12")
require("mime")
require("url")
-- create namespace inside LuaSocket namespace -- create namespace inside LuaSocket namespace
socket.http = socket.http or {} socket.http = socket.http or {}
-- make all module globals fall into namespace -- make all module globals fall into namespace
@ -41,7 +47,7 @@ end
local function receive_headers(reqt, respt, tmp) local function receive_headers(reqt, respt, tmp)
local sock = tmp.sock local sock = tmp.sock
local line, name, value, _ local line, name, value
local headers = {} local headers = {}
-- store results -- store results
respt.headers = headers respt.headers = headers
@ -50,7 +56,7 @@ local function receive_headers(reqt, respt, tmp)
-- headers go until a blank line is found -- headers go until a blank line is found
while line ~= "" do while line ~= "" do
-- get field-name and value -- get field-name and value
_, _, name, value = string.find(line, "^(.-):%s*(.*)") name, value = socket.skip(2, string.find(line, "^(.-):%s*(.*)"))
socket.try(name and value, "malformed reponse headers") socket.try(name and value, "malformed reponse headers")
name = string.lower(name) name = string.lower(name)
-- get next line (value might be folded) -- get next line (value might be folded)

View File

@ -35,38 +35,6 @@
#include "udp.h" #include "udp.h"
#include "select.h" #include "select.h"
#include "smtp.h" #include "smtp.h"
#include "mime.h"
/*=========================================================================*\
* Declarations
\*=========================================================================*/
static int mod_open(lua_State *L, const luaL_reg *mod);
static int mod_open(lua_State *L, const luaL_reg *mod)
{
for (; mod->name; mod++) mod->func(L);
#ifdef LUASOCKET_COMPILED
#include "ltn12.lch"
#include "auxiliar.lch"
#include "url.lch"
#include "mime.lch"
#include "tp.lch"
#include "smtp.lch"
#include "http.lch"
#include "ftp.lch"
#else
lua_dofile(L, "ltn12.lua");
lua_dofile(L, "auxiliar.lua");
lua_dofile(L, "url.lua");
lua_dofile(L, "mime.lua");
lua_dofile(L, "tp.lua");
lua_dofile(L, "smtp.lua");
lua_dofile(L, "http.lua");
lua_dofile(L, "ftp.lua");
#endif
return 0;
}
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Modules * Modules
@ -80,7 +48,6 @@ static const luaL_reg mod[] = {
{"tcp", tcp_open}, {"tcp", tcp_open},
{"udp", udp_open}, {"udp", udp_open},
{"select", select_open}, {"select", select_open},
{"mime", mime_open},
{"smtp", smtp_open}, {"smtp", smtp_open},
{NULL, NULL} {NULL, NULL}
}; };
@ -90,11 +57,13 @@ static const luaL_reg mod[] = {
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
LUASOCKET_API int luaopen_socket(lua_State *L) LUASOCKET_API int luaopen_socket(lua_State *L)
{ {
int i;
if (!sock_open()) { if (!sock_open()) {
lua_pushnil(L); lua_pushnil(L);
lua_pushstring(L, "unable to initialize library"); lua_pushstring(L, "unable to initialize library");
return 2; return 2;
} }
mod_open(L, mod); for (i = 0; mod[i].name; i++)
mod[i].func(L);
return 1; return 1;
} }

View File

@ -74,15 +74,15 @@ static UC b64unbase[256];
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Initializes module * Initializes module
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
int mime_open(lua_State *L) int luaopen_mime(lua_State *L)
{ {
lua_pushstring(L, "mime"); lua_pushstring(L, MIME_LIBNAME);
lua_newtable(L); lua_setglobal(L, "MIME_LIBNAME");
luaL_openlib(L, NULL, func, 0); luaL_openlib(L, MIME_LIBNAME, func, 0);
lua_settable(L, LUA_GLOBALSINDEX);
/* initialize lookup tables */ /* initialize lookup tables */
qpsetup(qpclass, qpunbase); qpsetup(qpclass, qpunbase);
b64setup(b64unbase); b64setup(b64unbase);
lua_pop(L, 1);
return 0; return 0;
} }

View File

@ -12,6 +12,13 @@
\*=========================================================================*/ \*=========================================================================*/
#include <lua.h> #include <lua.h>
int mime_open(lua_State *L); int luaopen_mime(lua_State *L);
/*-------------------------------------------------------------------------*\
* Library's namespace
\*-------------------------------------------------------------------------*/
#ifndef MIME_LIBNAME
#define MIME_LIBNAME "mime"
#endif
#endif /* MIME_H */ #endif /* MIME_H */

View File

@ -1,6 +1,27 @@
if not ltn12 then error('Requires LTN12 module') end -----------------------------------------------------------------------------
-- create mime namespace -- MIME support for the Lua language.
mime = mime or {} -- Author: Diego Nehab
-- Conforming to RFCs 2045-2049
-- RCS ID: $Id$
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Load MIME from dynamic library
-- Comment these lines if you are loading static
-----------------------------------------------------------------------------
open, err1, err2 = loadlib("mime", "luaopen_mime")
if not open then error(err1) end
open()
if not MIME_LIBNAME then error("MIME init failed") end
-----------------------------------------------------------------------------
-- Namespace independence
-----------------------------------------------------------------------------
local mime = _G[MIME_LIBNAME]
if not mime then error('MIME init FAILED') end
require("ltn12")
-- make all module globals fall into mime namespace -- make all module globals fall into mime namespace
setmetatable(mime, { __index = _G }) setmetatable(mime, { __index = _G })
setfenv(1, mime) setfenv(1, mime)

View File

@ -1,8 +1,16 @@
-----------------------------------------------------------------------------
-- SMTP client support for the Lua language.
-- LuaSocket toolkit.
-- Author: Diego Nehab
-- Conforming to RFC 2821
-- RCS ID: $Id$
-----------------------------------------------------------------------------
-- make sure LuaSocket is loaded -- make sure LuaSocket is loaded
if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end
-- get LuaSocket namespace -- get LuaSocket namespace
local socket = _G[LUASOCKET_LIBNAME] local socket = _G[LUASOCKET_LIBNAME]
if not socket then error('module requires LuaSocket') end if not socket then error('module requires LuaSocket') end
-- create smtp namespace inside LuaSocket namespace -- create smtp namespace inside LuaSocket namespace
local smtp = socket.smtp or {} local smtp = socket.smtp or {}
socket.smtp = smtp socket.smtp = smtp
@ -20,11 +28,6 @@ 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" ZONE = "-0000"
local function shift(a, b, c)
return b, c
end
-- high level stuffing filter -- high level stuffing filter
function stuff() function stuff()
return ltn12.filter.cycle(dot, 2) return ltn12.filter.cycle(dot, 2)
@ -82,6 +85,7 @@ function metat.__index:send(mailt)
end end
function open(server, port) function open(server, port)
print(server or SERVER, port or PORT)
local tp, error = socket.tp.connect(server or SERVER, port or PORT) local tp, error = socket.tp.connect(server or SERVER, port or PORT)
if not tp then return nil, error end if not tp then return nil, error end
return setmetatable({tp = tp}, metat) return setmetatable({tp = tp}, metat)
@ -180,17 +184,15 @@ function message(mesgt)
adjust_headers(mesgt) 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)
return function() return shift(coroutine.resume(co)) end return function() return socket.skip(1, coroutine.resume(co)) end
end end
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- High level SMTP API -- High level SMTP API
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
send = socket.protect(function(mailt) send = socket.protect(function(mailt)
local server = mailt.server or SERVER local smtp = socket.try(open(mailt.server, mailt.port))
local port = mailt.port or PORT smtp:greet(mailt.domain)
local smtp = socket.try(open(server, port))
smtp:greet(mailt.domain or DOMAIN)
smtp:send(mailt) smtp:send(mailt)
smtp:quit() smtp:quit()
return smtp:close() return smtp:close()

View File

@ -20,20 +20,20 @@ TIMEOUT = 60
-- gets server reply (works for SMTP and FTP) -- gets server reply (works for SMTP and FTP)
local function get_reply(control) local function get_reply(control)
local code, current, separator, _ local code, current, sep
local line, err = control:receive() local line, err = control:receive()
local reply = line local reply = line
if err then return nil, err end if err then return nil, err end
_, _, code, separator = string.find(line, "^(%d%d%d)(.?)") code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
if not code then return nil, "invalid server reply" end if not code then return nil, "invalid server reply" end
if separator == "-" then -- reply is multiline if sep == "-" then -- reply is multiline
repeat repeat
line, err = control:receive() line, err = control:receive()
if err then return nil, err end if err then return nil, err end
_,_, current, separator = string.find(line, "^(%d%d%d)(.?)") current, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
reply = reply .. "\n" .. line reply = reply .. "\n" .. line
-- reply ends with same code -- reply ends with same code
until code == current and separator == " " until code == current and sep == " "
end end
return code, reply return code, reply
end end

View File

@ -125,7 +125,7 @@ function parse(url, default)
-- initialize default parameters -- initialize default parameters
local parsed = default or {} local parsed = default or {}
-- empty url is parsed to nil -- empty url is parsed to nil
if not url or url == "" then return nil end if not url or url == "" then return nil, "invalid url" end
-- remove whitespace -- remove whitespace
-- url = string.gsub(url, "%s", "") -- url = string.gsub(url, "%s", "")
-- get fragment -- get fragment

View File

@ -3,6 +3,10 @@
-- needs ScriptAlias from /home/c/diego/tec/luasocket/test/cgi -- needs ScriptAlias from /home/c/diego/tec/luasocket/test/cgi
-- to "/luasocket-test-cgi" and "/luasocket-test-cgi/" -- to "/luasocket-test-cgi" and "/luasocket-test-cgi/"
-- needs "AllowOverride AuthConfig" on /home/c/diego/tec/luasocket/test/auth -- needs "AllowOverride AuthConfig" on /home/c/diego/tec/luasocket/test/auth
require("luasocket")
require("http")
dofile("testsupport.lua") dofile("testsupport.lua")
local host, proxy, request, response, index_file local host, proxy, request, response, index_file