Fine tuning the "require" business.

This commit is contained in:
Diego Nehab 2004-05-30 21:36:22 +00:00
parent c23240726e
commit 5ca1049ab4
17 changed files with 133 additions and 116 deletions

118
TODO
View File

@ -1,54 +1,14 @@
* should be interrupt-safe ajeitar os README.*
* notice the change in callback conventions ajeitar select. upvalue nao tem nada a ver...
* new mime module replacing old code module (faster, more functionality)
* new socket options (many)
* only allocate in case of success
* optimize for success (only call select if fails)
* add proxy support to http
* add gethostname
* local connect
* connect with timeout
* change code to mime
* change stay to redirect
* add shutdown
* change send/recv to avoid using select
* O location do "redirect" pode ser relativo ao servidor atual (não pode,
mas os servidores fazem merda...)
* Ajeitar para Lua 5.0
* Padronizar os retornos de funccao
* Separar as classes em arquivos
* Retorno de sendto em datagram sockets pode ser refused
* select sets are now associative
* colocar pump.all, pump.step
* mudar ltn12.html e usar o exemplo source.cat que está muito melhor.
* break smtp.send into c = smtp.open, c:send() c:close()
* fazer com que a socket.source e socket.sink sejam "selectable".
* change mime.eol to output marker on detection of first candidate, instead
of on the second. that way it works in one pass for strings that end with
one candidate.
* unify backbone of smtp and ftp
* unify filter and send/receive callback. new sink/source/pump idea.
* get rid of aux_optlstring
* get rid of unpack in mime.lua
* create socket.(sink|source).simplify
* break chain into a simpler binary chain and a complex (recursive) one.
* Create a passive mode option for the FTP (good for firewall).
* Modules should return their namespace table in the end of the chunk.
get.lua precisa de ftp.get com url e sink
make sure filter.chain fails gracefully. make sure filter.chain fails gracefully.
ajeitar o manual sobre select, mais liberal agora ajeitar o manual sobre select, mais liberal agora
conjunto associativo
falar sobre encodet/wrapt/decodet no manual sobre mime falar sobre encodet/wrapt/decodet no manual sobre mime
RECEIVE MUDOU!!! (partial stuff) COLOCAR NO MANUAL. RECEIVE MUDOU!!! (partial stuff) COLOCAR NO MANUAL.
HTTP.lua mudou bastante também. HTTP.lua mudou bastante também.
pump.step usado em todo mundo que recebe source ou sink pump.step usado em todo mundo que recebe source ou sink
colocar um userdata com gc metamethod pra chamar sock_close (WSAClose);
sources ans sinks are always simple in http and ftp and smtp sources ans sinks are always simple in http and ftp and smtp
expose encode/decode tables to provide extensibility for mime module expose encode/decode tables to provide extensibility for mime module
use coroutines instead of fancy filters use coroutines instead of fancy filters
@ -60,6 +20,7 @@ pop3???
add socket.TIMEOUT to be default timeout? add socket.TIMEOUT to be default timeout?
manual manual
compatibility: select sets are associative
add socket.connect and socket.bind to the manual add socket.connect and socket.bind to the manual
say what a nil callback does for http say what a nil callback does for http
check all occurences of it's check all occurences of it's
@ -87,24 +48,9 @@ tests
check for interrupts check for interrupts
wrp can't break lines in the middle of a line break. wrp can't break lines in the middle of a line break.
call select before accept, not after, dumbass!
get rid of setnonblocking/setblocking in the bind function
close has to block...
fmt is not a good name
change wrap() to accept a number and default to "character"
move gethostname to dns table
get rid of _cb in name of functions?
trust character constants in mime.c? noooooo.
smtp.lua needs stuff filter
add comments into each C module. add comments into each C module.
new option.c module to put all options (TCP and UDP share...)?
testar os options! testar os options!
add _tostring methods!
change all modules to use the new namespace scheme
write some utilities that use the code.lua module and put them
in etc, modify the README.etc file and makefile.dist (eol.lua is done)
use gethostname it in SMTP use gethostname it in SMTP
@ -150,3 +96,61 @@ Ajeitar o protocolo da luaopen_socket()... sei l
- unix 92 bytes maximo no endereço, incluindo o zero - unix 92 bytes maximo no endereço, incluindo o zero
- unix 9216 maximo de datagram size - unix 9216 maximo de datagram size
--------------
these are done
--------------
* should be interrupt-safe
* notice the change in callback conventions
* new mime module replacing old code module (faster, more functionality)
* new socket options (many)
* only allocate in case of success
* optimize for success (only call select if fails)
* add proxy support to http
* add gethostname
* local connect
* connect with timeout
* change code to mime
* change stay to redirect
* add shutdown
* change send/recv to avoid using select
* O location do "redirect" pode ser relativo ao servidor atual (não pode,
mas os servidores fazem merda...)
* Ajeitar para Lua 5.0
* Padronizar os retornos de funccao
* Separar as classes em arquivos
* Retorno de sendto em datagram sockets pode ser refused
* select sets are now associative
* colocar pump.all, pump.step
* mudar ltn12.html e usar o exemplo source.cat que está muito melhor.
* break smtp.send into c = smtp.open, c:send() c:close()
* fazer com que a socket.source e socket.sink sejam "selectable".
* change mime.eol to output marker on detection of first candidate, instead
of on the second. that way it works in one pass for strings that end with
one candidate.
* unify backbone of smtp and ftp
* unify filter and send/receive callback. new sink/source/pump idea.
* get rid of aux_optlstring
* get rid of unpack in mime.lua
* create socket.(sink|source).simplify
* break chain into a simpler binary chain and a complex (recursive) one.
* Create a passive mode option for the FTP (good for firewall).
* Modules should return their namespace table in the end of the chunk.
* get.lua precisa de ftp.get com url e sink
* conjunto associativo
* colocar um userdata com gc metamethod pra chamar sock_close (WSAClose);
* call select before accept, not after, dumbass!
* get rid of setnonblocking/setblocking in the bind function
* close has to block...
* fmt is not a good name
* change wrap() to accept a number and default to "character"
* move gethostname to dns table
* get rid of _cb in name of functions?
* trust character constants in mime.c? yup.
* smtp.lua needs stuff filter
* new option.c module to put all options (TCP and UDP share...)?
* add _tostring methods!
* change all modules to use the new namespace scheme
* write some utilities that use the code.lua module and put them
* in etc, modify the README.etc file and makefile.dist (eol.lua is done)

