Almost ready for beta3

This commit is contained in:
Diego Nehab 2004-11-27 07:58:04 +00:00
parent eb0fc857dd
commit 7c97e8e40a
26 changed files with 310 additions and 190 deletions

9
TODO
View File

@ -1,14 +1,12 @@
use wim's filter.chain or something better
make sure standard libraries are "required" by modules before use. make sure standard libraries are "required" by modules before use.
eliminate globals from namespaces created by module(). eliminate globals from namespaces created by module().
ftp.send/recv return bytes transfered? ftp.send/recv return bytes transfered?
new scheme to choose family/protocol of object to create new scheme to choose family/protocol of object to create
change ltn13 to make sure drawbacks are obvious change ltn13 to make sure drawbacks are obvious
- check discussion - check discussion
make sure errors not thrown by try() are not caught by protect()
use mike's "don't set to blocking before closing unless needed" patch? use mike's "don't set to blocking before closing unless needed" patch?
take a look at DB's smtp patch (add "extra argument" table) take a look at DB's smtp patch (add "extra argument" table)
move wsocket.c:sock_send kludge to buffer.c:sendraw (probably)?
optmize aux_getgroupudata (Mike idea) optmize aux_getgroupudata (Mike idea)
make aux_newclass receive upvalues make aux_newclass receive upvalues
@ -25,7 +23,10 @@ testar os options!
- proteger ou atomizar o conjunto (timedout, receive), (timedout, send) - proteger ou atomizar o conjunto (timedout, receive), (timedout, send)
- inet_ntoa também é uma merda. - inet_ntoa também é uma merda.
*use wim's filter.chain or something better *close wasn't returning 1
*make sure errors not thrown by try() are not caught by protect()
*move wsocket.c:sock_send kludge to buffer.c:sendraw?
*bug on UDP sendto.
*fix PROXY in http.lua *fix PROXY in http.lua
*use new distribution scheme *use new distribution scheme
*create the getstats method. *create the getstats method.

View File

@ -163,7 +163,7 @@ local ltn12 = require("ltn12")
local url = require("url") local url = require("url")
-- a function that returns a directory listing -- a function that returns a directory listing
function ls(u) function nlst(u)
local t = {} local t = {}
local p = url.parse(u) local p = url.parse(u)
p.command = "nlst" p.command = "nlst"

View File

