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
* 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
ajeitar os README.*
ajeitar select. upvalue nao tem nada a ver...
make sure filter.chain fails gracefully.
ajeitar o manual sobre select, mais liberal agora
conjunto associativo
falar sobre encodet/wrapt/decodet no manual sobre mime
RECEIVE MUDOU!!! (partial stuff) COLOCAR NO MANUAL.
HTTP.lua mudou bastante também.
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
expose encode/decode tables to provide extensibility for mime module
use coroutines instead of fancy filters
@ -60,6 +20,7 @@ pop3???
add socket.TIMEOUT to be default timeout?
manual
compatibility: select sets are associative
add socket.connect and socket.bind to the manual
say what a nil callback does for http
check all occurences of it's
@ -87,24 +48,9 @@ tests
check for interrupts
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.
new option.c module to put all options (TCP and UDP share...)?
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
@ -150,3 +96,61 @@ Ajeitar o protocolo da luaopen_socket()... sei l
- unix 92 bytes maximo no endereço, incluindo o zero
- 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
-- and we don't know how big the file is
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
end

View File

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

View File

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

View File

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

View File

@ -13,6 +13,7 @@ local socket = _G[LUASOCKET_LIBNAME]
-- require other modules
require("ltn12")
require("url")
require("tp")
-- create namespace inside LuaSocket namespace
socket.ftp = socket.ftp or {}
@ -101,7 +102,9 @@ function metat.__index:send(sendt)
local data
socket.try(self.pasvt or self.portt, "need port or pasv first")
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.."})
if self.portt then data = socket.try(port(self.portt)) end
local step = sendt.step or ltn12.pump.step
@ -128,7 +131,9 @@ function metat.__index:receive(recvt)
local data
socket.try(self.pasvt or self.portt, "need port or pasv first")
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.."})
if self.portt then data = socket.try(port(self.portt)) end
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))
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

View File

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

View File

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

View File

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

View File

@ -7,10 +7,10 @@
* To make the code as simple as possible, the select function is
* 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
* group select{able} and export two methods: fd() and dirty(). Fd returns
* the descriptor to be passed to the select function. Dirty() should return
* true if there is data ready for reading (required for buffered input).
* Each object that can be passed to the select function has to export two
* methods: fd() and dirty(). Fd returns the descriptor to be passed to the
* select function. Dirty() should return true if there is data ready for
* reading (required for buffered input).
*
* RCS ID: $Id$
\*=========================================================================*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,10 +8,14 @@ local qptest = "qptest.bin"
local eqptest = "qptest.bin2"
local dqptest = "qptest.bin3"
local b64test = "luasocket"
local b64test = "libluasocket.dylib"
local eb64test = "b64test.bin"
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"
local mao = [[
Cursavam estes dois moços a academia de S. Paulo, estando