View File

@ -106,7 +106,10 @@ function getbyftp(url, file)
-- only print feedback if output is not stdout -- only print feedback if output is not stdout
-- and we don't know how big the file is -- and we don't know how big the file is
if file then save = ltn12.sink.chain(stats(), save) end if file then save = ltn12.sink.chain(stats(), save) end
local ret, err = socket.ftp.get {url = url, sink = save, type = "i"} local gett = socket.url.parse(url)
gett.sink = save
gett.type = "i"
local ret, err = socket.ftp.get(gett)
if err then print(err) end if err then print(err) end
end end

View File

@ -4,6 +4,7 @@
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id$
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
require("socket")
host = host or "*" host = host or "*"
port = port or 8080 port = port or 8080
if arg then if arg then
@ -11,18 +12,10 @@ if arg then
port = arg[2] or port port = arg[2] or port
end end
print("Binding to host '" ..host.. "' and port " ..port.. "...") print("Binding to host '" ..host.. "' and port " ..port.. "...")
s, e = socket.bind(host, port) s = socket.try(socket.bind(host, port))
if not s then i, p = socket.try(s:getsockname())
print(e)
exit()
end
i, p = s:getsockname()
print("Waiting connection from talker on " .. i .. ":" .. p .. "...") print("Waiting connection from talker on " .. i .. ":" .. p .. "...")
c, e = s:accept() c = socket.try(s:accept())
if not c then
print(e)
exit()
end
print("Connected. Here is the stuff:") print("Connected. Here is the stuff:")
l, e = c:receive() l, e = c:receive()
while not e do while not e do

