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

2
config
View File

@ -27,7 +27,7 @@ COMPAT=compat-5.1r4
# Top of your Lua installation
# Relative paths will be inside the src tree
#
INSTALL_TOP_LUA=share
INSTALL_TOP_SHARE=share
INSTALL_TOP_LIB=lib
INSTALL_DATA=cp

View File

@ -69,22 +69,22 @@ independent files. Let's call these directories <tt>&lt;LIB&gt;</tt>
and <tt>&lt;SHARE&gt;</tt>, respectively.
For instance, in my laptop, I use '<tt>/usr/local/lib/lua/5.0</tt>' for
<tt>&lt;LIB&gt;</tt> and '<tt>/usr/local/share/lua/5.0</tt>' for
<tt>&lt;SHARE&gt;</tt>. On Windows, only one directory is used, say
<tt>&lt;SHARE&gt;</tt>. On Windows, sometimes only one directory is used, say
'<tt>c:\program files\lua\5.0</tt>'. Here is the standard LuaSocket
distribution directory structure:</p>
<pre class=example>
&lt;SHARE&gt;/compat-5.1.lua
&lt;SHARE&gt;/ltn12.lua
&lt;SHARE&gt;/mime/mime.lua
&lt;LIB&gt;/mime/core.dll
&lt;SHARE&gt;/socket/socket.lua
&lt;SHARE&gt;/socket.lua
&lt;LIB&gt;/socket/core.dll
&lt;SHARE&gt;/socket/http.lua
&lt;SHARE&gt;/socket/tp.lua
&lt;SHARE&gt;/socket/ftp.lua
&lt;SHARE&gt;/socket/smtp.lua
&lt;SHARE&gt;/socket/url.lua
&lt;SHARE&gt;/mime.lua
&lt;LIB&gt;/mime/core.dll
</pre>
<p> Naturally, on Unix systems, <tt>core.dll</tt>

View File

