Few tweaks in installation, some missing files, etc.

This commit is contained in:
Diego Nehab 2005-11-22 08:33:29 +00:00
parent a2b780bf7a
commit d55a5826e8
26 changed files with 232 additions and 238 deletions

View file

@ -40,7 +40,7 @@ function open(server, port, create)
local f = base.setmetatable({ tp = tp }, metat)
-- make sure everything gets closed in an exception
f.try = socket.newtry(function() f:close() end)
return f
return f
end
function metat.__index:portconnect()
@ -71,20 +71,20 @@ function metat.__index:pasv()
local pattern = "(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
local a, b, c, d, p1, p2 = socket.skip(2, string.find(reply, pattern))
self.try(a and b and c and d and p1 and p2, reply)
self.pasvt = {
ip = string.format("%d.%d.%d.%d", a, b, c, d),
self.pasvt = {
ip = string.format("%d.%d.%d.%d", a, b, c, d),
port = p1*256 + p2
}
if self.server then
if self.server then
self.server:close()
self.server = nil
end
return self.pasvt.ip, self.pasvt.port
return self.pasvt.ip, self.pasvt.port
end
function metat.__index:port(ip, port)
self.pasvt = nil
if not ip then
if not ip then
ip, port = self.try(self.tp:getcontrol():getsockname())
self.server = self.try(socket.bind(ip, 0))
ip, port = self.try(self.server:getsockname())
@ -100,11 +100,11 @@ end
function metat.__index:send(sendt)
self.try(self.pasvt or self.server, "need port or pasv first")
-- if there is a pasvt table, we already sent a PASV command
-- if there is a pasvt table, we already sent a PASV command
-- we just get the data connection into self.data
if self.pasvt then self:pasvconnect() end
-- get the transfer argument and command
local argument = sendt.argument or
-- get the transfer argument and command
local argument = sendt.argument or
url.unescape(string.gsub(sendt.path or "", "^[/\\]", ""))
if argument == "" then argument = nil end
local command = sendt.command or "stor"
@ -137,7 +137,7 @@ end
function metat.__index:receive(recvt)
self.try(self.pasvt or self.server, "need port or pasv first")
if self.pasvt then self:pasvconnect() end
local argument = recvt.argument or
local argument = recvt.argument or
url.unescape(string.gsub(recvt.path or "", "^[/\\]", ""))
if argument == "" then argument = nil end
local command = recvt.command or "retr"
@ -220,7 +220,7 @@ local function parse(u)
socket.try(t.scheme == "ftp", "wrong scheme '" .. t.scheme .. "'")
socket.try(t.host, "missing hostname")
local pat = "^type=(.)$"
if t.params then
if t.params then
t.type = socket.skip(2, string.find(t.params, pat))
socket.try(t.type == "a" or t.type == "i",
"invalid type '" .. t.type .. "'")
@ -229,7 +229,7 @@ local function parse(u)
end
local function sput(u, body)
local putt = parse(u)
local putt = parse(u)
putt.source = ltn12.source.string(body)
return tput(putt)
end
@ -253,7 +253,7 @@ local function tget(gett)
end
local function sget(u)
local gett = parse(u)
local gett = parse(u)
local t = {}
gett.sink = ltn12.sink.table(t)
tget(gett)

View file

@ -21,7 +21,7 @@ module("socket.http")
-- Program constants
-----------------------------------------------------------------------------
-- connection timeout in seconds
TIMEOUT = 60
TIMEOUT = 60
-- default port for document retrieval
PORT = 80
-- user agent field sent in request
@ -65,18 +65,18 @@ socket.sourcet["http-chunked"] = function(sock, headers)
return base.setmetatable({
getfd = function() return sock:getfd() end,
dirty = function() return sock:dirty() end
}, {
}, {
__call = function()
-- get chunk size, skip extention
local line, err = sock:receive()
if err then return nil, err end
if err then return nil, err end
local size = base.tonumber(string.gsub(line, ";.*", ""), 16)
if not size then return nil, "invalid chunk size" end
-- was it the last chunk?
if size > 0 then
if size > 0 then
-- if not, get chunk and skip terminating CRLF
local chunk, err, part = sock:receive(size)
if chunk then sock:receive() end
if chunk then sock:receive() end
return chunk, err
else
-- if it was, read trailers into headers table
@ -91,7 +91,7 @@ socket.sinkt["http-chunked"] = function(sock)
return base.setmetatable({
getfd = function() return sock:getfd() end,
dirty = function() return sock:dirty() end
}, {
}, {
__call = function(self, chunk, err)
if not chunk then return sock:send("0\r\n\r\n") end
local size = string.format("%X\r\n", string.len(chunk))
@ -115,11 +115,11 @@ function open(host, port, create)
h.try(c:settimeout(TIMEOUT))
h.try(c:connect(host, port or PORT))
-- here everything worked
return h
return h
end
function metat.__index:sendrequestline(method, uri)
local reqline = string.format("%s %s HTTP/1.1\r\n", method or "GET", uri)
local reqline = string.format("%s %s HTTP/1.1\r\n", method or "GET", uri)
return self.try(self.c:send(reqline))
end
@ -133,7 +133,7 @@ function metat.__index:sendheaders(headers)
end
function metat.__index:sendbody(headers, source, step)
source = source or ltn12.source.empty()
source = source or ltn12.source.empty()
step = step or ltn12.pump.step
-- if we don't know the size in advance, send chunked and hope for the best
local mode = "http-chunked"
@ -159,7 +159,7 @@ function metat.__index:receivebody(headers, sink, step)
local mode = "default" -- connection close
if t and t ~= "identity" then mode = "http-chunked"
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))
end
@ -185,7 +185,7 @@ local function adjusturi(reqt)
end
local function adjustproxy(reqt)
local proxy = reqt.proxy or PROXY
local proxy = reqt.proxy or PROXY
if proxy then
proxy = url.parse(proxy)
return proxy.host, proxy.port or 3128
@ -292,10 +292,10 @@ function trequest(reqt)
local code, headers, status
code, status = h:receivestatusline()
headers = h:receiveheaders()
if shouldredirect(reqt, code, headers) then
if shouldredirect(reqt, code, headers) then
h:close()
return tredirect(reqt, headers.location)
elseif shouldauthorize(reqt, code) then
elseif shouldauthorize(reqt, code) then
h:close()
return tauthorize(reqt)
elseif shouldreceivebody(reqt, code) then
@ -307,12 +307,12 @@ end
local function srequest(u, body)
local t = {}
local reqt = {
local reqt = {
url = u,
sink = ltn12.sink.table(t)
}
if body then
reqt.source = ltn12.source.string(body)
if body then
reqt.source = ltn12.source.string(body)
reqt.headers = { ["content-length"] = string.len(body) }
reqt.method = "POST"
end

View file

@ -36,19 +36,19 @@ end
-- chains a bunch of filters together
-- (thanks to Wim Couwenberg)
function filter.chain(...)
function filter.chain(...)
local n = table.getn(arg)
local top, index = 1, 1
local retry = ""
return function(chunk)
retry = chunk and retry
while true do
while true do
if index == top then
chunk = arg[index](chunk)
if chunk == "" or top == n then return chunk
elseif chunk then index = index + 1
else
top = top+1
else
top = top+1
index = top
end
else
@ -148,9 +148,9 @@ function source.chain(src, f)
last_in, err = src()
if err then return nil, err end
last_out = f(last_in)
if not last_out then
if not last_out then
if last_in then
base.error('filter returned inappropriate nil')
base.error('filter returned inappropriate nil')
else
return nil
end
@ -159,17 +159,17 @@ function source.chain(src, f)
if last_in then last_in = "" end
return last_out
end
else
else
last_out = f(last_in)
if last_out == "" then
if last_in == "" then
if last_out == "" then
if last_in == "" then
state = "feeding"
else
base.error('filter returned ""')
base.error('filter returned ""')
end
elseif not last_out then
if last_in then
base.error('filter returned inappropriate nil')
if last_in then
base.error('filter returned inappropriate nil')
else
return nil
end
@ -224,7 +224,7 @@ end
function sink.file(handle, io_err)
if handle then
return function(chunk, err)
if not chunk then
if not chunk then
handle:close()
return 1
else return handle:write(chunk) end
@ -248,7 +248,7 @@ function sink.error(err)
end
end
-- chains a sink with a filter
-- chains a sink with a filter
function sink.chain(f, snk)
base.assert(f and snk)
return function(chunk, err)
@ -282,7 +282,7 @@ function pump.all(src, snk, step)
step = step or pump.step
while true do
local ret, err = step(src, snk)
if not ret then
if not ret then
if err then return nil, err
else return 1 end
end

View file

@ -10,7 +10,7 @@ function Public.split_message(message_s)
if not message.body then
string.gsub(message_s, "^\n(.*)", function (b) message.body = b end)
end
if not message.headers and not message.body then
if not message.headers and not message.body then
message.headers = message_s
end
return message.headers or "", message.body or ""

View file

@ -20,10 +20,10 @@ encodet = {}
decodet = {}
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)
return function(name, opt1, opt2)
if base.type(name) ~= "string" then
if base.type(name) ~= "string" then
name, opt1, opt2 = "default", name, opt1
end
local f = table[name or "nil"]
@ -38,7 +38,7 @@ encodet['base64'] = function()
end
encodet['quoted-printable'] = function(mode)
return ltn12.filter.cycle(qp, "",
return ltn12.filter.cycle(qp, "",
(mode == "binary") and "=0D=0A" or "\r\n")
end
@ -56,22 +56,22 @@ local function format(chunk)
if chunk == "" then return "''"
else return string.len(chunk) end
else return "nil" end
end
end
-- define the line-wrap filters
wrapt['text'] = function(length)
length = length or 76
return ltn12.filter.cycle(wrp, length, length)
return ltn12.filter.cycle(wrp, length, length)
end
wrapt['base64'] = wrapt['text']
wrapt['default'] = wrapt['text']
wrapt['quoted-printable'] = function()
return ltn12.filter.cycle(qpwrp, 76, 76)
return ltn12.filter.cycle(qpwrp, 76, 76)
end
-- function that choose the encoding, decoding or wrap algorithm
encode = choose(encodet)
encode = choose(encodet)
decode = choose(decodet)
wrap = choose(wrapt)

View file

@ -27,8 +27,8 @@ TIMEOUT = 60
-- default server used to send e-mails
SERVER = "localhost"
-- default port
PORT = 25
-- domain used in HELO command and default sendmail
PORT = 25
-- domain used in HELO command and default sendmail
-- If we are under a CGI, try to get from environment
DOMAIN = os.getenv("SERVER_NAME") or "localhost"
-- default time zone (means we don't know)
@ -43,12 +43,12 @@ function metat.__index:greet(domain)
self.try(self.tp:check("2.."))
self.try(self.tp:command("EHLO", domain or DOMAIN))
return socket.skip(1, self.try(self.tp:check("2..")))
end
end
function metat.__index:mail(from)
self.try(self.tp:command("MAIL", "FROM:" .. from))
return self.try(self.tp:check("2.."))
end
end
function metat.__index:rcpt(to)
self.try(self.tp:command("RCPT", "TO:" .. to))
@ -99,7 +99,7 @@ function metat.__index:auth(user, password, ext)
end
-- send message or throw an exception
function metat.__index:send(mailt)
function metat.__index:send(mailt)
self:mail(mailt.from)
if base.type(mailt.rcpt) == "table" then
for i,v in base.ipairs(mailt.rcpt) do
@ -112,14 +112,14 @@ function metat.__index:send(mailt)
end
function open(server, port, create)
local tp = socket.try(tp.connect(server or SERVER, port or PORT,
local tp = socket.try(tp.connect(server or SERVER, port or PORT,
create, TIMEOUT))
local s = base.setmetatable({tp = tp}, metat)
-- make sure tp is closed if we get an exception
s.try = socket.newtry(function()
s.try = socket.newtry(function()
s:close()
end)
return s
return s
end
---------------------------------------------------------------------------
@ -142,7 +142,7 @@ local function send_headers(headers)
for i,v in base.pairs(headers) do
h = i .. ': ' .. v .. "\r\n" .. h
end
coroutine.yield(h)
coroutine.yield(h)
end
-- yield multipart message body from a multipart message table
@ -151,25 +151,25 @@ local function send_multipart(mesgt)
local bd = newboundary()
local headers = mesgt.headers or {}
headers['content-type'] = headers['content-type'] or 'multipart/mixed'
headers['content-type'] = headers['content-type'] ..
headers['content-type'] = headers['content-type'] ..
'; boundary="' .. bd .. '"'
send_headers(headers)
-- send preamble
if mesgt.body.preamble then
coroutine.yield(mesgt.body.preamble)
coroutine.yield("\r\n")
if mesgt.body.preamble then
coroutine.yield(mesgt.body.preamble)
coroutine.yield("\r\n")
end
-- send each part separated by a boundary
for i, m in base.ipairs(mesgt.body) do
coroutine.yield("\r\n--" .. bd .. "\r\n")
send_message(m)
end
-- send last boundary
-- send last boundary
coroutine.yield("\r\n--" .. bd .. "--\r\n\r\n")
-- send epilogue
if mesgt.body.epilogue then
coroutine.yield(mesgt.body.epilogue)
coroutine.yield("\r\n")
if mesgt.body.epilogue then
coroutine.yield(mesgt.body.epilogue)
coroutine.yield("\r\n")
end
end
@ -181,7 +181,7 @@ local function send_source(mesgt)
'text/plain; charset="iso-8859-1"'
send_headers(headers)
-- send body from source
while true do
while true do
local chunk, err = mesgt.body()
if err then coroutine.yield(nil, err)
elseif chunk then coroutine.yield(chunk)
@ -213,11 +213,11 @@ local function adjust_headers(mesgt)
for i,v in base.pairs(mesgt.headers or lower) do
lower[string.lower(i)] = v
end
lower["date"] = lower["date"] or
lower["date"] = lower["date"] or
os.date("!%a, %d %b %Y %H:%M:%S ") .. (mesgt.zone or ZONE)
lower["x-mailer"] = lower["x-mailer"] or socket._VERSION
-- this can't be overriden
lower["mime-version"] = "1.0"
lower["mime-version"] = "1.0"
mesgt.headers = lower
end
@ -225,7 +225,7 @@ function message(mesgt)
adjust_headers(mesgt)
-- create and return message source
local co = coroutine.create(function() send_message(mesgt) end)
return function()
return function()
local ret, a, b = coroutine.resume(co)
if ret then return a, b
else return nil, a end

View file

@ -19,7 +19,7 @@ module("socket")
function connect(address, port, laddress, lport)
local sock, err = socket.tcp()
if not sock then return nil, err end
if laddress then
if laddress then
local res, err = sock:bind(laddress, lport, -1)
if not res then return nil, err end
end
@ -65,9 +65,9 @@ sinkt["close-when-done"] = function(sock)
return base.setmetatable({
getfd = function() return sock:getfd() end,
dirty = function() return sock:dirty() end
}, {
}, {
__call = function(self, chunk, err)
if not chunk then
if not chunk then
sock:close()
return 1
else return sock:send(chunk) end
@ -79,7 +79,7 @@ sinkt["keep-open"] = function(sock)
return base.setmetatable({
getfd = function() return sock:getfd() end,
dirty = function() return sock:dirty() end
}, {
}, {
__call = function(self, chunk, err)
if chunk then return sock:send(chunk)
else return 1 end
@ -95,7 +95,7 @@ sourcet["by-length"] = function(sock, length)
return base.setmetatable({
getfd = function() return sock:getfd() end,
dirty = function() return sock:dirty() end
}, {
}, {
__call = function()
if length <= 0 then return nil end
local size = math.min(socket.BLOCKSIZE, length)
@ -112,16 +112,16 @@ sourcet["until-closed"] = function(sock)
return base.setmetatable({
getfd = function() return sock:getfd() end,
dirty = function() return sock:dirty() end
}, {
}, {
__call = function()
if done then return nil end
local chunk, err, partial = sock:receive(socket.BLOCKSIZE)
if not err then return chunk
elseif err == "closed" then
elseif err == "closed" then
sock:close()
done = 1
return partial
else return nil, err end
else return nil, err end
end
})
end

View file

@ -37,7 +37,7 @@ local function get_reply(c)
current, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
reply = reply .. "\n" .. line
-- reply ends with same code
until code == current and sep == " "
until code == current and sep == " "
end
return code, reply
end
@ -49,25 +49,25 @@ function metat.__index:check(ok)
local code, reply = get_reply(self.c)
if not code then return nil, reply end
if base.type(ok) ~= "function" then
if base.type(ok) == "table" then
if base.type(ok) == "table" then
for i, v in base.ipairs(ok) do
if string.find(code, v) then
return base.tonumber(code), reply
if string.find(code, v) then
return base.tonumber(code), reply
end
end
return nil, reply
else
if string.find(code, ok) then return base.tonumber(code), reply
if string.find(code, ok) then return base.tonumber(code), reply
else return nil, reply end
end
else return ok(base.tonumber(code), reply) end
end
function metat.__index:command(cmd, arg)
if arg then
if arg then
return self.c:send(cmd .. " " .. arg.. "\r\n")
else
return self.c:send(cmd .. "\r\n")
else
return self.c:send(cmd .. "\r\n")
end
end
@ -114,8 +114,8 @@ function connect(host, port, create, timeout)
if not c then return nil, e end
c:settimeout(timeout or TIMEOUT)
local r, e = c:connect(host, port)
if not r then
c:close()
if not r then
c:close()
return nil, e
end
return base.setmetatable({c = c}, metat)

View file

@ -20,7 +20,7 @@ _VERSION = "URL 1.0"
-----------------------------------------------------------------------------
-- Encodes a string into its escaped hexadecimal representation
-- Input
-- Input
-- s: binary string to be encoded
-- Returns
-- escaped representation of string binary
@ -33,8 +33,8 @@ end
-----------------------------------------------------------------------------
-- Protects a path segment, to prevent it from interfering with the
-- url parsing.
-- Input
-- url parsing.
-- Input
-- s: binary string to be encoded
-- Returns
-- escaped representation of string binary
@ -50,12 +50,12 @@ end
-- these are allowed withing a path segment, along with alphanum
-- other characters must be escaped
local segment_set = make_set {
"-", "_", ".", "!", "~", "*", "'", "(",
"-", "_", ".", "!", "~", "*", "'", "(",
")", ":", "@", "&", "=", "+", "$", ",",
}
local function protect_segment(s)
return string.gsub(s, "([^A-Za-z0-9_])", function (c)
return string.gsub(s, "([^A-Za-z0-9_])", function (c)
if segment_set[c] then return c
else return string.format("%%%02x", string.byte(c)) end
end)
@ -63,7 +63,7 @@ end
-----------------------------------------------------------------------------
-- Encodes a string into its escaped hexadecimal representation
-- Input
-- Input
-- s: binary string to be encoded
-- Returns
-- escaped representation of string binary
@ -86,11 +86,11 @@ local function absolute_path(base_path, relative_path)
if string.sub(relative_path, 1, 1) == "/" then return relative_path end
local path = string.gsub(base_path, "[^/]*$", "")
path = path .. relative_path
path = string.gsub(path, "([^/]*%./)", function (s)
path = string.gsub(path, "([^/]*%./)", function (s)
if s ~= "./" then return s else return "" end
end)
path = string.gsub(path, "/%.$", "/")
local reduced
local reduced
while reduced ~= path do
reduced = path
path = string.gsub(reduced, "([^/]*/%.%./)", function (s)
@ -116,7 +116,7 @@ end
-- Returns
-- table with the following fields, where RFC naming conventions have
-- been preserved:
-- scheme, authority, userinfo, user, password, host, port,
-- scheme, authority, userinfo, user, password, host, port,
-- path, params, query, fragment
-- Obs:
-- the leading '/' in {/<path>} is considered part of <path>
@ -130,26 +130,26 @@ function parse(url, default)
-- remove whitespace
-- url = string.gsub(url, "%s", "")
-- get fragment
url = string.gsub(url, "#(.*)$", function(f)
parsed.fragment = f
url = string.gsub(url, "#(.*)$", function(f)
parsed.fragment = f
return ""
end)
-- get scheme
url = string.gsub(url, "^([%w][%w%+%-%.]*)%:",
url = string.gsub(url, "^([%w][%w%+%-%.]*)%:",
function(s) parsed.scheme = s; return "" end)
-- get authority
url = string.gsub(url, "^//([^/]*)", function(n)
parsed.authority = n
url = string.gsub(url, "^//([^/]*)", function(n)
parsed.authority = n
return ""
end)
-- get query stringing
url = string.gsub(url, "%?(.*)", function(q)
parsed.query = q
url = string.gsub(url, "%?(.*)", function(q)
parsed.query = q
return ""
end)
-- get params
url = string.gsub(url, "%;(.*)", function(p)
parsed.params = p
url = string.gsub(url, "%;(.*)", function(p)
parsed.params = p
return ""
end)
-- path is whatever was left
@ -158,14 +158,14 @@ function parse(url, default)
if not authority then return parsed end
authority = string.gsub(authority,"^([^@]*)@",
function(u) parsed.userinfo = u; return "" end)
authority = string.gsub(authority, ":([^:]*)$",
authority = string.gsub(authority, ":([^:]*)$",
function(p) parsed.port = p; return "" end)
if authority ~= "" then parsed.host = authority end
local userinfo = parsed.userinfo
if not userinfo then return parsed end
userinfo = string.gsub(userinfo, ":([^:]*)$",
userinfo = string.gsub(userinfo, ":([^:]*)$",
function(p) parsed.password = p; return "" end)
parsed.user = userinfo
parsed.user = userinfo
return parsed
end
@ -189,8 +189,8 @@ function build(parsed)
local userinfo = parsed.userinfo
if parsed.user then
userinfo = parsed.user
if parsed.password then
userinfo = userinfo .. ":" .. parsed.password
if parsed.password then
userinfo = userinfo .. ":" .. parsed.password
end
end
if userinfo then authority = userinfo .. "@" .. authority end
@ -233,8 +233,8 @@ function absolute(base_url, relative_url)
relative_parsed.query = base_parsed.query
end
end
else
relative_parsed.path = absolute_path(base_parsed.path or "",
else
relative_parsed.path = absolute_path(base_parsed.path or "",
relative_parsed.path)
end
end

View file

@ -110,7 +110,8 @@ int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,
double t = timeout_getretry(tm);
tv.tv_sec = (int) t;
tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6);
ret = select(n, rfds, wfds, efds, t >= 0.0? &tv: NULL);
/* timeout = 0 means no wait */
ret = select(n, rfds, wfds, efds, t >= 0.0 ? &tv: NULL);
} while (ret < 0 && errno == EINTR);
return ret;
}