Already compiling and running for Lua 5.0 (alpha)

This commit is contained in:
Diego Nehab 2002-12-02 23:34:41 +00:00
parent b796207ce0
commit d7e80592a6
12 changed files with 164 additions and 101 deletions

View File

@ -32,7 +32,7 @@ Public.BLOCKSIZE = 8192
-----------------------------------------------------------------------------
function Private.try_receive(...)
local sock = arg[1]
local data, err = call(sock.receive, arg)
local data, err = sock.receive(unpack(arg))
if err then
sock:close()
return nil, err
@ -62,7 +62,7 @@ end
-----------------------------------------------------------------------------
function Private.get_statuscode(line)
local code, _
_, _, code = strfind(line, "HTTP/%d*%.%d* (%d%d%d)")
_, _, code = string.find(line, "HTTP/%d*%.%d* (%d%d%d)")
return tonumber(code)
end
@ -102,17 +102,17 @@ function Private.receive_headers(sock, headers)
-- headers go until a blank line is found
while line ~= "" do
-- get field-name and value
_,_, name, value = strfind(line, "^(.-):%s*(.*)")
_,_, name, value = string.find(line, "^(.-):%s*(.*)")
if not name or not value then
sock:close()
return nil, "malformed reponse headers"
end
name = strlower(name)
name = string.lower(name)
-- get next line (value might be folded)
line, err = Private.try_receive(sock)
if err then return nil, err end
-- unfold any folded values
while not err and strfind(line, "^%s") do
while not err and string.find(line, "^%s") do
value = value .. line
line, err = Private.try_receive(sock)
if err then return nil, err end
@ -142,7 +142,7 @@ function Private.receivebody_bychunks(sock, headers, receive_cb)
local go, uerr = receive_cb(nil, err)
return uerr or err
end
size = tonumber(gsub(line, ";.*", ""), 16)
size = tonumber(string.gsub(line, ";.*", ""), 16)
if not size then
err = "invalid chunk size"
sock:close()
@ -299,7 +299,7 @@ function Private.send_indirect(data, send_cb, chunk, size)
data:close()
return err
end
sent = sent + strlen(chunk)
sent = sent + string.len(chunk)
if sent >= size then break end
chunk, size = send_cb()
end
@ -391,7 +391,7 @@ function Private.fill_headers(headers, parsed)
lower["user-agent"] = Public.USERAGENT
-- override with user values
for i,v in headers do
lower[strlower(i)] = v
lower[string.lower(i)] = v
end
lower["host"] = parsed.host
-- this cannot be overriden
@ -554,7 +554,7 @@ function Public.request_cb(request, response)
request.headers = Private.fill_headers(request.headers, parsed)
-- try to connect to server
local sock
sock, response.error = connect(parsed.host, parsed.port)
sock, response.error = socket.connect(parsed.host, parsed.port)
if not sock then return response end
-- set connection timeout so that we do not hang forever
sock:timeout(Public.TIMEOUT)
@ -619,7 +619,7 @@ function Public.request(request)
local response = {}
if request.body then
request.body_cb = function()
return request.body, strlen(request.body)
return request.body, string.len(request.body)
end
end
local cat = Concat.create()

View File