View File

@ -4,6 +4,7 @@
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id$
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
require("socket")
host = host or "localhost" host = host or "localhost"
port = port or 8080 port = port or 8080
if arg then if arg then
@ -11,18 +12,10 @@ if arg then
port = arg[2] or port port = arg[2] or port
end end
print("Attempting connection to host '" ..host.. "' and port " ..port.. "...") print("Attempting connection to host '" ..host.. "' and port " ..port.. "...")
c, e = socket.connect(host, port) c = socket.try(socket.connect(host, port))
if not c then
print(e)
os.exit()
end
print("Connected! Please type stuff (empty line to stop):") print("Connected! Please type stuff (empty line to stop):")
l = io.read() l = io.read()
while l and l ~= "" and not e do while l and l ~= "" and not e do
t, e = c:send(l, "\n") socket.try(c:send(l, "\n"))
if e then
print(e)
os.exit()
end
l = io.read() l = io.read()
end end

View File

@ -4,6 +4,7 @@
-- Author: Diego Nehab -- Author: Diego Nehab
-- RCS ID: $Id$ -- RCS ID: $Id$
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
require("socket")
host = host or "*" host = host or "*"
port1 = port1 or 8080 port1 = port1 or 8080
port2 = port2 or 8181 port2 = port2 or 8181
@ -13,12 +14,10 @@ if arg then
port2 = arg[3] or port2 port2 = arg[3] or port2
end end
server1, error = socket.bind(host, port1) server1 = socket.try(socket.bind(host, port1))
assert(server1, error) server2 = socket.try(socket.bind(host, port2))
server1:settimeout(1) -- make sure we don't block in accept server1:settimeout(1) -- make sure we don't block in accept
server2, error = socket.bind(host, port2) server2:settimeout(1)
assert(server2, error)
server2:settimeout(1) -- make sure we don't block in accept
io.write("Servers bound\n") io.write("Servers bound\n")
@ -49,7 +48,7 @@ set:insert(server2)
while 1 do while 1 do
local readable, _, error = socket.select(set, nil) local readable, _, error = socket.select(set, nil)
for _, input in readable do for _, input in ipairs(readable) do
-- is it a server socket? -- is it a server socket?
if input == server1 or input == server2 then if input == server1 or input == server2 then
io.write("Waiting for clients\n") io.write("Waiting for clients\n")
@ -68,10 +67,12 @@ while 1 do
set:remove(input) set:remove(input)
else else
io.write("Broadcasting line '", line, "'\n") io.write("Broadcasting line '", line, "'\n")
__, writable, error = socket.select(nil, set, 1) writable, error = socket.skip(1, socket.select(nil, set, 1))
if not error then if not error then
for ___, output in writable do for __, output in ipairs(writable) do
output:send(line .. "\n") if output ~= input then
output:send(line .. "\n")
end
end end
else io.write("No client ready to receive!!!\n") end else io.write("No client ready to receive!!!\n") end
end end

View File