@ -210,13 +210,6 @@ Use the <a href=tcp.html#settimeout><tt>settimeout</tt></a>
method or <tt>accept</tt> might block forever.
</p>
<p class=note>
Interesting note: as mentioned in some Unix manuals, calling select with both
sets empty and a non-null timeout is a fairly portable way to sleep with
sub-second precision (<b>except it doesn't work on Windows</b>).
</p>
<!-- sink ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<p class=name id=sink>

View File

@ -37,7 +37,7 @@ function getstatus(link)
handler:start(function()
local r, c, h, s = http.request{
method = "HEAD",
url = link,
url = link,
create = handler.tcp
}
if r and c == 200 then io.write('\t', link, '\n')
@ -107,6 +107,6 @@ for _, address in ipairs(arg) do
checklinks(url.absolute("file:", address))
end
while nthreads > 0 do
while nthreads > 0 do
handler:step()
end
end

View File

@ -17,7 +17,7 @@ local tp = require("socket.tp")
module("socket.dict")
-----------------------------------------------------------------------------
-- Globals
-- Globals
-----------------------------------------------------------------------------
HOST = "dict.org"
PORT = 2628
@ -39,7 +39,7 @@ end
function metat.__index:check(ok)
local code, status = socket.try(self.tp:check(ok))
return code,
return code,
base.tonumber(socket.skip(2, string.find(status, "^%d%d%d (%d*)")))
end
@ -101,7 +101,7 @@ local default = {
}
local function there(f)
if f == "" then return nil
if f == "" then return nil
else return f end
end
@ -116,7 +116,7 @@ local function parse(u)
arg = string.gsub(arg, "^:([^:]+)", function(f) t.word = f end)
socket.try(t.word, "need at least <word> in URL")
arg = string.gsub(arg, "^:([^:]*)", function(f) t.database = there(f) end)
if cmd == "m" then
if cmd == "m" then
arg = string.gsub(arg, "^:([^:]*)", function(f) t.strat = there(f) end)
end
string.gsub(arg, ":([^:]*)$", function(f) t.n = base.tonumber(f) end)
@ -130,7 +130,7 @@ local function tget(gett)
local def = con:define(gett.database, gett.word)
con:quit()
con:close()
if gett.n then return def[gett.n]
if gett.n then return def[gett.n]
else return def end
elseif gett.command == "m" then
local mat = con:match(gett.database, gett.strat, gett.word)

View File

@ -14,7 +14,7 @@ module("dispatch")
TIMEOUT = 60
-----------------------------------------------------------------------------
-- We implement 3 types of dispatchers:
-- We implement 3 types of dispatchers:
-- sequential
-- coroutine
-- threaded
@ -34,7 +34,7 @@ end
-- sequential handler simply calls the functions and doesn't wrap I/O
function handlert.sequential()
return {
return {
tcp = socket.tcp,
start = seqstart
}
@ -55,7 +55,7 @@ function socket.protect(f)
if not status then
if type(results[1]) == 'table' then
return nil, results[1][1]
else error(results[1]) end
else error(results[1]) end
end
if coroutine.status(co) == "suspended" then
arg = {coroutine.yield(unpack(results))}
@ -84,17 +84,17 @@ local function newset()
if index then
reverse[value] = nil
local top = table.remove(set)
if top ~= value then
if top ~= value then
reverse[top] = index
set[index] = top
end
end
end
end
}})
}})
end
-----------------------------------------------------------------------------
-- socket.tcp() wrapper for the coroutine dispatcher
-- socket.tcp() wrapper for the coroutine dispatcher
-----------------------------------------------------------------------------
local function cowrap(dispatcher, tcp, error)
if not tcp then return nil, error end
@ -102,7 +102,7 @@ local function cowrap(dispatcher, tcp, error)
tcp:settimeout(0)
-- metatable for wrap produces new methods on demand for those that we
-- don't override explicitly.
local metat = { __index = function(table, key)
local metat = { __index = function(table, key)
table[key] = function(...)
arg[1] = tcp
return tcp[key](unpack(arg))
@ -112,7 +112,7 @@ local function cowrap(dispatcher, tcp, error)
-- does our user want to do his own non-blocking I/O?
local zero = false
-- create a wrap object that will behave just like a real socket object
local wrap = { }
local wrap = { }
-- we ignore settimeout to preserve our 0 timeout, but record whether
-- the user wants to do his own non-blocking I/O
function wrap:settimeout(value, mode)
@ -121,19 +121,19 @@ local function cowrap(dispatcher, tcp, error)
return 1
end
-- send in non-blocking mode and yield on timeout
function wrap:send(data, first, last)
function wrap:send(data, first, last)
first = (first or 1) - 1
local result, error
while true do
-- return control to dispatcher and tell it we want to send
-- if upon return the dispatcher tells us we timed out,
-- return an error to whoever called us
if coroutine.yield(dispatcher.sending, tcp) == "timeout" then
return nil, "timeout"
if coroutine.yield(dispatcher.sending, tcp) == "timeout" then
return nil, "timeout"
end
-- try sending
result, error, first = tcp:send(data, first+1, last)
-- if we are done, or there was an unexpected error,
-- if we are done, or there was an unexpected error,
-- break away from loop
if error ~= "timeout" then return result, error, first end
end
@ -143,20 +143,20 @@ local function cowrap(dispatcher, tcp, error)
function wrap:receive(pattern, partial)
local error = "timeout"
local value
while true do
while true do
-- return control to dispatcher and tell it we want to receive
-- if upon return the dispatcher tells us we timed out,
-- return an error to whoever called us
if coroutine.yield(dispatcher.receiving, tcp) == "timeout" then
return nil, "timeout"
if coroutine.yield(dispatcher.receiving, tcp) == "timeout" then
return nil, "timeout"
end
-- try receiving
value, error, partial = tcp:receive(pattern, partial)
-- if we are done, or there was an unexpected error,
-- if we are done, or there was an unexpected error,
-- break away from loop. also, if the user requested
-- zero timeout, return all we got
if (error ~= "timeout") or zero then
return value, error, partial
if (error ~= "timeout") or zero then
return value, error, partial
end
end
end
@ -168,8 +168,8 @@ local function cowrap(dispatcher, tcp, error)
-- connection succeeds.
-- if upon return the dispatcher tells us we have a
-- timeout, just abort
if coroutine.yield(dispatcher.sending, tcp) == "timeout" then
return nil, "timeout"
if coroutine.yield(dispatcher.sending, tcp) == "timeout" then
return nil, "timeout"
end
-- when we come back, check if connection was successful
result, error = tcp:connect(host, port)
@ -179,27 +179,27 @@ local function cowrap(dispatcher, tcp, error)
end
-- accept in non-blocking mode and yield on timeout
function wrap:accept()
while 1 do
while 1 do
-- return control to dispatcher. we will be readable when a
-- connection arrives.
-- if upon return the dispatcher tells us we have a
-- timeout, just abort
if coroutine.yield(dispatcher.receiving, tcp) == "timeout" then
return nil, "timeout"
if coroutine.yield(dispatcher.receiving, tcp) == "timeout" then
return nil, "timeout"
end
local client, error = tcp:accept()
if error ~= "timeout" then
return cowrap(dispatcher, client, error)
if error ~= "timeout" then
return cowrap(dispatcher, client, error)
end
end
end
end
-- remove cortn from context
function wrap:close()
dispatcher.stamp[tcp] = nil
dispatcher.sending.set:remove(tcp)
dispatcher.sending.cortn[tcp] = nil
dispatcher.sending.cortn[tcp] = nil
dispatcher.receiving.set:remove(tcp)
dispatcher.receiving.cortn[tcp] = nil
dispatcher.receiving.cortn[tcp] = nil
return tcp:close()
end
return setmetatable(wrap, metat)
@ -207,12 +207,12 @@ end
-----------------------------------------------------------------------------
-- Our coroutine dispatcher
-- Our coroutine dispatcher
-----------------------------------------------------------------------------
local cometat = { __index = {} }
function schedule(cortn, status, operation, tcp)
if status then
if status then
if cortn and operation then
operation.set:insert(tcp)
operation.cortn[tcp] = cortn
@ -233,7 +233,7 @@ function wakeup(operation, tcp)
kick(operation, tcp)
return cortn, coroutine.resume(cortn)
-- othrewise, just get scheduler not to do anything
else
else
return nil, true
end
end
@ -249,7 +249,7 @@ end
-- step through all active cortns
function cometat.__index:step()
-- check which sockets are interesting and act on them
local readable, writable = socket.select(self.receiving.set,
local readable, writable = socket.select(self.receiving.set,
self.sending.set, 1)
-- for all readable connections, resume their cortns and reschedule
-- when they yield back to us
@ -260,7 +260,7 @@ function cometat.__index:step()
for _, tcp in ipairs(writable) do
schedule(wakeup(self.sending, tcp))
end
-- politely ask replacement I/O functions in idle cortns to
-- politely ask replacement I/O functions in idle cortns to
-- return reporting a timeout
local now = socket.gettime()
for tcp, stamp in pairs(self.stamp) do
@ -271,25 +271,25 @@ function cometat.__index:step()
end
end
function cometat.__index:start(func)
function cometat.__index:start(func)
local cortn = coroutine.create(func)
schedule(cortn, coroutine.resume(cortn))
end
function handlert.coroutine()
local stamp = {}
local dispatcher = {
local dispatcher = {
stamp = stamp,
sending = {
name = "sending",
set = newset(),
cortn = {},
name = "sending",
set = newset(),
cortn = {},
stamp = stamp
},
receiving = {
name = "receiving",
set = newset(),
cortn = {},
set = newset(),
cortn = {},
stamp = stamp
},
}

View File

@ -1,5 +1,5 @@
-----------------------------------------------------------------------------
-- Little program to adjust end of line markers.
-- Little program to adjust end of line markers.
-- LuaSocket sample files
-- Author: Diego Nehab
-- RCS ID: $Id$

View File

@ -17,10 +17,10 @@ local function move(foo, bar)
live = data or error == "timeout"
data = data or partial
local result, error = bar:send(data)
if not live or not result then
foo:close()
if not live or not result then
foo:close()
bar:close()
break
break
end
end
end
@ -51,7 +51,7 @@ for i, v in ipairs(arg) do
handler:start(function()
move(client, peer)
end)
-- afte starting new handler, enter in loop sending data from
-- afte starting new handler, enter in loop sending data from
-- peer to client
move(peer, client)
end)

View File

@ -53,10 +53,10 @@ local elapsed_s = "%s received, %s/s throughput, %s elapsed "
function gauge(got, delta, size)
local rate = got / delta
if size and size >= 1 then
return string.format(remaining_s, nicesize(got), nicesize(rate),
return string.format(remaining_s, nicesize(got), nicesize(rate),
100*got/size, nicetime((size-got)/rate))
else
return string.format(elapsed_s, nicesize(got),
else
return string.format(elapsed_s, nicesize(got),
nicesize(rate), nicetime(delta))
end
end
@ -68,18 +68,18 @@ function stats(size)
local got = 0
return function(chunk)
-- elapsed time since start
local delta = socket.gettime() - start
if chunk then
local delta = socket.gettime() - start
if chunk then
-- total bytes received
got = got + string.len(chunk)
got = got + string.len(chunk)
-- not enough time for estimate
if delta > 0.1 then
io.stderr:write("\r", gauge(got, delta, size))
if delta > 0.1 then
io.stderr:write("\r", gauge(got, delta, size))
io.stderr:flush()
end
else
else
-- close up
io.stderr:write("\r", gauge(got, delta), "\n")
io.stderr:write("\r", gauge(got, delta), "\n")
end
return chunk
end
@ -111,11 +111,11 @@ function getbyftp(u, file)
local gett = url.parse(u)
gett.sink = save
gett.type = "i"
local ret, err = ftp.get(gett)
local ret, err = ftp.get(gett)
if err then print(err) end
end
-- determines the scheme
-- determines the scheme
function getscheme(u)
-- this is an heuristic to solve a common invalid url poblem
if not string.find(u, "//") then u = "//" .. u end
@ -134,7 +134,7 @@ end
-- main program
arg = arg or {}
if table.getn(arg) < 1 then
if table.getn(arg) < 1 then
io.write("Usage:\n lua get.lua <remote-url> [<local-file>]\n")
os.exit(1)
else get(arg[1], arg[2]) end

View File

@ -46,7 +46,7 @@ local function ACK(block)
local low, high
low = math.mod(block, 256)
high = (block - low)/256
return char(0, OP_ACK, high, low)
return char(0, OP_ACK, high, low)
end
local function get_OP(dgram)
@ -71,7 +71,7 @@ local function get_ERROR(dgram)
end
-----------------------------------------------------------------------------
-- The real work
-- The real work
-----------------------------------------------------------------------------
local function tget(gett)
local retries, dgram, sent, datahost, dataport, code
@ -83,15 +83,15 @@ local function tget(gett)
gett.host = try(socket.dns.toip(gett.host))
con:settimeout(1)
-- first packet gives data host/port to be used for data transfers
local path = string.gsub(gett.path or "", "^/", "")
local path = string.gsub(gett.path or "", "^/", "")
path = url.unescape(path)
retries = 0
repeat
repeat
sent = try(con:sendto(RRQ(path, "octet"), gett.host, gett.port))
dgram, datahost, dataport = con:receivefrom()
retries = retries + 1
until dgram or datahost ~= "timeout" or retries > 5
try(dgram, datahost)
try(dgram, datahost)
-- associate socket with data host/port
try(con:setpeername(datahost, dataport))
-- default sink
@ -110,7 +110,7 @@ local function tget(gett)
last = block
end
-- last packet brings less than 512 bytes of data
if string.len(data) < 512 then
if string.len(data) < 512 then
try(con:send(ACK(block)))
try(con:close())
try(sink(nil))
@ -118,7 +118,7 @@ local function tget(gett)
end
-- get the next packet
retries = 0
repeat
repeat
sent = try(con:send(ACK(last)))
dgram, err = con:receive()
retries = retries + 1
@ -141,7 +141,7 @@ local function parse(u)
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

@ -6,9 +6,9 @@ include config
#------
# Hopefully no need to change anything below this line
#
INSTALL_SOCKET_LUA=$(INSTALL_TOP_LUA)/socket
INSTALL_SOCKET_SHARE=$(INSTALL_TOP_SHARE)/socket
INSTALL_SOCKET_LIB=$(INSTALL_TOP_LIB)/socket
INSTALL_MIME_LUA=$(INSTALL_TOP_LUA)/mime
INSTALL_MIME_SHARE=$(INSTALL_TOP_SHARE)/mime
INSTALL_MIME_LIB=$(INSTALL_TOP_LIB)/mime
all clean:
@ -17,35 +17,34 @@ all clean:
#------
# Files to install
#
TO_SOCKET_LUA:= \
socket.lua \
TO_SOCKET_SHARE:= \
http.lua \
url.lua \
tp.lua \
ftp.lua \
smtp.lua
TO_TOP_LUA:= \
ltn12.lua
TO_MIME_LUA:= \
TO_TOP_SHARE:= \
$(COMPAT)/compat-5.1.lua \
ltn12.lua \
socket.lua \
mime.lua
TO_MIME_SHARE:=
#------
# Install LuaSocket according to recommendation
#
install: all
cd src; mkdir -p $(INSTALL_TOP_LUA)
cd src; mkdir -p $(INSTALL_TOP_LIB)
cd src; $(INSTALL_DATA) $(COMPAT)/compat-5.1.lua $(INSTALL_TOP_LUA)
cd src; $(INSTALL_DATA) ltn12.lua $(INSTALL_TOP_LUA)
cd src; mkdir -p $(INSTALL_SOCKET_LUA)
cd src; mkdir -p $(INSTALL_TOP_SHARE)
cd src; $(INSTALL_DATA) $(TO_TOP_SHARE) $(INSTALL_TOP_SHARE)
cd src; mkdir -p $(INSTALL_SOCKET_SHARE)
cd src; $(INSTALL_DATA) $(TO_SOCKET_SHARE) $(INSTALL_SOCKET_SHARE)
cd src; mkdir -p $(INSTALL_SOCKET_LIB)
cd src; $(INSTALL_DATA) $(TO_SOCKET_LUA) $(INSTALL_SOCKET_LUA)
cd src; $(INSTALL_EXEC) $(SOCKET_SO) $(INSTALL_SOCKET_LIB)/core.$(EXT)
cd src; mkdir -p $(INSTALL_MIME_LUA)
#cd src; mkdir -p $(INSTALL_MIME_SHARE)
#cd src; $(INSTALL_DATA) $(TO_MIME_SHARE) $(INSTALL_MIME_SHARE)
cd src; mkdir -p $(INSTALL_MIME_LIB)
cd src; $(INSTALL_DATA) $(TO_MIME_LUA) $(INSTALL_MIME_LUA)
cd src; $(INSTALL_EXEC) $(MIME_SO) $(INSTALL_MIME_LIB)/core.$(EXT)
#------

View File

@ -1,13 +1,12 @@
#--------------------------------------------------------------------------
# Distribution makefile
#--------------------------------------------------------------------------
DIST = luasocket-2.0
COMPAT = src/compat-5.1r4
TEST = \
test/README \
test/testclnt.lua \
test/testsrvr.lua \
test/testsupport.lua
@ -33,12 +32,12 @@ ETC = \
etc/eol.lua \
etc/forward.lua \
etc/get.lua \
etc/links \
etc/lp.lua \
etc/qp.lua \
etc/tftp.lua
SRC = \
src/makefile \
src/auxiliar.c \
src/auxiliar.h \
src/buffer.c \
@ -108,6 +107,7 @@ dist:
mkdir -p $(DIST)
cp -vf NEW $(DIST)
cp -vf LICENSE $(DIST)
cp -vf README $(DIST)
cp -vf $(MAKE) $(DIST)
mkdir -p $(DIST)/etc

View File

@ -16,7 +16,7 @@ function parse(body)
return nil, code, message
end
local data = {}
for l in lines do
for l in lines do
local c = string.sub(l, 1, 1)
if c ~= '#' and c ~= '.' then
local key, value = socket.skip(2, string.find(l, "(.-)=(.*)"))
@ -26,7 +26,7 @@ function parse(body)
data[key] = value
end
end
return data, code, message
return data, code, message
end
local host = socket.dns.gethostname()
@ -34,13 +34,13 @@ local query = "%s?cmd=cddb+read+%s+%s&hello=LuaSocket+%s+LuaSocket+2.0&proto=6"
local url = string.format(query, server, arg[1], arg[2], host)
local body, headers, code = http.get(url)
if code == 200 then
if code == 200 then
local data, code, error = parse(body)
if not data then
if not data then
print(error or code)
else
for i,v in pairs(data) do
io.write(i, ': ', v, '\n')
for i,v in pairs(data) do
io.write(i, ': ', v, '\n')
end
end
else print(error) end

View File

@ -20,10 +20,10 @@ assert(ip, port)
print("Waiting packets on " .. ip .. ":" .. port .. "...")
while 1 do
dgram, ip, port = udp:receivefrom()
if dgram then
if dgram then
print("Echoing '" .. dgram .. "' to " .. ip .. ":" .. port)
udp:sendto(dgram, ip, port)
else
print(ip)
else
print(ip)
end
end

View File

@ -36,7 +36,8 @@ do
return usage()
end
if arg[1] ~= "query" then
r,e=lp.send(arg[1],opt)
opt.file = arg[1]
r,e=lp.send(opt)
io.stdout:write(tostring(r or e),'\n')
else
r,e=lp.query(opt)

View File

@ -62,24 +62,24 @@ while 1 do
if input == server1 or input == server2 then
io.write("Waiting for clients\n")
local new = input:accept()
if new then
if new then
new:settimeout(1)
io.write("Inserting client in set\n")
set:insert(new)
set:insert(new)
end
-- it is a client socket
else
local line, error = input:receive()
if error then
if error then
input:close()
io.write("Removing client from set\n")
set:remove(input)
set:remove(input)
else
io.write("Broadcasting line '", line, "'\n")
writable, error = socket.skip(1, socket.select(nil, set, 1))
if not error then
for __, output in ipairs(writable) do
if output ~= input then
if output ~= input then
output:send(line .. "\n")
end
end

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;
}