@ -8,11 +8,14 @@
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Load required modules -- Load required modules
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local base = require("base")
local string = require("string")
local table = require("table")
local socket = require("socket") local socket = require("socket")
local url = require("socket.url") local url = require("socket.url")
local tp = require("socket.tp") local tp = require("socket.tp")
module("socket.dict") local dict = module("socket.dict")
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Globals -- Globals
@ -28,7 +31,7 @@ local metat = { __index = {} }
function open(host, port) function open(host, port)
local tp = socket.try(tp.connect(host or HOST, port or PORT, TIMEOUT)) local tp = socket.try(tp.connect(host or HOST, port or PORT, TIMEOUT))
return setmetatable({tp = tp}, metat) return base.setmetatable({tp = tp}, metat)
end end
function metat.__index:greet() function metat.__index:greet()
@ -37,7 +40,8 @@ end
function metat.__index:check(ok) function metat.__index:check(ok)
local code, status = socket.try(self.tp:check(ok)) local code, status = socket.try(self.tp:check(ok))
return code, tonumber(socket.skip(2, string.find(status, "^%d%d%d (%d*)"))) return code,
base.tonumber(socket.skip(2, string.find(status, "^%d%d%d (%d*)")))
end end
function metat.__index:getdef() function metat.__index:getdef()
@ -116,7 +120,7 @@ local function parse(u)
if cmd == "m" then if cmd == "m" then
arg = string.gsub(arg, "^:([^:]*)", function(f) t.strat = there(f) end) arg = string.gsub(arg, "^:([^:]*)", function(f) t.strat = there(f) end)
end end
string.gsub(arg, ":([^:]*)$", function(f) t.n = tonumber(f) end) string.gsub(arg, ":([^:]*)$", function(f) t.n = base.tonumber(f) end)
return t return t
end end
@ -143,6 +147,8 @@ local function sget(u)
end end
get = socket.protect(function(gett) get = socket.protect(function(gett)
if 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)
base.setmetatable(dict, nil)

View File

@ -9,9 +9,12 @@
if you have any questions: RFC 1179 if you have any questions: RFC 1179
]] ]]
-- make sure LuaSocket is loaded -- make sure LuaSocket is loaded
local io = require("io")
local base = require("base")
local string = require("string")
local socket = require("socket") local socket = require("socket")
local ltn12 = require("ltn12") local ltn12 = require("ltn12")
local test = socket.try local lp = module("socket.lp")
-- default port -- default port
PORT = 515 PORT = 515
@ -28,7 +31,7 @@ local function connect(localhost, option)
local localport = 721 local localport = 721
local done, err local done, err
repeat repeat
skt = test(socket.tcp()) skt = socket.try(socket.tcp())
try(skt:settimeout(30)) try(skt:settimeout(30))
done, err = skt:bind(localhost, localport) done, err = skt:bind(localhost, localport)
if not done then if not done then
@ -37,8 +40,8 @@ local function connect(localhost, option)
skt = nil skt = nil
else break end else break end
until localport > 731 until localport > 731
test(skt, err) socket.try(skt, err)
else skt = test(socket.tcp()) end else skt = socket.try(socket.tcp()) end
try(skt:connect(host, port)) try(skt:connect(host, port))
return { skt = skt, try = try } return { skt = skt, try = try }
end end
@ -241,9 +244,9 @@ local format_codes = {
-- lp.send -- lp.send
send = socket.protect(function(file, option) send = socket.protect(function(file, option)
test(file, "invalid file name") socket.try(file, "invalid file name")
test(option and type(option) == "table", "invalid options") socket.try(option and base.type(option) == "table", "invalid options")
local fh = test(io.open(file,"rb")) local fh = socket.try(io.open(file,"rb"))
local datafile_size = fh:seek("end") -- get total size local datafile_size = fh:seek("end") -- get total size
fh:seek("set") -- go back to start of file fh:seek("set") -- go back to start of file
local localhost = socket.dns.gethostname() or os.getenv("COMPUTERNAME") local localhost = socket.dns.gethostname() or os.getenv("COMPUTERNAME")
@ -270,11 +273,11 @@ send = socket.protect(function(file, option)
lpfile, lpfile,
ctlfn); -- mandatory part of ctl file ctlfn); -- mandatory part of ctl file
if (option.banner) then cfile = cfile .. 'L'..user..'\10' end if (option.banner) then cfile = cfile .. 'L'..user..'\10' end
if (option.indent) then cfile = cfile .. 'I'..tonumber(option.indent)..'\10' end if (option.indent) then cfile = cfile .. 'I'..base.tonumber(option.indent)..'\10' end
if (option.mail) then cfile = cfile .. 'M'..string.sub((option.mail),1,128)..'\10' end if (option.mail) then cfile = cfile .. 'M'..string.sub((option.mail),1,128)..'\10' end
if (fmt == 'p' and option.title) then cfile = cfile .. 'T'..string.sub((option.title),1,79)..'\10' end if (fmt == 'p' and option.title) then cfile = cfile .. 'T'..string.sub((option.title),1,79)..'\10' end
if ((fmt == 'p' or fmt == 'l' or fmt == 'f') and option.width) then if ((fmt == 'p' or fmt == 'l' or fmt == 'f') and option.width) then
cfile = cfile .. 'W'..tonumber(option,width)..'\10' cfile = cfile .. 'W'..base.tonumber(option,width)..'\10'
end end
con.skt:settimeout(option.timeout or 65) con.skt:settimeout(option.timeout or 65)
@ -314,3 +317,5 @@ query = socket.protect(function(p)
con.skt:close() con.skt:close()
return data return data
end) end)
base.setmetatable(lp, nil)

View File

@ -8,11 +8,14 @@
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Load required files -- Load required files
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local base = require("base")
local table = require("table")
local math = require("math")
local string = require("string")
local socket = require("socket") local socket = require("socket")
local ltn12 = require("ltn12") local ltn12 = require("ltn12")
local url = require("socket.url") local url = require("socket.url")
local tftp = module("socket.tftp")
module("socket.tftp")
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Program constants -- Program constants
@ -73,16 +76,18 @@ end
local function tget(gett) local function tget(gett)
local retries, dgram, sent, datahost, dataport, code local retries, dgram, sent, datahost, dataport, code
local last = 0 local last = 0
socket.try(gett.host, "missing host")
local con = socket.try(socket.udp()) local con = socket.try(socket.udp())
local try = socket.newtry(function() con:close() end) local try = socket.newtry(function() con:close() end)
-- convert from name to ip if needed -- convert from name to ip if needed
gett.host = try(socket.dns.toip(gett.host)) gett.host = try(socket.dns.toip(gett.host))
con:settimeout(1) con:settimeout(1)
-- first packet gives data host/port to be used for data transfers -- first packet gives data host/port to be used for data transfers
local path = string.gsub(gett.path or "", "^/", "")
path = url.unescape(path)
retries = 0 retries = 0
repeat repeat
sent = try(con:sendto(RRQ(gett.path, "octet"), sent = try(con:sendto(RRQ(path, "octet"), gett.host, gett.port))
gett.host, gett.port))
dgram, datahost, dataport = con:receivefrom() dgram, datahost, dataport = con:receivefrom()
retries = retries + 1 retries = retries + 1
until dgram or datahost ~= "timeout" or retries > 5 until dgram or datahost ~= "timeout" or retries > 5
@ -144,6 +149,8 @@ local function sget(u)
end end
get = socket.protect(function(gett) get = socket.protect(function(gett)
if 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)
base.setmetatable(tftp, nil)

View File

@ -12,17 +12,18 @@
<Configurations> <Configurations>
<Configuration <Configuration
Name="Debug|Win32" Name="Debug|Win32"
OutputDirectory="Debug" OutputDirectory=".\"
IntermediateDirectory="Debug" IntermediateDirectory=".\"
ConfigurationType="2" ConfigurationType="2"
CharacterSet="2"> CharacterSet="2">
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LUASOCKET_EXPORTS" AdditionalIncludeDirectories="h:\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LUASOCKET_EXPORTS;LUASOCKET_API=__declspec(dllexport)"
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="1" RuntimeLibrary="5"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
WarningLevel="3" WarningLevel="3"
Detect64BitPortabilityProblems="TRUE" Detect64BitPortabilityProblems="TRUE"
@ -31,6 +32,7 @@
Name="VCCustomBuildTool"/> Name="VCCustomBuildTool"/>
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="ws2_32.lib"
OutputFile="$(OutDir)/lsocket.dll" OutputFile="$(OutDir)/lsocket.dll"
LinkIncremental="2" LinkIncremental="2"
GenerateDebugInformation="TRUE" GenerateDebugInformation="TRUE"
@ -69,7 +71,7 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../include" AdditionalIncludeDirectories="../../include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LUASOCKET_EXPORTS;LUASOCKET_API=__declspec(dllexport); LUASOCKET_DEBUG" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LUASOCKET_EXPORTS;LUASOCKET_API=__declspec(dllexport); LUASOCKET_DEBUG"
RuntimeLibrary="0" RuntimeLibrary="4"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
WarningLevel="3" WarningLevel="3"
Detect64BitPortabilityProblems="TRUE" Detect64BitPortabilityProblems="TRUE"
@ -209,10 +211,10 @@
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter> </Filter>
<File <File
RelativePath="..\..\lib\lua.lib"> RelativePath="..\..\lib\liblua.lib">
</File> </File>
<File <File
RelativePath="..\..\lib\lualib.lib"> RelativePath="..\..\lib\liblualib.lib">
</File> </File>
</Files> </Files>
<Globals> <Globals>

View File

@ -12,17 +12,18 @@
<Configurations> <Configurations>
<Configuration <Configuration
Name="Debug|Win32" Name="Debug|Win32"
OutputDirectory="Debug" OutputDirectory=".\"
IntermediateDirectory="Debug" IntermediateDirectory=".\"
ConfigurationType="2" ConfigurationType="2"
CharacterSet="2"> CharacterSet="2">
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MIME_EXPORTS" AdditionalIncludeDirectories="h:\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MIME_EXPORTS;MIME_API=__declspec(dllexport)"
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="1" RuntimeLibrary="5"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
WarningLevel="3" WarningLevel="3"
Detect64BitPortabilityProblems="TRUE" Detect64BitPortabilityProblems="TRUE"
@ -69,7 +70,7 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../include" AdditionalIncludeDirectories="../../include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MIME_EXPORTS; MIME_API=__declspec(dllexport)" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MIME_EXPORTS; MIME_API=__declspec(dllexport)"
RuntimeLibrary="0" RuntimeLibrary="4"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
WarningLevel="3" WarningLevel="3"
Detect64BitPortabilityProblems="TRUE" Detect64BitPortabilityProblems="TRUE"
@ -136,10 +137,10 @@
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter> </Filter>
<File <File
RelativePath="..\..\lib\lua.lib"> RelativePath="..\..\lib\liblua.lib">
</File> </File>
<File <File
RelativePath="..\..\lib\lualib.lib"> RelativePath="..\..\lib\liblualib.lib">
</File> </File>
</Files> </Files>
<Globals> <Globals>

View File

@ -158,6 +158,7 @@ int buf_isempty(p_buf buf) {
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Sends a block of data (unbuffered) * Sends a block of data (unbuffered)
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
#define STEPSIZE 8192
static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent) { static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent) {
p_io io = buf->io; p_io io = buf->io;
p_tm tm = buf->tm; p_tm tm = buf->tm;
@ -165,7 +166,8 @@ static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent) {
int err = IO_DONE; int err = IO_DONE;
while (total < count && err == IO_DONE) { while (total < count && err == IO_DONE) {
size_t done; size_t done;
err = io->send(io->ctx, data+total, count-total, &done, tm); size_t step = (count-total <= STEPSIZE)? count-total: STEPSIZE;
err = io->send(io->ctx, data+total, step, &done, tm);
total += done; total += done;
} }
*sent = total; *sent = total;

View File

@ -29,11 +29,21 @@ static luaL_reg func[] = {
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Try factory * Try factory
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
static void wrap(lua_State *L) {
lua_newtable(L);
lua_pushnumber(L, 1);
lua_pushvalue(L, -3);
lua_settable(L, -3);
lua_insert(L, -2);
lua_pop(L, 1);
}
static int finalize(lua_State *L) { static int finalize(lua_State *L) {
if (!lua_toboolean(L, 1)) { if (!lua_toboolean(L, 1)) {
lua_pushvalue(L, lua_upvalueindex(1)); lua_pushvalue(L, lua_upvalueindex(1));
lua_pcall(L, 0, 0, 0); lua_pcall(L, 0, 0, 0);
lua_settop(L, 2); lua_settop(L, 2);
wrap(L);
lua_error(L); lua_error(L);
return 0; return 0;
} else return lua_gettop(L); } else return lua_gettop(L);
@ -54,13 +64,23 @@ static int global_newtry(lua_State *L) {
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Protect factory * Protect factory
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
static int unwrap(lua_State *L) {
if (lua_istable(L, -1)) {
lua_pushnumber(L, 1);
lua_gettable(L, -2);
lua_pushnil(L);
lua_insert(L, -2);
return 1;
} else return 0;
}
static int protected_(lua_State *L) { static int protected_(lua_State *L) {
lua_pushvalue(L, lua_upvalueindex(1)); lua_pushvalue(L, lua_upvalueindex(1));
lua_insert(L, 1); lua_insert(L, 1);
if (lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0) != 0) { if (lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0) != 0) {
lua_pushnil(L); if (unwrap(L)) return 2;
lua_insert(L, 1); else lua_error(L);
return 2; return 0;
} else return lua_gettop(L); } else return lua_gettop(L);
} }

View File

@ -8,13 +8,15 @@
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Declare module and import dependencies -- Declare module and import dependencies
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local base = require("base")
local table = require("table")
local string = require("string")
local math = require("math")
local socket = require("socket") 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")
local ftp = module("socket.ftp")
module("socket.ftp")
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Program constants -- Program constants
@ -35,7 +37,7 @@ local metat = { __index = {} }
function open(server, port) function open(server, port)
local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT)) local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT))
local f = 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)
return f return f
@ -102,7 +104,8 @@ function metat.__index:send(sendt)
-- we just get the data connection into self.data -- we just get the data connection into self.data
if self.pasvt then self:pasvconnect() end if self.pasvt then self:pasvconnect() end
-- get the transfer argument and command -- get the transfer argument and command
local argument = sendt.argument or string.gsub(sendt.path, "^/", "") local argument = sendt.argument or
url.unescape(string.gsub(sendt.path or "", "^/", ""))
if argument == "" then argument = nil end if argument == "" then argument = nil end
local command = sendt.command or "stor" local command = sendt.command or "stor"
-- send the transfer command and check the reply -- send the transfer command and check the reply
@ -134,7 +137,8 @@ end
function metat.__index:receive(recvt) function metat.__index:receive(recvt)
self.try(self.pasvt or self.server, "need port or pasv first") self.try(self.pasvt or self.server, "need port or pasv first")
if self.pasvt then self:pasvconnect() end if self.pasvt then self:pasvconnect() end
local argument = recvt.argument or string.gsub(recvt.path, "^/", "") local argument = recvt.argument or
url.unescape(string.gsub(recvt.path or "", "^/", ""))
if argument == "" then argument = nil end if argument == "" then argument = nil end
local command = recvt.command or "retr" local command = recvt.command or "retr"
self.try(self.tp:command(command, argument)) self.try(self.tp:command(command, argument))
@ -182,7 +186,19 @@ end
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- High level FTP API -- High level FTP API
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
function override(t)
if t.url then
u = url.parse(t.url)
for i,v in base.pairs(t) do
u[i] = v
end
return u
else return t end
end
local function tput(putt) local function tput(putt)
putt = override(putt)
socket.try(putt.host, "missing hostname")
local f = open(putt.host, putt.port) local f = open(putt.host, putt.port)
f:greet() f:greet()
f:login(putt.user, putt.password) f:login(putt.user, putt.password)
@ -201,8 +217,8 @@ local default = {
local function parse(u) local function parse(u)
local t = socket.try(url.parse(u, default)) local t = socket.try(url.parse(u, default))
socket.try(t.scheme == "ftp", "invalid scheme '" .. t.scheme .. "'") socket.try(t.scheme == "ftp", "wrong scheme '" .. t.scheme .. "'")
socket.try(t.host, "invalid host") socket.try(t.host, "missing hostname")
local pat = "^type=(.)$" local pat = "^type=(.)$"
if t.params then if t.params then
t.type = socket.skip(2, string.find(t.params, pat)) t.type = socket.skip(2, string.find(t.params, pat))
@ -219,11 +235,13 @@ local function sput(u, body)
end end
put = socket.protect(function(putt, body) put = socket.protect(function(putt, body)
if 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)
local function tget(gett) local function tget(gett)
gett = override(gett)
socket.try(gett.host, "missing hostname")
local f = open(gett.host, gett.port) local f = open(gett.host, gett.port)
f:greet() f:greet()
f:login(gett.user, gett.password) f:login(gett.user, gett.password)
@ -242,7 +260,22 @@ local function sget(u)
return table.concat(t) return table.concat(t)
end end
command = socket.protect(function(cmdt)
cmdt = override(cmdt)
socket.try(cmdt.host, "missing hostname")
socket.try(cmdt.command, "missing command")
local f = open(cmdt.host, cmdt.port)
f:greet()
f:login(cmdt.user, cmdt.password)
f.try(f.tp:command(cmdt.command, cmdt.argument))
if cmdt.check then f.try(f.tp:check(cmdt.check)) end
f:quit()
return f:close()
end)
get = socket.protect(function(gett) get = socket.protect(function(gett)
if 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)
base.setmetatable(ftp, nil)

View File

@ -12,8 +12,10 @@ local socket = require("socket")
local url = require("socket.url") local url = require("socket.url")
local ltn12 = require("ltn12") local ltn12 = require("ltn12")
local mime = require("mime") local mime = require("mime")
local string = require("string")
module("socket.http") local base = require("base")
local table = require("table")
local http = module("socket.http")
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Program constants -- Program constants
@ -32,7 +34,7 @@ local metat = { __index = {} }
function open(host, port) function open(host, port)
local c = socket.try(socket.tcp()) local c = socket.try(socket.tcp())
local h = setmetatable({ c = c }, metat) local h = base.setmetatable({ c = c }, metat)
-- make sure the connection gets closed on exception -- make sure the connection gets closed on exception
h.try = socket.newtry(function() h:close() end) h.try = socket.newtry(function() h:close() end)
h.try(c:settimeout(TIMEOUT)) h.try(c:settimeout(TIMEOUT))
@ -46,7 +48,7 @@ function metat.__index:sendrequestline(method, uri)
end end
function metat.__index:sendheaders(headers) function metat.__index:sendheaders(headers)
for i, v in pairs(headers) do for i, v in base.pairs(headers) do
self.try(self.c:send(i .. ": " .. v .. "\r\n")) self.try(self.c:send(i .. ": " .. v .. "\r\n"))
end end
-- mark end of request headers -- mark end of request headers
@ -66,7 +68,7 @@ end
function metat.__index:receivestatusline() function metat.__index:receivestatusline()
local status = self.try(self.c:receive()) local status = self.try(self.c:receive())
local code = socket.skip(2, string.find(status, "HTTP/%d*%.%d* (%d%d%d)")) local code = socket.skip(2, string.find(status, "HTTP/%d*%.%d* (%d%d%d)"))
return self.try(tonumber(code), status) return self.try(base.tonumber(code), status)
end end
function metat.__index:receiveheaders() function metat.__index:receiveheaders()
@ -97,11 +99,11 @@ end
function metat.__index:receivebody(headers, sink, step) function metat.__index:receivebody(headers, sink, step)
sink = sink or ltn12.sink.null() sink = sink or ltn12.sink.null()
step = step or ltn12.pump.step step = step or ltn12.pump.step
local length = tonumber(headers["content-length"]) local length = base.tonumber(headers["content-length"])
local TE = headers["transfer-encoding"] local TE = headers["transfer-encoding"]
local mode = "default" -- connection close local mode = "default" -- connection close
if TE and TE ~= "identity" then mode = "http-chunked" if TE and TE ~= "identity" then mode = "http-chunked"
elseif tonumber(headers["content-length"]) then mode = "by-length" end elseif base.tonumber(headers["content-length"]) then mode = "by-length" end
return self.try(ltn12.pump.all(socket.source(mode, self.c, length), return self.try(ltn12.pump.all(socket.source(mode, self.c, length),
sink, step)) sink, step))
end end
@ -159,9 +161,10 @@ local default = {
local function adjustrequest(reqt) local function adjustrequest(reqt)
-- parse url if provided -- parse url if provided
local nreqt = reqt.url and url.parse(reqt.url, default) or {} local nreqt = reqt.url and url.parse(reqt.url, default) or {}
local t = url.parse(reqt.url, default)
-- explicit components override url -- explicit components override url
for i,v in reqt do nreqt[i] = reqt[i] end for i,v in reqt do nreqt[i] = reqt[i] end
socket.try(nreqt.host, "invalid host '" .. tostring(nreqt.host) .. "'") socket.try(nreqt.host, "invalid host '" .. base.tostring(nreqt.host) .. "'")
-- compute uri if user hasn't overriden -- compute uri if user hasn't overriden
nreqt.uri = reqt.uri or adjusturi(nreqt) nreqt.uri = reqt.uri or adjusturi(nreqt)
-- ajust host and port if there is a proxy -- ajust host and port if there is a proxy
@ -253,6 +256,8 @@ local function srequest(u, body)
end end
request = socket.protect(function(reqt, body) request = socket.protect(function(reqt, body)
if 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)
base.setmetatable(http, nil)

View File

@ -8,7 +8,11 @@
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Declare module -- Declare module
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module("ltn12") local string = require("string")
local table = require("table")
local base = require("base")
local coroutine = require("coroutine")
local ltn12 = module("ltn12")
filter = {} filter = {}
source = {} source = {}
@ -23,7 +27,7 @@ BLOCKSIZE = 2048
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- returns a high level filter that cycles a low-level filter -- returns a high level filter that cycles a low-level filter
function filter.cycle(low, ctx, extra) function filter.cycle(low, ctx, extra)
assert(low) base.assert(low)
return function(chunk) return function(chunk)
local ret local ret
ret, ctx = low(ctx, chunk, extra) ret, ctx = low(ctx, chunk, extra)
@ -121,7 +125,7 @@ end
-- turns a fancy source into a simple source -- turns a fancy source into a simple source
function source.simplify(src) function source.simplify(src)
assert(src) base.assert(src)
return function() return function()
local chunk, err_or_new = src() local chunk, err_or_new = src()
src = err_or_new or src src = err_or_new or src
@ -145,7 +149,7 @@ end
-- creates rewindable source -- creates rewindable source
function source.rewind(src) function source.rewind(src)
assert(src) base.assert(src)
local t = {} local t = {}
return function(chunk) return function(chunk)
if not chunk then if not chunk then
@ -160,7 +164,7 @@ end
-- chains a source with a filter -- chains a source with a filter
function source.chain(src, f) function source.chain(src, f)
assert(src and f) base.assert(src and f)
local co = coroutine.create(function() local co = coroutine.create(function()
while true do while true do
local chunk, err = src() local chunk, err = src()
@ -215,7 +219,7 @@ end
-- turns a fancy sink into a simple sink -- turns a fancy sink into a simple sink
function sink.simplify(snk) function sink.simplify(snk)
assert(snk) base.assert(snk)
return function(chunk, err) return function(chunk, err)
local ret, err_or_new = snk(chunk, err) local ret, err_or_new = snk(chunk, err)
if not ret then return nil, err_or_new end if not ret then return nil, err_or_new end
@ -254,7 +258,7 @@ end
-- chains a sink with a filter -- chains a sink with a filter
function sink.chain(f, snk) function sink.chain(f, snk)
assert(f and snk) base.assert(f and snk)
return function(chunk, err) return function(chunk, err)
local filtered = f(chunk) local filtered = f(chunk)
local done = chunk and "" local done = chunk and ""
@ -279,10 +283,12 @@ end
-- pumps all data from a source to a sink, using a step function -- pumps all data from a source to a sink, using a step function
function pump.all(src, snk, step) function pump.all(src, snk, step)
assert(src and snk) base.assert(src and snk)
step = step or pump.step step = step or pump.step
while true do while true do
local ret, err = step(src, snk) local ret, err = step(src, snk)
if not ret then return not err, err end if not ret then return not err, err end
end end
end end
base.setmetatable(ltn12, nil)

View File

@ -8,9 +8,10 @@
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Declare module and import dependencies -- Declare module and import dependencies
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module("mime") local base = require("base")
local mime = require("lmime")
local ltn12 = require("ltn12") local ltn12 = require("ltn12")
local mime = require("lmime")
module("mime")
-- encode, decode and wrap algorithm tables -- encode, decode and wrap algorithm tables
mime.encodet = {} mime.encodet = {}
@ -20,11 +21,11 @@ mime.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)
return function(name, opt1, opt2) return function(name, opt1, opt2)
if type(name) ~= "string" then if base.type(name) ~= "string" then
name, opt1, opt2 = "default", name, opt1 name, opt1, opt2 = "default", name, opt1
end end
local f = table[name or "nil"] local f = table[name or "nil"]
if not f then error("unknown key (" .. tostring(name) .. ")", 3) if not f then error("unknown key (" .. base.tostring(name) .. ")", 3)
else return f(opt1, opt2) end else return f(opt1, opt2) end
end end
end end
@ -74,3 +75,5 @@ end
function mime.stuff() function mime.stuff()
return ltn12.filter.cycle(dot, 2) return ltn12.filter.cycle(dot, 2)
end end
base.setmetatable(mime, nil)

View File

@ -8,13 +8,16 @@
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Declare module and import dependencies -- Declare module and import dependencies
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local base = require("base")
local coroutine = require("coroutine")
local string = require("string")
local math = require("math")
local os = require("os")
local socket = require("socket") local socket = require("socket")
local tp = require("socket.tp") local tp = require("socket.tp")
local ltn12 = require("ltn12") local ltn12 = require("ltn12")
local mime = require("mime") local mime = require("mime")
local smtp = module("socket.smtp")
module("socket.smtp")
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Program constants -- Program constants
@ -98,8 +101,8 @@ end
-- send message or throw an exception -- send message or throw an exception
function metat.__index:send(mailt) function metat.__index:send(mailt)
self:mail(mailt.from) self:mail(mailt.from)
if type(mailt.rcpt) == "table" then if base.type(mailt.rcpt) == "table" then
for i,v in ipairs(mailt.rcpt) do for i,v in base.ipairs(mailt.rcpt) do
self:rcpt(v) self:rcpt(v)
end end
else else
@ -110,7 +113,7 @@ end
function open(server, port) function open(server, port)
local tp = socket.try(tp.connect(server or SERVER, port or PORT, TIMEOUT)) local tp = socket.try(tp.connect(server or SERVER, port or PORT, TIMEOUT))
local s = 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()
if s.tp:command("QUIT") then s.tp:check("2..") end if s.tp:command("QUIT") then s.tp:check("2..") end
@ -145,7 +148,7 @@ local function send_multipart(mesgt)
coroutine.yield("\r\n") coroutine.yield("\r\n")
end end
-- send each part separated by a boundary -- send each part separated by a boundary
for i, m in ipairs(mesgt.body) do for i, m in base.ipairs(mesgt.body) do
coroutine.yield("\r\n--" .. bd .. "\r\n") coroutine.yield("\r\n--" .. bd .. "\r\n")
send_message(m) send_message(m)
end end
@ -191,7 +194,7 @@ end
-- yield the headers one by one -- yield the headers one by one
local function send_headers(mesgt) local function send_headers(mesgt)
if mesgt.headers then if mesgt.headers then
for i,v in pairs(mesgt.headers) do for i,v in base.pairs(mesgt.headers) do
coroutine.yield(i .. ':' .. v .. "\r\n") coroutine.yield(i .. ':' .. v .. "\r\n")
end end
end end
@ -200,8 +203,8 @@ end
-- message source -- message source
function send_message(mesgt) function send_message(mesgt)
send_headers(mesgt) send_headers(mesgt)
if type(mesgt.body) == "table" then send_multipart(mesgt) if base.type(mesgt.body) == "table" then send_multipart(mesgt)
elseif type(mesgt.body) == "function" then send_source(mesgt) elseif base.type(mesgt.body) == "function" then send_source(mesgt)
else send_string(mesgt) end else send_string(mesgt) end
end end
@ -241,3 +244,5 @@ send = socket.protect(function(mailt)
s:quit() s:quit()
return s:close() return s:close()
end) end)
base.setmetatable(smtp, nil)

View File

@ -233,7 +233,8 @@ static int meth_close(lua_State *L)
{ {
p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1);
sock_destroy(&tcp->sock); sock_destroy(&tcp->sock);
return 0; lua_pushnumber(L, 1);
return 1;
} }
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\

View File

@ -8,10 +8,12 @@
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Declare module and import dependencies -- Declare module and import dependencies
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local base = require("base")
local string = require("string")
local socket = require("socket") local socket = require("socket")
local ltn12 = require("ltn12") local ltn12 = require("ltn12")
module("socket.tp") local tp = module("socket.tp")
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Program constants -- Program constants
@ -47,22 +49,27 @@ local metat = { __index = {} }
function metat.__index:check(ok) function metat.__index:check(ok)
local code, reply = get_reply(self.c) local code, reply = get_reply(self.c)
if not code then return nil, reply end if not code then return nil, reply end
if type(ok) ~= "function" then if base.type(ok) ~= "function" then
if type(ok) == "table" then if base.type(ok) == "table" then
for i, v in ipairs(ok) do for i, v in base.ipairs(ok) do
if string.find(code, v) then return tonumber(code), reply end if string.find(code, v) then
return base.tonumber(code), reply
end
end end
return nil, reply return nil, reply
else else
if string.find(code, ok) then return tonumber(code), reply if string.find(code, ok) then return base.tonumber(code), reply
else return nil, reply end else return nil, reply end
end end
else return ok(tonumber(code), reply) end else return ok(base.tonumber(code), reply) end
end end
function metat.__index:command(cmd, arg) function metat.__index:command(cmd, arg)
if arg then return self.c:send(cmd .. " " .. arg.. "\r\n") if arg then
else return self.c:send(cmd .. "\r\n") end return self.c:send(cmd .. " " .. arg.. "\r\n")
else
return self.c:send(cmd .. "\r\n")
end
end end
function metat.__index:sink(snk, pat) function metat.__index:sink(snk, pat)
@ -111,5 +118,7 @@ function connect(host, port, timeout)
c:close() c:close()
return nil, e return nil, e
end end
return setmetatable({c = c}, metat) return base.setmetatable({c = c}, metat)
end end
base.setmetatable(tp, nil)

View File

@ -288,7 +288,8 @@ static int meth_setpeername(lua_State *L) {
static int meth_close(lua_State *L) { static int meth_close(lua_State *L) {
p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1);
sock_destroy(&udp->sock); sock_destroy(&udp->sock);
return 0; lua_pushnumber(L, 1);
return 1;
} }
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\

View File

@ -8,7 +8,10 @@
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Declare module -- Declare module
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module("socket.url") local string = require("string")
local base = require("base")
local table = require("table")
local url = module("socket.url")
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Encodes a string into its escaped hexadecimal representation -- Encodes a string into its escaped hexadecimal representation
@ -18,7 +21,7 @@ module("socket.url")
-- escaped representation of string binary -- escaped representation of string binary
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
function escape(s) function escape(s)
return string.gsub(s, "(.)", 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)
end end
@ -33,7 +36,7 @@ end
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local function make_set(t) local function make_set(t)
local s = {} local s = {}
for i = 1, table.getn(t) do for i,v in base.ipairs(t) do
s[t[i]] = 1 s[t[i]] = 1
end end
return s return s
@ -62,7 +65,7 @@ end
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
function unescape(s) function unescape(s)
return string.gsub(s, "%%(%x%x)", function(hex) return string.gsub(s, "%%(%x%x)", function(hex)
return string.char(tonumber(hex, 16)) return string.char(base.tonumber(hex, 16))
end) end)
end end
@ -191,7 +194,7 @@ end
-- corresponding absolute url -- corresponding absolute url
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
function absolute(base_url, relative_url) function absolute(base_url, relative_url)
local base = type(base_url) == "table" and base_url or parse(base_url) local base = base.type(base_url) == "table" and base_url or parse(base_url)
local relative = parse(relative_url) local relative = parse(relative_url)
if not base then return relative_url if not base then return relative_url
elseif not relative then return base_url elseif not relative then return base_url
@ -269,3 +272,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
base.setmetatable(url, nil)

View File

@ -180,9 +180,10 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *len, p_tm tm) {
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Send with timeout * Send with timeout
* On windows, if you try to send 10MB, the OS will buffer EVERYTHING
* this can take an awful lot of time and we will end up blocked.
* Therefore, whoever calls this function should not pass a huge buffer.
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
/* has to be larger than UDP_DATAGRAMSIZE !!!*/
#define MAXCHUNK (64*1024)
int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm) int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm)
{ {
int err; int err;
@ -192,9 +193,7 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm)
*sent = 0; *sent = 0;
for ( ;; ) { for ( ;; ) {
/* try to send something */ /* try to send something */
/* on windows, if you try to send 10MB, the OS will buffer EVERYTHING int put = send(*ps, data, count, 0);
* this can take an awful lot of time and we will end up blocked. */
int put = send(*ps, data, (count < MAXCHUNK)? (int)count: MAXCHUNK, 0);
/* if we sent something, we are done */ /* if we sent something, we are done */
if (put > 0) { if (put > 0) {
*sent = put; *sent = put;
@ -221,7 +220,7 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent,
if (*ps == SOCK_INVALID) return IO_CLOSED; if (*ps == SOCK_INVALID) return IO_CLOSED;
*sent = 0; *sent = 0;
for ( ;; ) { for ( ;; ) {
int put = send(*ps, data, (int) count, 0); int put = sendto(*ps, data, (int) count, 0, addr, len);
if (put > 0) { if (put > 0) {
*sent = put; *sent = put;
return IO_DONE; return IO_DONE;
@ -298,13 +297,13 @@ void sock_setnonblocking(p_sock ps) {
int sock_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { int sock_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) {
*hp = gethostbyaddr(addr, len, AF_INET); *hp = gethostbyaddr(addr, len, AF_INET);
if (*hp) return IO_DONE; if (*hp) return IO_DONE;
else return h_errno; else return WSAGetLastError();
} }
int sock_gethostbyname(const char *addr, struct hostent **hp) { int sock_gethostbyname(const char *addr, struct hostent **hp) {
*hp = gethostbyname(addr); *hp = gethostbyname(addr);
if (*hp) return IO_DONE; if (*hp) return IO_DONE;
else return h_errno; else return WSAGetLastError();
} }
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\

View File

@ -1,3 +1,3 @@
local dict = require"socket.dict" local dict = require"socket.dict"
for i,v in dict.get("dict://localhost/d:banana") do print(v) end for i,v in dict.get("dict://dell-diego/d:banana") do print(v) end

View File

@ -1,103 +1,110 @@
local similar = function(s1, s2) local socket = require("socket")
return local ftp = require("socket.ftp")
string.lower(string.gsub(s1, "%s", "")) == local url = require("socket.url")
string.lower(string.gsub(s2, "%s", "")) local ltn12 = require("ltn12")
-- override protection to make sure we see all errors
--socket.protect = function(s) return s end
dofile("testsupport.lua")
local host, port, index_file, index, back, err, ret
local t = socket.gettime()
host = host or "diego.student.princeton.edu"
index_file = "test/index.html"
-- a function that returns a directory listing
local function nlst(u)
local t = {}
local p = url.parse(u)
p.command = "nlst"
p.sink = ltn12.sink.table(t)
local r, e = ftp.get(p)
return r and table.concat(t), e
end end
local readfile = function(name) -- function that removes a remote file
local f = io.open(name, "r") local function dele(u)
if not f then return nil end local p = url.parse(u)
local s = f:read("*a") p.command = "dele"
f:close() p.argument = string.gsub(p.path, "^/", "")
return s if p.argumet == "" then p.argument = nil end
p.check = 250
return ftp.command(p)
end end
local capture = function(cmd) -- read index with CRLF convention
local f = io.popen(cmd) index = readfile(index_file)
if not f then return nil end
local s = f:read("*a")
f:close()
return s
end
local check = function(v, e, o)
e = e or "failed!"
o = o or "ok"
if v then print(o)
else print(e) os.exit() end
end
-- needs an account luasocket:password
-- and some directories and files in ~ftp
local index, err, saved, back, expected
local t = socket.time()
index = readfile("test/index.html")
io.write("testing wrong scheme: ") io.write("testing wrong scheme: ")
back, err = socket.ftp.get("wrong://banana.com/lixo") back, err = ftp.get("wrong://banana.com/lixo")
check(not back and err == "unknown scheme 'wrong'", err) assert(not back and err == "wrong scheme 'wrong'", err)
print("ok")
io.write("testing invalid url: ") io.write("testing invalid url: ")
back, err = socket.ftp.get("localhost/dir1/index.html;type=i") back, err = ftp.get("localhost/dir1/index.html;type=i")
local c, e = socket.connect("", 21) assert(not back and err)
check(not back and err == e, err) print("ok")
io.write("testing anonymous file upload: ")
os.remove("/var/ftp/pub/index.up.html")
ret, err = socket.ftp.put("ftp://localhost/pub/index.up.html;type=i", index)
saved = readfile("/var/ftp/pub/index.up.html")
check(ret and not err and saved == index, err)
io.write("testing anonymous file download: ") io.write("testing anonymous file download: ")
back, err = socket.ftp.get("ftp://localhost/pub/index.up.html;type=i") back, err = socket.ftp.get("ftp://" .. host .. "/pub/index.html;type=i")
check(not err and back == index, err) assert(not err and back == index, err)
print("ok")
io.write("testing no directory changes: ") io.write("erasing before upload: ")
back, err = socket.ftp.get("ftp://localhost/index.html;type=i") ret, err = dele("ftp://luasocket:password@" .. host .. "/index.up.html")
check(not err and back == index, err) if not ret then print(err)
else print("ok") end
io.write("testing multiple directory changes: ") io.write("testing upload: ")
back, err = socket.ftp.get("ftp://localhost/pub/dir1/dir2/dir3/dir4/dir5/index.html;type=i") ret, err = ftp.put("ftp://luasocket:password@" .. host .. "/index.up.html;type=i", index)
check(not err and back == index, err) assert(ret and not err, err)
print("ok")
io.write("testing authenticated upload: ") io.write("downloading uploaded file: ")
os.remove("/home/luasocket/index.up.html") back, err = ftp.get("ftp://luasocket:password@" .. host .. "/index.up.html;type=i")
ret, err = socket.ftp.put("ftp://luasocket:password@localhost/index.up.html;type=i", index) assert(ret and not err and index == back, err)
saved = readfile("/home/luasocket/index.up.html") print("ok")
check(ret and not err and saved == index, err)
io.write("testing authenticated download: ") io.write("erasing after upload/download: ")
back, err = socket.ftp.get("ftp://luasocket:password@localhost/index.up.html;type=i") ret, err = dele("ftp://luasocket:password@" .. host .. "/index.up.html")
check(not err and back == index, err) assert(ret and not err, err)
print("ok")
io.write("testing weird-character translation: ") io.write("testing weird-character translation: ")
back, err = socket.ftp.get("ftp://luasocket:password@localhost/%2fvar/ftp/pub/index.html;type=i") back, err = ftp.get("ftp://luasocket:password@" .. host .. "/%23%3f;type=i")
check(not err and back == index, err) assert(not err and back == index, err)
print("ok")
io.write("testing parameter overriding: ") io.write("testing parameter overriding: ")
back, err = socket.ftp.get { local back = {}
url = "//stupid:mistake@localhost/index.html", ret, err = ftp.get{
url = "//stupid:mistake@" .. host .. "/index.html",
user = "luasocket", user = "luasocket",
password = "password", password = "password",
type = "i" type = "i",
sink = ltn12.sink.table(back)
} }
check(not err and back == index, err) assert(ret and not err and table.concat(back) == index, err)
print("ok")
io.write("testing upload denial: ") io.write("testing upload denial: ")
ret, err = socket.ftp.put("ftp://localhost/index.up.html;type=a", index) ret, err = ftp.put("ftp://" .. host .. "/index.up.html;type=a", index)
check(err, err) assert(not ret and err, "should have failed")
print(err)
io.write("testing authentication failure: ") io.write("testing authentication failure: ")
ret, err = socket.ftp.put("ftp://luasocket:wrong@localhost/index.html;type=a", index) ret, err = ftp.get("ftp://luasocket:wrong@".. host .. "/index.html;type=a")
assert(not ret and err, "should have failed")
print(err) print(err)
check(not ret and err, err)
io.write("testing wrong file: ") io.write("testing wrong file: ")
back, err = socket.ftp.get("ftp://localhost/index.wrong.html;type=a") back, err = ftp.get("ftp://".. host .. "/index.wrong.html;type=a")
check(err, err) assert(not back and err, "should have failed")
print(err)
print("passed all tests") print("passed all tests")
print(string.format("done in %.2fs", socket.time() - t)) print(string.format("done in %.2fs", socket.gettime() - t))

View File

@ -23,7 +23,7 @@ http.TIMEOUT = 10
local t = socket.gettime() local t = socket.gettime()
host = host or "diego.student.princeton.edu" host = host or "diego.student.princeton.edu"
proxy = proxy or "http://localhost:3128" proxy = proxy or "http://dell-diego.cs.princeton.edu:3128"
prefix = prefix or "/luasocket-test" prefix = prefix or "/luasocket-test"
cgiprefix = cgiprefix or "/luasocket-test-cgi" cgiprefix = cgiprefix or "/luasocket-test-cgi"
index_file = "test/index.html" index_file = "test/index.html"

View File

@ -1,7 +1,7 @@
local socket = require"socket" local socket = require"socket"
host = host or "localhost" host = host or "localhost"
port = port or "8080" port = port or "8383"
function pass(...) function pass(...)
local s = string.format(unpack(arg)) local s = string.format(unpack(arg))
@ -590,7 +590,6 @@ test_mixed(200)
test_mixed(17) test_mixed(17)
test_mixed(1) test_mixed(1)
test("binary line") test("binary line")
test_rawline(1) test_rawline(1)
test_rawline(17) test_rawline(17)
@ -630,14 +629,12 @@ test_nonblocking(200)
test_nonblocking(17) test_nonblocking(17)
test_nonblocking(1) test_nonblocking(1)
test("total timeout on send") test("total timeout on send")
test_totaltimeoutsend(800091, 1, 3) test_totaltimeoutsend(800091, 1, 3)
test_totaltimeoutsend(800091, 2, 3) test_totaltimeoutsend(800091, 2, 3)
test_totaltimeoutsend(800091, 5, 2) test_totaltimeoutsend(800091, 5, 2)
test_totaltimeoutsend(800091, 3, 1) test_totaltimeoutsend(800091, 3, 1)
test("total timeout on receive") test("total timeout on receive")
test_totaltimeoutreceive(800091, 1, 3) test_totaltimeoutreceive(800091, 1, 3)
test_totaltimeoutreceive(800091, 2, 3) test_totaltimeoutreceive(800091, 2, 3)

View File

@ -1,5 +1,5 @@
-- load the smtp support and its friends -- load the smtp support and its friends
local smtp = require("smtp") local smtp = require("socket.smtp")
local mime = require("mime") local mime = require("mime")
local ltn12 = require("ltn12") local ltn12 = require("ltn12")
@ -48,6 +48,11 @@ source = smtp.message{
} }
} }
--[[
sink = ltn12.sink.file(io.stdout)
ltn12.pump.all(source, sink)
]]
-- finally send it -- finally send it
r, e = smtp.send{ r, e = smtp.send{
rcpt = {"<diego@tecgraf.puc-rio.br>", rcpt = {"<diego@tecgraf.puc-rio.br>",

View File

@ -1,6 +1,6 @@
socket = require("socket"); socket = require("socket");
host = host or "localhost"; host = host or "localhost";
port = port or "8080"; port = port or "8383";
server = assert(socket.bind(host, port)); server = assert(socket.bind(host, port));
ack = "\n"; ack = "\n";
while 1 do while 1 do

View File

@ -12,7 +12,7 @@ function readfile(file)
return a return a
end end
host = host or "localhost" host = host or "diego.student.princeton.edu"
retrieved, err = tftp.get("tftp://" .. host .."/index.html") retrieved, err = tftp.get("tftp://" .. host .."/index.html")
assert(not err, err) assert(not err, err)
original = readfile("test/index.html") original = readfile("test/index.html")