@ -38,9 +38,9 @@ static int inet_aton(cchar *cp, struct in_addr *inp);
void inet_open(lua_State *L)
{
lua_pushcfunction(L, inet_lua_toip);
lua_setglobal(L, "toip");
priv_newglobal(L, "toip");
lua_pushcfunction(L, inet_lua_tohostname);
lua_setglobal(L, "tohostname");
priv_newglobal(L, "tohostname");
priv_newglobalmethod(L, "getsockname");
priv_newglobalmethod(L, "getpeername");
}
@ -145,7 +145,7 @@ static int inet_lua_getpeername(lua_State *L)
{
p_sock sock = (p_sock) lua_touserdata(L, 1);
struct sockaddr_in peer;
size_t peer_len = sizeof(peer);
int peer_len = sizeof(peer);
if (getpeername(sock->fd, (SA *) &peer, &peer_len) < 0) {
lua_pushnil(L);
return 1;
@ -167,7 +167,7 @@ static int inet_lua_getsockname(lua_State *L)
{
p_sock sock = (p_sock) lua_touserdata(L, 1);
struct sockaddr_in local;
size_t local_len = sizeof(local);
int local_len = sizeof(local);
if (getsockname(sock->fd, (SA *) &local, &local_len) < 0) {
lua_pushnil(L);
return 1;

View File

@ -56,5 +56,13 @@ LUASOCKET_API int lua_socketlibopen(lua_State *L)
buf_open(L);
tcps_open(L);
udp_open(L);
return 1;
#if LUASOCKET_DEBUG
lua_dofile(L, "concat.lua");
lua_dofile(L, "code.lua");
lua_dofile(L, "url.lua");
lua_dofile(L, "http.lua");
lua_dofile(L, "smtp.lua");
lua_dofile(L, "ftp.lua");
#endif
return 0;
}

View File

@ -11,7 +11,12 @@
/*-------------------------------------------------------------------------*\
* Current luasocket version
\*-------------------------------------------------------------------------*/
#define LUASOCKET_VERSION "LuaSocket 1.5"
#define LUASOCKET_VERSION "LuaSocket 1.5 (alpha)"
/*-------------------------------------------------------------------------*\
* Library's namespace
\*-------------------------------------------------------------------------*/
#define LUASOCKET_LIBNAME "socket"
/*-------------------------------------------------------------------------*\
* This macro prefixes all exported API functions

View File

@ -1,45 +1,88 @@
local Public = {}
parse = Public
mbox = Public
function Public.headers(headers_s)
local headers = {}
headers_s = "\n" .. headers_s .. "$$$:\n"
local i, j = 1, 1
local name, value, _
while 1 do
j = strfind(headers_s, "\n%S-:", i+1)
if not j then break end
_,_, name, value = strfind(strsub(headers_s, i+1, j-1), "(%S-):%s?(.*)")
value = gsub(value or "", "\r\n", "\n")
value = gsub(value, "\n%s*", " ")
name = strlower(name)
if headers[name] then headers[name] = headers[name] .. ", " .. value
else headers[name] = value end
i, j = j, i
function Public.split_message(message_s)
local message = {}
message_s = gsub(message_s, "\r\n", "\n")
gsub(message_s, "^(.-\n)\n", function (h) %message.headers = h end)
gsub(message_s, "^.-\n\n(.*)", function (b) %message.body = b end)
if not message.body then
gsub(message_s, "^\n(.*)", function (b) %message.body = b end)
end
headers["$$$"] = nil
if not message.headers and not message.body then
message.headers = message_s
end
return message.headers or "", message.body or ""
end
function Public.split_headers(headers_s)
local headers = {}
headers_s = gsub(headers_s, "\r\n", "\n")
headers_s = gsub(headers_s, "\n[ ]+", " ")
gsub("\n" .. headers_s, "\n([^\n]+)", function (h) tinsert(%headers, h) end)
return headers
end
function Public.message(message_s)
message_s = gsub(message_s, "^.-\n", "")
local _, headers_s, body
_, _, headers_s, body = strfind(message_s, "^(.-\n)\n(.*)")
headers_s = headers_s or ""
body = body or ""
return { headers = %Public.headers(headers_s), body = body }
function Public.parse_header(header_s)
header_s = gsub(header_s, "\n[ ]+", " ")
header_s = gsub(header_s, "\n+", "")
local _, __, name, value = strfind(header_s, "([^%s:]-):%s*(.*)")
return name, value
end
function Public.mbox(mbox_s)
local mbox = {}
mbox_s = "\n" .. mbox_s .. "\nFrom "
local i, j = 1, 1
while 1 do
j = strfind(mbox_s, "\nFrom ", i + 1)
if not j then break end
tinsert(mbox, %Public.message(strsub(mbox_s, i + 1, j - 1)))
i, j = j, i
function Public.parse_headers(headers_s)
local headers_t = %Public.split_headers(headers_s)
local headers = {}
for i = 1, getn(headers_t) do
local name, value = %Public.parse_header(headers_t[i])
if name then
name = strlower(name)
if headers[name] then
headers[name] = headers[name] .. ", " .. value
else headers[name] = value end
end
end
return mbox
return headers
end
function Public.parse_from(from)
local _, __, name, address = strfind(from, "^%s*(.-)%s*%<(.-)%>")
if not address then
_, __, address = strfind(from, "%s*(.+)%s*")
end
name = name or ""
address = address or ""
if name == "" then name = address end
name = gsub(name, '"', "")
return name, address
end
function Public.split_mbox(mbox_s)
mbox = {}
mbox_s = gsub(mbox_s, "\r\n", "\n") .."\n\nFrom \n"
local nj, i, j = 1, 1, 1
while 1 do
i, nj = strfind(mbox_s, "\n\nFrom .-\n", j)
if not i then break end
local message = strsub(mbox_s, j, i-1)
tinsert(mbox, message)
j = nj+1
end
return mbox
end
function Public.parse_mbox(mbox_s)
local mbox = %Public.split_mbox(mbox_s)
for i = 1, getn(mbox) do
mbox[i] = %Public.parse_message(mbox[i])
end
return mbox
end
function Public.parse_message(message_s)
local message = {}
message.headers, message.body = %Public.split_message(message_s)
message.headers = %Public.parse_headers(message.headers)
return message
end

View File

@ -31,9 +31,12 @@ void select_open(lua_State *L)
{
/* push select auxiliar lua function and register
* select_lua_select with it as an upvalue */
#include "lsselect.loh"
#ifdef LUASOCKET_DEBUG
#endif
luaL_loadfile(L, "lsselect.lua");
lua_call(L, 0, 1);
lua_pushcclosure(L, select_lua_select, 1);
lua_setglobal(L, "select");
priv_newglobal(L, "select");
/* create luasocket(select) table */
lua_pushstring(L, "luasocket(select)");
lua_newtable(L);
@ -61,8 +64,8 @@ static int select_lua_select(lua_State *L)
/* make sure we have enough arguments (nil is the default) */
lua_settop(L, 4);
/* pass FD_SET and manipulation functions */
lua_newuserdatabox(L, &read);
lua_newuserdatabox(L, &write);
lua_boxpointer(L, &read);
lua_boxpointer(L, &write);
lua_pushcfunction(L, local_FD_SET);
lua_pushcfunction(L, local_FD_ISSET);
/* pass getfd function with selectable table as upvalue */
@ -121,7 +124,7 @@ static int local_select(lua_State *L)
static int local_FD_SET(lua_State *L)
{
COMPAT_FD fd = (COMPAT_FD) lua_tonumber(L, 1);
fd_set *set = (fd_set *) lua_touserdata(L, 2);
fd_set *set = (fd_set *) lua_topointer(L, 2);
if (fd >= 0) FD_SET(fd, set);
return 0;
}
@ -129,7 +132,7 @@ static int local_FD_SET(lua_State *L)
static int local_FD_ISSET(lua_State *L)
{
COMPAT_FD fd = (COMPAT_FD) lua_tonumber(L, 1);
fd_set *set = (fd_set *) lua_touserdata(L, 2);
fd_set *set = (fd_set *) lua_topointer(L, 2);
if (fd >= 0 && FD_ISSET(fd, set)) lua_pushnumber(L, 1);
else lua_pushnil(L);
return 1;

View File

@ -19,7 +19,7 @@ Public.TIMEOUT = 180
Public.PORT = 25
-- domain used in HELO command and default sendmail
-- If we are under a CGI, try to get from environment
Public.DOMAIN = getenv("SERVER_NAME") or "localhost"
Public.DOMAIN = os.getenv("SERVER_NAME") or "localhost"
-- default server used to send e-mails
Public.SERVER = "localhost"

View File

@ -125,9 +125,9 @@ void tm_open(lua_State *L)
(void) L;
#ifdef _DEBUG
lua_pushcfunction(L, tm_lua_time);
lua_setglobal(L, "_time");
priv_newglobal(L, "_time");
lua_pushcfunction(L, tm_lua_sleep);
lua_setglobal(L, "_sleep");
priv_newglobal(L, "_sleep");
#endif
}

View File

@ -45,7 +45,7 @@ void udp_open(lua_State *L)
udp_inherit(L, UDP_CLASS);
/* declare global functions */
lua_pushcfunction(L, udp_global_udpsocket);
lua_setglobal(L, "udpsocket");
priv_newglobal(L, "udp");
for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++)
priv_newglobalmethod(L, funcs[i].name);
/* make class selectable */
@ -162,12 +162,12 @@ static int udp_lua_receivefrom(lua_State *L)
p_udp udp = (p_udp) lua_touserdata(L, 1);
p_tm tm = &udp->base_tm;
struct sockaddr_in peer;
size_t peer_len = sizeof(peer);
int peer_len = sizeof(peer);
unsigned char buffer[UDP_DATAGRAMSIZE];
size_t wanted = (size_t) luaL_opt_number(L, 2, sizeof(buffer));
size_t got;
int err;
if (udp->udp_connected) lua_error(L, "receivefrom on connected socket");
if (udp->udp_connected) luaL_error(L, "receivefrom on connected socket");
tm_markstart(tm);
wanted = MIN(wanted, sizeof(buffer));
err = compat_recvfrom(udp->fd, buffer, wanted, &got, tm_getremaining(tm),
@ -201,7 +201,7 @@ static int udp_lua_send(lua_State *L)
size_t wanted, sent = 0;
int err;
cchar *data = luaL_check_lstr(L, 2, &wanted);
if (!udp->udp_connected) lua_error(L, "send on unconnected socket");
if (!udp->udp_connected) luaL_error(L, "send on unconnected socket");
tm_markstart(tm);
err = compat_send(udp->fd, data, wanted, &sent, tm_getremaining(tm));
priv_pusherror(L, err == PRIV_CLOSED ? PRIV_REFUSED : err);
@ -230,9 +230,9 @@ static int udp_lua_sendto(lua_State *L)
p_tm tm = &udp->base_tm;
struct sockaddr_in peer;
int err;
if (udp->udp_connected) lua_error(L, "sendto on connected socket");
if (udp->udp_connected) luaL_error(L, "sendto on connected socket");
memset(&peer, 0, sizeof(peer));
if (!inet_aton(ip, &peer.sin_addr)) lua_error(L, "invalid ip address");
if (!inet_aton(ip, &peer.sin_addr)) luaL_error(L, "invalid ip address");
peer.sin_family = AF_INET;
peer.sin_port = htons(port);
tm_markstart(tm);

View File

@ -28,7 +28,7 @@ void compat_open(lua_State *L)
}
COMPAT_FD compat_accept(COMPAT_FD s, struct sockaddr *addr,
socklen_t *len, int deadline)
int *len, int deadline)
{
struct timeval tv;
fd_set fds;
@ -74,7 +74,7 @@ int compat_send(COMPAT_FD c, cchar *data, size_t count, size_t *sent,
}
int compat_sendto(COMPAT_FD c, cchar *data, size_t count, size_t *sent,
int deadline, SA *addr, socklen_t len)
int deadline, SA *addr, int len)
{
struct timeval tv;
fd_set fds;
@ -134,7 +134,7 @@ int compat_recv(COMPAT_FD c, uchar *data, size_t count, size_t *got,
}
int compat_recvfrom(COMPAT_FD c, uchar *data, size_t count, size_t *got,
int deadline, SA *addr, socklen_t *len)
int deadline, SA *addr, int *len)
{
struct timeval tv;
fd_set fds;
@ -290,7 +290,7 @@ cchar *compat_trysetoptions(lua_State *L, COMPAT_FD sock)
static cchar *try_setbooloption(lua_State *L, COMPAT_FD sock, int name)
{
int bool, res;
if (!lua_isnumber(L, -1)) lua_error(L, "invalid option value");
if (!lua_isnumber(L, -1)) luaL_error(L, "invalid option value");
bool = (int) lua_tonumber(L, -1);
res = setsockopt(sock, SOL_SOCKET, name, (char *) &bool, sizeof(bool));
if (res < 0) return "error setting option";

View File

@ -46,15 +46,15 @@ void compat_open(lua_State *L);
#define compat_select select
COMPAT_FD compat_socket(int domain, int type, int protocol);
COMPAT_FD compat_accept(COMPAT_FD s, SA *addr, socklen_t *len, int deadline);
COMPAT_FD compat_accept(COMPAT_FD s, SA *addr, int *len, int deadline);
int compat_send(COMPAT_FD c, cchar *data, size_t count, size_t *done,
int deadline);
int compat_recv(COMPAT_FD c, uchar *data, size_t count, size_t *done,
int deadline);
int compat_sendto(COMPAT_FD c, cchar *data, size_t count, size_t *done,
int deadline, SA *addr, socklen_t len);
int deadline, SA *addr, int len);
int compat_recvfrom(COMPAT_FD c, uchar *data, size_t count, size_t *got,
int deadline, SA *addr, socklen_t *len);
int deadline, SA *addr, int *len);
void compat_setnonblocking(COMPAT_FD sock);
void compat_setblocking(COMPAT_FD sock);
void compat_setreuseaddr(COMPAT_FD sock);

View File

@ -34,26 +34,30 @@ function Public.parse_url(url, default)
-- empty url is parsed to nil
if not url or url == "" then return nil end
-- remove whitespace
url = gsub(url, "%s", "")
url = string.gsub(url, "%s", "")
-- get fragment
url = gsub(url, "#(.*)$", function(f) parsed.fragment = f end)
url = string.gsub(url, "#(.*)$", function(f) parsed.fragment = f end)
-- get scheme
url = gsub(url, "^([%w][%w%+%-%.]*)%:", function(s) parsed.scheme = s end)
url = string.gsub(url, "^([%w][%w%+%-%.]*)%:",
function(s) parsed.scheme = s end)
-- get authority
url = gsub(url, "^//([^/]*)", function(n) parsed.authority = n end)
-- get query string
url = gsub(url, "%?(.*)", function(q) parsed.query = q end)
url = string.gsub(url, "^//([^/]*)", function(n) parsed.authority = n end)
-- get query stringing
url = string.gsub(url, "%?(.*)", function(q) parsed.query = q end)
-- get params
url = gsub(url, "%;(.*)", function(p) parsed.params = p end)
url = string.gsub(url, "%;(.*)", function(p) parsed.params = p end)
if url ~= "" then parsed.path = url end
local authority = parsed.authority
if not authority then return parsed end
authority = gsub(authority,"^([^@]*)@",function(u) parsed.userinfo = u end)
authority = gsub(authority, ":([^:]*)$", function(p) parsed.port = p end)
authority = string.gsub(authority,"^([^@]*)@",
function(u) parsed.userinfo = u end)
authority = string.gsub(authority, ":([^:]*)$",
function(p) parsed.port = p end)
if authority ~= "" then parsed.host = authority end
local userinfo = parsed.userinfo
if not userinfo then return parsed end
userinfo = gsub(userinfo, ":([^:]*)$", function(p) parsed.password = p end)
userinfo = string.gsub(userinfo, ":([^:]*)$",
function(p) parsed.password = p end)
parsed.user = userinfo
return parsed
end
@ -64,7 +68,7 @@ end
-- Input
-- parsed: parsed URL, as returned by Public.parse
-- Returns
-- a string with the corresponding URL
-- a stringing with the corresponding URL
-----------------------------------------------------------------------------
function Public.build_url(parsed)
local url = parsed.path or ""
@ -86,7 +90,7 @@ function Public.build_url(parsed)
if authority then url = "//" .. authority .. url end
if parsed.scheme then url = parsed.scheme .. ":" .. url end
if parsed.fragment then url = url .. "#" .. parsed.fragment end
url = gsub(url, "%s", "")
url = string.gsub(url, "%s", "")
return url
end
@ -134,13 +138,13 @@ end
function Public.parse_path(path)
local parsed = {}
path = path or ""
path = gsub(path, "%s", "")
gsub(path, "([^/]+)", function (s) tinsert(parsed, s) end)
for i = 1, getn(parsed) do
path = string.gsub(path, "%s", "")
string.gsub(path, "([^/]+)", function (s) table.insert(parsed, s) end)
for i = 1, table.getn(parsed) do
parsed[i] = Code.unescape(parsed[i])
end
if strsub(path, 1, 1) == "/" then parsed.is_absolute = 1 end
if strsub(path, -1, -1) == "/" then parsed.is_directory = 1 end
if stringsub(path, 1, 1) == "/" then parsed.is_absolute = 1 end
if stringsub(path, -1, -1) == "/" then parsed.is_directory = 1 end
return parsed
end
@ -150,11 +154,11 @@ end
-- parsed: path segments
-- unsafe: if true, segments are not protected before path is built
-- Returns
-- path: correspondin path string
-- path: correspondin path stringing
-----------------------------------------------------------------------------
function Public.build_path(parsed, unsafe)
local path = ""
local n = getn(parsed)
local n = table.getn(parsed)
if unsafe then
for i = 1, n-1 do
path = path .. parsed[i]
@ -178,10 +182,10 @@ function Public.build_path(parsed, unsafe)
return path
end
function Private.make_set(table)
function Private.make_set(t)
local s = {}
for i = 1, getn(table) do
s[table[i]] = 1
for i = 1, table.getn(t) do
s[t[i]] = 1
end
return s
end
@ -195,7 +199,7 @@ Private.segment_set = Private.make_set {
function Private.protect_segment(s)
local segment_set = Private.segment_set
return gsub(s, "(%W)", function (c)
return string.gsub(s, "(%W)", function (c)
if segment_set[c] then return c
else return Code.escape(c) end
end)
@ -210,21 +214,21 @@ end
-- corresponding absolute path
-----------------------------------------------------------------------------
function Private.absolute_path(base_path, relative_path)
if strsub(relative_path, 1, 1) == "/" then return relative_path end
local path = gsub(base_path, "[^/]*$", "")
if stringsub(relative_path, 1, 1) == "/" then return relative_path end
local path = string.gsub(base_path, "[^/]*$", "")
path = path .. relative_path
path = gsub(path, "([^/]*%./)", function (s)
path = string.gsub(path, "([^/]*%./)", function (s)
if s ~= "./" then return s else return "" end
end)
path = gsub(path, "/%.$", "/")
path = string.gsub(path, "/%.$", "/")
local reduced
while reduced ~= path do
reduced = path
path = gsub(reduced, "([^/]*/%.%./)", function (s)
path = string.gsub(reduced, "([^/]*/%.%./)", function (s)
if s ~= "../../" then return "" else return s end
end)
end
path = gsub(reduced, "([^/]*/%.%.)$", function (s)
path = string.gsub(reduced, "([^/]*/%.%.)$", function (s)
if s ~= "../.." then return "" else return s end
end)
return path