mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-11-08 06:18:21 +01:00
Already compiling and running for Lua 5.0 (alpha)
This commit is contained in:
parent
b796207ce0
commit
d7e80592a6
20
src/http.lua
20
src/http.lua
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
111
src/mbox.lua
111
src/mbox.lua
@ -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
|
||||
|
15
src/select.c
15
src/select.c
@ -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;
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
12
src/udp.c
12
src/udp.c
@ -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);
|
||||
|
@ -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";
|
||||
|
@ -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);
|
||||
|
62
src/url.lua
62
src/url.lua
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user