@ -13,6 +13,7 @@ local socket = _G[LUASOCKET_LIBNAME]
-- require other modules -- require other modules
require("ltn12") require("ltn12")
require("url") require("url")
require("tp")
-- create namespace inside LuaSocket namespace -- create namespace inside LuaSocket namespace
socket.ftp = socket.ftp or {} socket.ftp = socket.ftp or {}
@ -101,7 +102,9 @@ 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 or "stor", sendt.argument)) local argument = sendt.argument or string.gsub(sendt.path, "^/", "")
local command = sendt.command or "stor"
socket.try(self.tp:command(command, 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
@ -128,7 +131,9 @@ 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 or "retr", recvt.argument)) local argument = recvt.argument or string.gsub(recvt.path, "^/", "")
local command = recvt.command or "retr"
socket.try(self.tp:command(command, 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)
@ -200,8 +205,6 @@ local function parse(url)
putt.type = socket.skip(2, string.find(putt.params, pat)) putt.type = socket.skip(2, string.find(putt.params, pat))
socket.try(putt.type == "a" or putt.type == "i") socket.try(putt.type == "a" or putt.type == "i")
end end
-- skip first backslash in path
putt.argument = string.sub(putt.path, 2)
return putt return putt
end end

View File

@ -13,6 +13,8 @@ local socket = _G[LUASOCKET_LIBNAME]
-- require other modules -- require other modules
require("ltn12") require("ltn12")
require("mime") require("mime")
-- get MIME namespace
local mime = _G[MIME_LIBNAME]
require("url") require("url")
-- create namespace inside LuaSocket namespace -- create namespace inside LuaSocket namespace

View File

@ -25,11 +25,10 @@
\*=========================================================================*/ \*=========================================================================*/
#include "luasocket.h" #include "luasocket.h"
#include "base.h"
#include "auxiliar.h" #include "auxiliar.h"
#include "base.h"
#include "timeout.h" #include "timeout.h"
#include "buffer.h" #include "buffer.h"
#include "socket.h"
#include "inet.h" #include "inet.h"
#include "tcp.h" #include "tcp.h"
#include "udp.h" #include "udp.h"
@ -40,10 +39,10 @@
* Modules * Modules
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
static const luaL_reg mod[] = { static const luaL_reg mod[] = {
{"auxiliar", aux_open},
{"base", base_open}, {"base", base_open},
{"aux", aux_open}, {"timeout", tm_open},
{"tm", tm_open}, {"buffer", buf_open},
{"buf", buf_open},
{"inet", inet_open}, {"inet", inet_open},
{"tcp", tcp_open}, {"tcp", tcp_open},
{"udp", udp_open}, {"udp", udp_open},
@ -55,14 +54,8 @@ static const luaL_reg mod[] = {
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Initializes all library modules. * Initializes all library modules.
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
LUASOCKET_API int luaopen_socket(lua_State *L) LUASOCKET_API int luaopen_socket(lua_State *L) {
{
int i; int i;
if (!sock_open()) {
lua_pushnil(L);
lua_pushstring(L, "unable to initialize library");
return 2;
}
for (i = 0; mod[i].name; i++) for (i = 0; mod[i].name; i++)
mod[i].func(L); mod[i].func(L);
return 1; return 1;

View File

@ -82,8 +82,7 @@ int luaopen_mime(lua_State *L)
/* initialize lookup tables */ /* initialize lookup tables */
qpsetup(qpclass, qpunbase); qpsetup(qpclass, qpunbase);
b64setup(b64unbase); b64setup(b64unbase);
lua_pop(L, 1); return 1;
return 0;
} }
/*=========================================================================*\ /*=========================================================================*\

View File

@ -7,10 +7,10 @@
* To make the code as simple as possible, the select function is * To make the code as simple as possible, the select function is
* implemented int Lua, with a few helper functions written in C. * implemented int Lua, with a few helper functions written in C.
* *
* Each object that can be passed to the select function has to be in the * Each object that can be passed to the select function has to export two
* group select{able} and export two methods: fd() and dirty(). Fd returns * methods: fd() and dirty(). Fd returns the descriptor to be passed to the
* the descriptor to be passed to the select function. Dirty() should return * select function. Dirty() should return true if there is data ready for
* true if there is data ready for reading (required for buffered input). * reading (required for buffered input).
* *
* RCS ID: $Id$ * RCS ID: $Id$
\*=========================================================================*/ \*=========================================================================*/

View File

@ -6,11 +6,12 @@
-- RCS ID: $Id$ -- RCS ID: $Id$
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- make sure LuaSocket is loaded -- make sure LuaSocket is loaded
require"socket" require("socket")
-- get LuaSocket namespace -- get LuaSocket namespace
local socket = _G[LUASOCKET_LIBNAME] local socket = _G[LUASOCKET_LIBNAME]
require"ltn12" require("ltn12")
require("tp")
-- create smtp namespace inside LuaSocket namespace -- create smtp namespace inside LuaSocket namespace
local smtp = socket.smtp or {} local smtp = socket.smtp or {}

View File

@ -38,6 +38,7 @@ typedef struct sockaddr SA;
* interface to sockets * interface to sockets
\*=========================================================================*/ \*=========================================================================*/
int sock_open(void); int sock_open(void);
int sock_close(void);
void sock_destroy(p_sock ps); void sock_destroy(p_sock ps);
void sock_shutdown(p_sock ps, int how); void sock_shutdown(p_sock ps, int how);
int sock_send(p_sock ps, const char *data, size_t count, int sock_send(p_sock ps, const char *data, size_t count,

View File

@ -6,10 +6,10 @@
-- RCS ID: $Id$ -- RCS ID: $Id$
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- make sure LuaSocket is loaded -- make sure LuaSocket is loaded
if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end require("socket")
-- 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
-- create namespace inside LuaSocket namespace -- create namespace inside LuaSocket namespace
socket.tp = socket.tp or {} socket.tp = socket.tp or {}
-- make all module globals fall into namespace -- make all module globals fall into namespace
@ -35,6 +35,7 @@ local function get_reply(control)
-- reply ends with same code -- reply ends with same code
until code == current and sep == " " until code == current and sep == " "
end end
print(reply)
return code, reply return code, reply
end end
@ -58,6 +59,7 @@ function metat.__index:check(ok)
end end
function metat.__index:command(cmd, arg) function metat.__index:command(cmd, arg)
print(cmd, arg)
if arg then return self.control:send(cmd .. " " .. arg.. "\r\n") if arg then return self.control:send(cmd .. " " .. arg.. "\r\n")
else return self.control:send(cmd .. "\r\n") end else return self.control:send(cmd .. "\r\n") end
end end

View File

@ -9,10 +9,11 @@
require("socket") require("socket")
-- get LuaSocket namespace -- get LuaSocket namespace
local socket = _G[LUASOCKET_LIBNAME] local socket = _G[LUASOCKET_LIBNAME]
-- create url namespace inside LuaSocket namespace -- create url namespace inside LuaSocket namespace
local url = socket.url or {} local url = socket.url or {}
socket.url = url socket.url = url
-- make all module globals fall into smtp namespace -- make all module globals fall into url namespace
setmetatable(url, { __index = _G }) setmetatable(url, { __index = _G })
setfenv(1, url) setfenv(1, url)

View File

@ -42,6 +42,14 @@ int sock_open(void)
return 1; return 1;
} }
/*-------------------------------------------------------------------------*\
* Close module
\*-------------------------------------------------------------------------*/
int sock_close(void)
{
return 1;
}
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Close and inutilize socket * Close and inutilize socket
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/

View File

@ -37,6 +37,15 @@ int sock_open(void)
return 1; return 1;
} }
/*-------------------------------------------------------------------------*\
* Close module
\*-------------------------------------------------------------------------*/
int sock_close(void)
{
WSACleanup();
return 1;
}
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Select with int timeout in ms * Select with int timeout in ms
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/

View File

@ -8,10 +8,14 @@ local qptest = "qptest.bin"
local eqptest = "qptest.bin2" local eqptest = "qptest.bin2"
local dqptest = "qptest.bin3" local dqptest = "qptest.bin3"
local b64test = "luasocket" local b64test = "libluasocket.dylib"
local eb64test = "b64test.bin" local eb64test = "b64test.bin"
local db64test = "b64test.bin2" local db64test = "b64test.bin2"
-- make sure test file exists
local f = assert(io.open(b64test, "r"))
f:close()
-- from Machado de Assis, "A Mão e a Rosa" -- from Machado de Assis, "A Mão e a Rosa"
local mao = [[ local mao = [[
Cursavam estes dois moços a academia de S. Paulo, estando Cursavam estes dois moços a academia de S. Paulo, estando