From 0c3cdd5ef2485a79d6fec9261f2850c41577d5b3 Mon Sep 17 00:00:00 2001
From: Diego Nehab
Date: Fri, 12 Aug 2005 05:56:32 +0000
Subject: [PATCH] Final push for release...
---
FIX | 11 ++++++
TODO | 36 ++++++++---------
config | 2 +-
doc/ftp.html | 10 ++++-
doc/http.html | 7 +++-
doc/index.html | 4 +-
doc/installation.html | 14 +++----
doc/reference.html | 4 +-
doc/smtp.html | 8 +++-
doc/socket.html | 6 +--
doc/tcp.html | 21 +++++-----
etc/check-links-nb.lua | 81 +++++++++++++++++++++++----------------
etc/check-links.lua | 2 +-
etc/dict.lua | 2 +-
etc/lp.lua | 2 +-
etc/tftp.lua | 2 +-
makefile | 52 +++++++++++++++++++++++++
src/ftp.lua | 12 +++---
src/http.lua | 45 +++++++++-------------
src/ltn12.lua | 12 +++---
src/luasocket.c | 2 +-
src/makefile | 87 ++++++++++++++++++++++++++++++++++++++++++
src/mime.lua | 3 +-
src/smtp.lua | 29 +++++++-------
src/socket.lua | 3 +-
src/ssl.c | 70 ---------------------------------
src/ssl.h | 29 --------------
src/tp.lua | 9 +++--
src/url.lua | 2 +-
src/wsocket.c | 5 ++-
test/testmesg.lua | 15 ++++----
31 files changed, 332 insertions(+), 255 deletions(-)
create mode 100644 makefile
create mode 100644 src/makefile
delete mode 100644 src/ssl.c
delete mode 100644 src/ssl.h
diff --git a/FIX b/FIX
index 3d0b3de..84504f0 100644
--- a/FIX
+++ b/FIX
@@ -1,3 +1,14 @@
+fix smtp.send hang on source error
+add create field to FTP and SMTP and fix HTTP ugliness
+clean timeout argument to open functions in SMTP, HTTP and FTP
+eliminate globals from namespaces created by module().
+
+
+
+
+
+
+
url.absolute was not working when base_url was already parsed
http.request was redirecting even when the location header was empty
tcp{client}:shutdown() was checking for group instead of class.
diff --git a/TODO b/TODO
index cb5ac32..b2a167e 100644
--- a/TODO
+++ b/TODO
@@ -1,22 +1,13 @@
+new instalation scheme???
+test empty socket.select no windows.
+bug by mathew percival?
+
+arranjar um jeito de fazer multipart/alternative
+
what the hell does __unload do?
-clean timeout argument to open functions in SMTP, HTTP and FTP
-add create field to FTP and SMTP
-talk about new create field in HTTP, FTP and SMTP
-talk about the non-blocking connect in the manual
+
test it on Windows!!!
-think about a dispatcher.
- - it creates a server and receives a function that will do the work on
- received connections
- - this function is invoked with the client socket
- - it calls special send and receive functions that yield on timeout
-
-think about how to extend http, ftp, smtp to use special send and receive
-functions for non-blocking so they can be used in the context of the
-dispatcher!
-
-adjust manual for new sock:send returns.
-
leave code for losers that don't have nanosleep
ftp.send/recv return bytes transfered?
@@ -41,7 +32,16 @@ testar os options!
- proteger ou atomizar o conjunto (timedout, receive), (timedout, send)
- inet_ntoa também é uma merda.
-eliminate globals from namespaces created by module().
-
* BUG NO SET DO TINYIRC!!! SINISTRO.
* _VERSION, _DEBUG, etc.
+* talk about new create field in HTTP, FTP and SMTP
+* talk about the non-blocking connect in the manual
+* think about how to extend http, ftp, smtp to use special send and receive
+* functions for non-blocking so they can be used in the context of the
+* dispatcher!
+* adjust manual for new sock:send returns.
+* think about a dispatcher.
+ * - it creates a server and receives a function that will do the work on
+ * received connections
+ * - this function is invoked with the client socket
+ * - it calls special send and receive functions that yield on timeout
diff --git a/config b/config
index dcc3955..da9fdf4 100644
--- a/config
+++ b/config
@@ -21,7 +21,7 @@ LUALIB=
#------
# Compat-5.1 directory
#
-COMPAT=compat-5.1r3
+COMPAT=compat-5.1r4
#------
# Top of your Lua installation
diff --git a/doc/ftp.html b/doc/ftp.html
index 7860c27..8b7ed96 100644
--- a/doc/ftp.html
+++ b/doc/ftp.html
@@ -106,6 +106,7 @@ ftp.get{
[port = number,]
[type = string,]
[step = LTN12 pump step,]
+ [create = function]
}
@@ -138,7 +139,9 @@ authentication. Defaults to "accept: An optional function to be used instead of
+socket.tcp when the communications socket is created.
@@ -167,7 +171,7 @@ If successful, the function returns 1. Otherwise, the function returns
-Note: SMTP servers are can be very picky with the format of e-mail
+Note: SMTP servers can be very picky with the format of e-mail
addresses. To be safe, use only addresses of the form
"<fulano@example.com>" in the from and
rcpt arguments to the send function. In headers, e-mail
diff --git a/doc/socket.html b/doc/socket.html
index 5cc7157..54b12cb 100644
--- a/doc/socket.html
+++ b/doc/socket.html
@@ -80,12 +80,12 @@ socket.connect(address, port [, locaddr, locport])
This function is a shortcut that creates and returns a TCP client object
connected to a remote host at a given port. Optionally,
the user can also specify the local address and port to bind
-(locaddr and locport).
+(locaddr and locport).
-
+
socket._DEBUG
@@ -372,7 +372,7 @@ c = socket.try(socket.connect("localhost", 80))
-
+
socket._VERSION
diff --git a/doc/tcp.html b/doc/tcp.html
index ae8efd5..5c810de 100644
--- a/doc/tcp.html
+++ b/doc/tcp.html
@@ -79,7 +79,7 @@ reported by nil followed by a message describing the error.
Note: calling socket.select
with a server object in
-the receive parameter before a call to accept does
+the recvt parameter before a call to accept does
not guarantee accept will return immediately. Use the settimeout method or accept
might block until another client shows up.
@@ -111,7 +111,7 @@ method returns nil followed by an error message.
Note: The function socket.bind
-is available and is a shortcut for the creation server sockets.
+is available and is a shortcut for the creation of server sockets.
@@ -173,8 +173,11 @@ is available and is a shortcut for the creation of client sockets.
Note: Starting with LuaSocket 2.0,
the settimeout
-method affects the behavior of connect, causing it to return in case of
-a timeout.
+method affects the behavior of connect, causing it to return
+with an error in case of a timeout. If that happens, you can still call socket.select with the socket in the
+sendt table. The socket will be writable when the connection is
+stablished.
@@ -328,11 +331,11 @@ substring to be sent.
-If successful, the method returns the number of bytes accepted by
-the transport layer. In case of error, the method returns
+If successful, the method returns the number of bytes sent.
+In case of error, the method returns
nil, followed by an error message, followed by the
-partial number of bytes accepted by the transport layer.
-The error message can be 'closed' in case
+index of the first character within [i, j] that has not been sent yet
+(you might want to try again from then on). The error message can be 'closed' in case
the connection was closed before the transmission was completed or the
string 'timeout' in case there was a timeout during the
operation.
@@ -433,7 +436,7 @@ of bandwidth.
Received is a number with the new number of bytes received.
Sent is a number with the new number of bytes sent.
-Age is the new age in seconds
+Age is the new age in seconds.
diff --git a/etc/check-links-nb.lua b/etc/check-links-nb.lua
index 7e8df1b..c379e9a 100644
--- a/etc/check-links-nb.lua
+++ b/etc/check-links-nb.lua
@@ -84,17 +84,22 @@ function newcreate(thread)
first = (first or 1) - 1
local result, error
while true do
+ -- tell dispatcher we want to keep sending before we
+ -- yield control
+ sending:insert(tcp)
+ -- return control to dispatcher
+ -- if upon return the dispatcher tells us we timed out,
+ -- return an error to whoever called us
+ if coroutine.yield() == "timeout" then
+ return nil, "timeout"
+ end
+ -- mark time we started waiting
+ context[tcp].last = socket.gettime()
+ -- try sending
result, error, first = tcp:send(data, first+1, last)
- if error == "timeout" then
- -- tell dispatcher we want to keep sending
- sending:insert(tcp)
- -- mark time we started waiting
- context[tcp].last = socket.gettime()
- -- return control to dispatcher
- if coroutine.yield() == "timeout" then
- return nil, "timeout"
- end
- else return result, error, first end
+ -- if we are done, or there was an unexpected error,
+ -- break away from loop
+ if error ~= "timeout" then return result, error, first end
end
end,
-- receive in non-blocking mode and yield on timeout
@@ -102,28 +107,35 @@ function newcreate(thread)
local error, partial = "timeout", ""
local value
while true do
+ -- tell dispatcher we want to keep receiving before we
+ -- yield control
+ receiving:insert(tcp)
+ -- return control to dispatcher
+ -- if upon return the dispatcher tells us we timed out,
+ -- return an error to whoever called us
+ if coroutine.yield() == "timeout" then
+ return nil, "timeout"
+ end
+ -- mark time we started waiting
+ context[tcp].last = socket.gettime()
+ -- try receiving
value, error, partial = tcp:receive(pattern, partial)
- if error == "timeout" then
- -- tell dispatcher we want to keep receiving
- receiving:insert(tcp)
- -- mark time we started waiting
- context[tcp].last = socket.gettime()
- -- return control to dispatcher
- if coroutine.yield() == "timeout" then
- return nil, "timeout"
- end
- else return value, error, partial end
+ -- if we are done, or there was an unexpected error,
+ -- break away from loop
+ if error ~= "timeout" then return value, error, partial end
end
end,
-- connect in non-blocking mode and yield on timeout
connect = function(self, host, port)
local result, error = tcp:connect(host, port)
+ -- mark time we started waiting
+ context[tcp].last = socket.gettime()
if error == "timeout" then
-- tell dispatcher we will be able to write uppon connection
sending:insert(tcp)
- -- mark time we started waiting
- context[tcp].last = socket.gettime()
-- return control to dispatcher
+ -- if upon return the dispatcher tells us we have a
+ -- timeout, just abort
if coroutine.yield() == "timeout" then
return nil, "timeout"
end
@@ -148,10 +160,10 @@ function newcreate(thread)
end
-- get the status of a URL, non-blocking
-function getstatus(from, link)
+function getstatus(link)
local parsed = url.parse(link, {scheme = "file"})
if parsed.scheme == "http" then
- local thread = coroutine.create(function(thread, from, link)
+ local thread = coroutine.create(function(thread, link)
local r, c, h, s = http.request{
method = "HEAD",
url = link,
@@ -162,7 +174,7 @@ function getstatus(from, link)
nthreads = nthreads - 1
end)
nthreads = nthreads + 1
- assert(coroutine.resume(thread, thread, from, link))
+ assert(coroutine.resume(thread, thread, link))
end
end
@@ -190,6 +202,8 @@ function dispatch()
local now = socket.gettime()
for who, data in pairs(context) do
if data.last and now - data.last > TIMEOUT then
+ sending:remove(who)
+ receiving:remove(who)
assert(coroutine.resume(context[who].thread, "timeout"))
end
end
@@ -206,14 +220,15 @@ function readfile(path)
else return nil, error end
end
-function retrieve(u)
+function load(u)
local parsed = url.parse(u, { scheme = "file" })
local body, headers, code, error
local base = u
if parsed.scheme == "http" then
body, code, headers = http.request(u)
if code == 200 then
- base = base or headers.location
+ -- if there was a redirect, update base to reflect it
+ base = headers.location or base
end
if not body then
error = code
@@ -241,12 +256,13 @@ function getlinks(body, base)
return links
end
-function checklinks(from)
- local base, body, error = retrieve(from)
+function checklinks(address)
+ local base, body, error = load(address)
if not body then print(error) return end
+ print("Checking ", base)
local links = getlinks(body, base)
for _, link in ipairs(links) do
- getstatus(from, link)
+ getstatus(link)
end
end
@@ -255,8 +271,7 @@ if table.getn(arg) < 1 then
print("Usage:\n luasocket check-links.lua {}")
exit()
end
-for _, a in ipairs(arg) do
- print("Checking ", a)
- checklinks(url.absolute("file:", a))
+for _, address in ipairs(arg) do
+ checklinks(url.absolute("file:", address))
end
dispatch()
diff --git a/etc/check-links.lua b/etc/check-links.lua
index 79e6a54..9d837e4 100644
--- a/etc/check-links.lua
+++ b/etc/check-links.lua
@@ -37,7 +37,7 @@ function retrieve(u)
if parsed.scheme == "http" then
body, code, headers = http.request(u)
if code == 200 then
- base = base or headers.location
+ base = headers.location or base
end
if not body then
error = code
diff --git a/etc/dict.lua b/etc/dict.lua
index 76b254a..62d6913 100644
--- a/etc/dict.lua
+++ b/etc/dict.lua
@@ -16,6 +16,7 @@ local url = require("socket.url")
local tp = require("socket.tp")
module("socket.dict")
+getmetatable(_M).__index = nil
-----------------------------------------------------------------------------
-- Globals
@@ -151,4 +152,3 @@ get = socket.protect(function(gett)
else return tget(gett) end
end)
---getmetatable(_M).__index = nil
diff --git a/etc/lp.lua b/etc/lp.lua
index 2ba7954..66a9692 100644
--- a/etc/lp.lua
+++ b/etc/lp.lua
@@ -15,6 +15,7 @@ local string = require("string")
local socket = require("socket")
local ltn12 = require("ltn12")
module("socket.lp")
+getmetatable(_M).__index = nil
-- default port
PORT = 515
@@ -318,4 +319,3 @@ query = socket.protect(function(p)
return data
end)
---getmetatable(_M).__index = nil
diff --git a/etc/tftp.lua b/etc/tftp.lua
index 60658f7..b974db8 100644
--- a/etc/tftp.lua
+++ b/etc/tftp.lua
@@ -16,6 +16,7 @@ local socket = require("socket")
local ltn12 = require("ltn12")
local url = require("socket.url")
module("socket.tftp")
+getmetatable(_M).__index = nil
-----------------------------------------------------------------------------
-- Program constants
@@ -153,4 +154,3 @@ get = socket.protect(function(gett)
else return tget(gett) end
end)
---getmetatable(_M).__index = nil
diff --git a/makefile b/makefile
new file mode 100644
index 0000000..234e162
--- /dev/null
+++ b/makefile
@@ -0,0 +1,52 @@
+#------
+# Load configuration
+#
+include config
+
+#------
+# Hopefully no need to change anything below this line
+#
+INSTALL_SOCKET=$(INSTALL_TOP)/socket
+INSTALL_MIME=$(INSTALL_TOP)/mime
+
+all clean:
+ cd src; $(MAKE) $@
+
+#------
+# Files to install
+#
+TO_SOCKET:= \
+ socket.lua \
+ http.lua \
+ url.lua \
+ tp.lua \
+ ftp.lua \
+ smtp.lua
+
+TO_TOP:= \
+ ltn12.lua
+
+TO_MIME:= \
+ $(MIME_SO) \
+ mime.lua
+
+#------
+# Install LuaSocket according to recommendation
+#
+install: all
+ cd src; mkdir -p $(INSTALL_TOP)
+ cd src; $(INSTALL_DATA) $(COMPAT)/compat-5.1.lua $(INSTALL_TOP)
+ cd src; $(INSTALL_DATA) ltn12.lua $(INSTALL_TOP)
+ cd src; mkdir -p $(INSTALL_SOCKET)
+ cd src; $(INSTALL_EXEC) $(SOCKET_SO) $(INSTALL_SOCKET)
+ cd src; $(INSTALL_DATA) $(TO_SOCKET) $(INSTALL_SOCKET)
+ cd src; cd $(INSTALL_SOCKET); $(INSTALL_LINK) -s $(SOCKET_SO) core.$(EXT)
+ cd src; cd $(INSTALL_SOCKET); $(INSTALL_LINK) -s socket.lua init.lua
+ cd src; mkdir -p $(INSTALL_MIME)
+ cd src; $(INSTALL_DATA) $(TO_MIME) $(INSTALL_MIME)
+ cd src; cd $(INSTALL_MIME); $(INSTALL_LINK) -s $(MIME_SO) core.$(EXT)
+ cd src; cd $(INSTALL_MIME); $(INSTALL_LINK) -s mime.lua init.lua
+
+#------
+# End of makefile
+#
diff --git a/src/ftp.lua b/src/ftp.lua
index 841df5f..226e04c 100644
--- a/src/ftp.lua
+++ b/src/ftp.lua
@@ -17,6 +17,7 @@ local url = require("socket.url")
local tp = require("socket.tp")
local ltn12 = require("ltn12")
module("socket.ftp")
+getmetatable(_M).__index = nil
-----------------------------------------------------------------------------
-- Program constants
@@ -35,8 +36,8 @@ PASSWORD = "anonymous@anonymous.org"
-----------------------------------------------------------------------------
local metat = { __index = {} }
-function open(server, port)
- local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT))
+function open(server, port, create)
+ local tp = socket.try(tp.connect(server, port or PORT, create, TIMEOUT))
local f = base.setmetatable({ tp = tp }, metat)
-- make sure everything gets closed in an exception
f.try = socket.newtry(function() f:close() end)
@@ -199,7 +200,7 @@ end
local function tput(putt)
putt = override(putt)
socket.try(putt.host, "missing hostname")
- local f = open(putt.host, putt.port)
+ local f = open(putt.host, putt.port, putt.create)
f:greet()
f:login(putt.user, putt.password)
if putt.type then f:type(putt.type) end
@@ -242,7 +243,7 @@ end)
local function tget(gett)
gett = override(gett)
socket.try(gett.host, "missing hostname")
- local f = open(gett.host, gett.port)
+ local f = open(gett.host, gett.port, gett.create)
f:greet()
f:login(gett.user, gett.password)
if gett.type then f:type(gett.type) end
@@ -264,7 +265,7 @@ command = socket.protect(function(cmdt)
cmdt = override(cmdt)
socket.try(cmdt.host, "missing hostname")
socket.try(cmdt.command, "missing command")
- local f = open(cmdt.host, cmdt.port)
+ local f = open(cmdt.host, cmdt.port, cmdt.create)
f:greet()
f:login(cmdt.user, cmdt.password)
f.try(f.tp:command(cmdt.command, cmdt.argument))
@@ -278,4 +279,3 @@ get = socket.protect(function(gett)
else return tget(gett) end
end)
---getmetatable(_M).__index = nil
diff --git a/src/http.lua b/src/http.lua
index 91c52da..9434d97 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -16,6 +16,7 @@ local string = require("string")
local base = _G
local table = require("table")
module("socket.http")
+getmetatable(_M).__index = nil
-----------------------------------------------------------------------------
-- Program constants
@@ -105,26 +106,16 @@ end
-----------------------------------------------------------------------------
local metat = { __index = {} }
--- default connect function, respecting the timeout
-local function connect(host, port, create)
- local c, e = (create or socket.tcp)()
- if not c then return nil, e end
- c:settimeout(TIMEOUT)
- local r, e = c:connect(host, port or PORT)
- if not r then
- c:close()
- return nil, e
- end
- return c
-end
-
function open(host, port, create)
-- create socket with user connect function, or with default
- local c = socket.try(connect(host, port, create))
- -- create our http request object, pointing to the socket
+ local c = socket.try(create or socket.tcp)()
local h = base.setmetatable({ c = c }, metat)
- -- make sure the object close gets called on exception
+ -- create finalized try
h.try = socket.newtry(function() h:close() end)
+ -- set timeout before connecting
+ h.try(c:settimeout(TIMEOUT))
+ h.try(c:connect(host, port or PORT))
+ -- here everything worked
return h
end
@@ -134,11 +125,11 @@ function metat.__index:sendrequestline(method, uri)
end
function metat.__index:sendheaders(headers)
+ local h = "\r\n"
for i, v in base.pairs(headers) do
- self.try(self.c:send(i .. ": " .. v .. "\r\n"))
+ h = i .. ": " .. v .. "\r\n" .. h
end
- -- mark end of request headers
- self.try(self.c:send("\r\n"))
+ self.try(self.c:send(h))
return 1
end
@@ -213,7 +204,7 @@ local function adjustheaders(headers, host)
["te"] = "trailers"
}
-- override with user headers
- for i,v in pairs(headers or lower) do
+ for i,v in base.pairs(headers or lower) do
lower[string.lower(i)] = v
end
return lower
@@ -232,7 +223,7 @@ local function adjustrequest(reqt)
local nreqt = reqt.url and url.parse(reqt.url, default) or {}
local t = url.parse(reqt.url, default)
-- explicit components override url
- for i,v in pairs(reqt) do nreqt[i] = v end
+ for i,v in base.pairs(reqt) do nreqt[i] = v end
socket.try(nreqt.host, "invalid host '" .. base.tostring(nreqt.host) .. "'")
-- compute uri if user hasn't overriden
nreqt.uri = reqt.uri or adjusturi(nreqt)
@@ -276,11 +267,11 @@ function tauthorize(reqt)
return trequest(reqt)
end
-function tredirect(reqt, headers)
- return trequest {
+function tredirect(reqt, location)
+ local result, code, headers, status = trequest {
-- the RFC says the redirect URL has to be absolute, but some
-- servers do not respect that
- url = url.absolute(reqt, headers["location"]),
+ url = url.absolute(reqt, location),
source = reqt.source,
sink = reqt.sink,
headers = reqt.headers,
@@ -288,6 +279,9 @@ function tredirect(reqt, headers)
nredirects = (reqt.nredirects or 0) + 1,
connect = reqt.connect
}
+ -- pass location header back as a hint we redirected
+ headers.location = headers.location or location
+ return result, code, headers, status
end
function trequest(reqt)
@@ -301,7 +295,7 @@ function trequest(reqt)
headers = h:receiveheaders()
if shouldredirect(reqt, code, headers) then
h:close()
- return tredirect(reqt, headers)
+ return tredirect(reqt, headers.location)
elseif shouldauthorize(reqt, code) then
h:close()
return tauthorize(reqt)
@@ -332,4 +326,3 @@ request = socket.protect(function(reqt, body)
else return trequest(reqt) end
end)
---getmetatable(_M).__index = nil
diff --git a/src/ltn12.lua b/src/ltn12.lua
index fbc9dce..633e0d7 100644
--- a/src/ltn12.lua
+++ b/src/ltn12.lua
@@ -12,6 +12,7 @@ local string = require("string")
local table = require("table")
local base = _G
module("ltn12")
+getmetatable(_M).__index = nil
filter = {}
source = {}
@@ -134,8 +135,6 @@ function source.rewind(src)
end
end
-local print = print
-
-- chains a source with a filter
function source.chain(src, f)
base.assert(src and f)
@@ -258,7 +257,8 @@ end
function pump.step(src, snk)
local chunk, src_err = src()
local ret, snk_err = snk(chunk, src_err)
- return chunk and ret and not src_err and not snk_err, src_err or snk_err
+ if chunk and ret then return 1
+ else return nil, src_err or snk_err end
end
-- pumps all data from a source to a sink, using a step function
@@ -267,8 +267,10 @@ function pump.all(src, snk, step)
step = step or pump.step
while true do
local ret, err = step(src, snk)
- if not ret then return not err, err end
+ if not ret then
+ if err then return nil, err
+ else return 1 end
+ end
end
end
---getmetatable(_M).__index = nil
diff --git a/src/luasocket.c b/src/luasocket.c
index ed26b1f..94ea05b 100644
--- a/src/luasocket.c
+++ b/src/luasocket.c
@@ -108,7 +108,7 @@ static int base_open(lua_State *L) {
/*-------------------------------------------------------------------------*\
* Initializes all library modules.
\*-------------------------------------------------------------------------*/
-LUASOCKET_API int luaopen_socketcore(lua_State *L) {
+LUASOCKET_API int luaopen_socket_core(lua_State *L) {
int i;
base_open(L);
for (i = 0; mod[i].name; i++) mod[i].func(L);
diff --git a/src/makefile b/src/makefile
new file mode 100644
index 0000000..7ef18bf
--- /dev/null
+++ b/src/makefile
@@ -0,0 +1,87 @@
+#------
+# Load configuration
+#
+include ../config
+
+#------
+# Hopefully no need to change anything below this line
+#
+
+#------
+# Modules belonging to socket-core
+#
+SOCKET_OBJS:= \
+ luasocket.o \
+ timeout.o \
+ buffer.o \
+ io.o \
+ auxiliar.o \
+ options.o \
+ inet.o \
+ tcp.o \
+ udp.o \
+ except.o \
+ select.o \
+ $(COMPAT)/compat-5.1.o \
+ usocket.o
+
+#------
+# Modules belonging mime-core
+#
+MIME_OBJS:=\
+ mime.o \
+ $(COMPAT)/compat-5.1.o
+
+#------
+# Modules belonging unix (local domain sockets)
+#
+UNIX_OBJS:=\
+ buffer.o \
+ auxiliar.o \
+ options.o \
+ timeout.o \
+ io.o \
+ usocket.o \
+ unix.o
+
+all: $(SOCKET_SO) $(MIME_SO)
+
+$(SOCKET_SO): $(SOCKET_OBJS)
+ $(LD) $(LDFLAGS) -o $@ $^
+
+$(MIME_SO): $(MIME_OBJS)
+ $(LD) $(LDFLAGS) -o $@ $^
+
+$(UNIX_SO): $(UNIX_OBJS)
+ $(LD) $(LDFLAGS) -o $@ $^
+
+#------
+# List of dependencies
+#
+auxiliar.o: auxiliar.c auxiliar.h
+buffer.o: buffer.c buffer.h io.h timeout.h
+except.o: except.c except.h
+inet.o: inet.c inet.h socket.h io.h timeout.h usocket.h
+io.o: io.c io.h timeout.h
+luasocket.o: luasocket.c luasocket.h auxiliar.h except.h timeout.h \
+ buffer.h io.h inet.h socket.h usocket.h tcp.h udp.h select.h
+mime.o: mime.c mime.h
+options.o: options.c auxiliar.h options.h socket.h io.h timeout.h \
+ usocket.h inet.h
+select.o: select.c socket.h io.h timeout.h usocket.h select.h
+tcp.o: tcp.c auxiliar.h socket.h io.h timeout.h usocket.h inet.h \
+ options.h tcp.h buffer.h
+timeout.o: timeout.c auxiliar.h timeout.h
+udp.o: udp.c auxiliar.h socket.h io.h timeout.h usocket.h inet.h \
+ options.h udp.h
+unix.o: unix.c auxiliar.h socket.h io.h timeout.h usocket.h options.h \
+ unix.h buffer.h
+usocket.o: usocket.c socket.h io.h timeout.h usocket.h
+
+clean:
+ rm -f $(SOCKET_SO) $(SOCKET_OBJS)
+ rm -f $(MIME_SO) $(UNIX_SO) $(MIME_OBJS) $(UNIX_OBJS)
+
+#------
+# End of makefile configuration
+#
diff --git a/src/mime.lua b/src/mime.lua
index e112f8a..af42dcd 100644
--- a/src/mime.lua
+++ b/src/mime.lua
@@ -14,6 +14,7 @@ local mime = require("mime.core")
local io = require("io")
local string = require("string")
module("mime")
+getmetatable(_M).__index = nil
-- encode, decode and wrap algorithm tables
encodet = {}
@@ -84,5 +85,3 @@ end
function stuff()
return ltn12.filter.cycle(dot, 2)
end
-
---getmetatable(_M).__index = nil
diff --git a/src/smtp.lua b/src/smtp.lua
index 6850f7f..46df1ab 100644
--- a/src/smtp.lua
+++ b/src/smtp.lua
@@ -18,6 +18,7 @@ local tp = require("socket.tp")
local ltn12 = require("ltn12")
local mime = require("mime")
module("socket.smtp")
+getmetatable(_M).__index = nil
-----------------------------------------------------------------------------
-- Program constants
@@ -111,12 +112,12 @@ function metat.__index:send(mailt)
self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step)
end
-function open(server, port)
- local tp = socket.try(tp.connect(server or SERVER, port or PORT, TIMEOUT))
+function open(server, port, create)
+ 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()
- if s.tp:command("QUIT") then s.tp:check("2..") end
s:close()
end)
return s
@@ -165,10 +166,9 @@ end
local function send_source(mesgt)
-- set content-type if user didn't override
if not mesgt.headers or not mesgt.headers["content-type"] then
- coroutine.yield('content-type: text/plain; charset="iso-8859-1"\r\n')
- end
+ coroutine.yield('content-type: text/plain; charset="iso-8859-1"\r\n\r\n')
+ else coroutine.yield("\r\n") end
-- finish headers
- coroutine.yield("\r\n")
-- send body from source
while true do
local chunk, err = mesgt.body()
@@ -182,21 +182,20 @@ end
local function send_string(mesgt)
-- set content-type if user didn't override
if not mesgt.headers or not mesgt.headers["content-type"] then
- coroutine.yield('content-type: text/plain; charset="iso-8859-1"\r\n')
- end
- -- finish headers
- coroutine.yield("\r\n")
+ coroutine.yield('content-type: text/plain; charset="iso-8859-1"\r\n\r\n')
+ else coroutine.yield("\r\n") end
-- send body from string
coroutine.yield(mesgt.body)
-
end
--- yield the headers one by one
+-- yield the headers all at once
local function send_headers(mesgt)
if mesgt.headers then
+ local h = ""
for i,v in base.pairs(mesgt.headers) do
- coroutine.yield(i .. ':' .. v .. "\r\n")
+ h = i .. ': ' .. v .. "\r\n" .. h
end
+ coroutine.yield(h)
end
end
@@ -237,12 +236,10 @@ end
-- High level SMTP API
-----------------------------------------------------------------------------
send = socket.protect(function(mailt)
- local s = open(mailt.server, mailt.port)
+ local s = open(mailt.server, mailt.port, mailt.create)
local ext = s:greet(mailt.domain)
s:auth(mailt.user, mailt.password, ext)
s:send(mailt)
s:quit()
return s:close()
end)
-
---getmetatable(_M).__index = nil
diff --git a/src/socket.lua b/src/socket.lua
index 13b474d..be01667 100644
--- a/src/socket.lua
+++ b/src/socket.lua
@@ -12,6 +12,7 @@ local string = require("string")
local math = require("math")
local socket = require("socket.core")
module("socket")
+getmetatable(_M).__index = nil
-----------------------------------------------------------------------------
-- Exported auxiliar functions
@@ -131,5 +132,3 @@ sourcet["default"] = sourcet["until-closed"]
source = choose(sourcet)
--- clear globals from namespace
-getmetatable(_M).__index = nil
diff --git a/src/ssl.c b/src/ssl.c
deleted file mode 100644
index 8e2ce00..0000000
--- a/src/ssl.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*=========================================================================*\
-* Simple client SSL support
-* LuaSocket toolkit
-*
-* RCS ID: $Id$
-\*=========================================================================*/
-#include
-#include
-
-#include "ssl.h"
-
-/*=========================================================================*\
-* Internal function prototypes
-\*=========================================================================*/
-static int global_wrap(lua_State *L);
-
-/* functions in library namespace */
-static luaL_reg func[] = {
- {"wrap", global_create},
- {NULL, NULL}
-};
-
-static luaL_reg wrap[] = {
- {"__tostring", aux_tostring},
- {"__gc", meth_close},
- {"close", meth_close},
- {"receive", meth_receive},
- {"send", meth_send},
- {NULL, NULL}
-};
-
-static luaL_reg owned[] = {
- {"__tostring", aux_tostring},
- {NULL, NULL}
-};
-
-/*-------------------------------------------------------------------------*\
-* Initializes module
-\*-------------------------------------------------------------------------*/
-int ssl_open(lua_State *L)
-{
- aux_newclass(L, "ssl{wraper}", wrap);
- aux_newclass(L, "ssl{owned}", owned);
- lua_pushstring(L, "ssl")
- lua_newtable(L);
- luaL_openlib(L, NULL, func, 0);
- lua_settable(L, -3);
- return 0;
-}
-
-/*=========================================================================*\
-* Library functions
-\*=========================================================================*/
-/*-------------------------------------------------------------------------*\
-* Wraps a tcp object into an SSL object
-\*-------------------------------------------------------------------------*/
-static int global_wrap(lua_State *L) {
- p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1);
- /* change class of tcp object */
- aux_setclass(L, "ssl{owned}", 1);
- /* create wrapper */
- p_wrap wrap = (p_wrap) lua_newuserdata(L, sizeof(t_wrap));
- /* lock reference */
- lua_pushvalue(L, 1);
- wrap->ref = lua_ref(L, 1);
- /* initialize wrapper */
- wrap->tcp = tcp;
- io_init(&tcp->io, wrap_send, wrap_recv, wrap);
- return 1;
-}
diff --git a/src/ssl.h b/src/ssl.h
deleted file mode 100644
index 13ce97b..0000000
--- a/src/ssl.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef SSL_H
-#define SSL_H
-/*=========================================================================*\
-* Simple client SSL support
-* LuaSocket toolkit
-*
-* This is just a simple example to show how to extend LuaSocket
-*
-* RCS ID: $Id$
-\*=========================================================================*/
-#include
-#include
-
-#include "buffer.h"
-#include "timeout.h"
-#include "socket.h"
-#include "tcp.h"
-
-typedef struct t_wrap_ {
- p_tcp tcp;
- SSL* ssl;
- int ref;
-} t_wrap;
-
-typedef t_wrap *p_wrap;
-
-int ssl_open(lua_State *L);
-
-#endif /* SSL_H */
diff --git a/src/tp.lua b/src/tp.lua
index c51d123..7823699 100644
--- a/src/tp.lua
+++ b/src/tp.lua
@@ -13,6 +13,7 @@ local string = require("string")
local socket = require("socket")
local ltn12 = require("ltn12")
module("socket.tp")
+getmetatable(_M).__index = nil
-----------------------------------------------------------------------------
-- Program constants
@@ -98,7 +99,8 @@ end
function metat.__index:source(source, step)
local sink = socket.sink("keep-open", self.c)
- return ltn12.pump.all(source, sink, step or ltn12.pump.step)
+ local ret, err = ltn12.pump.all(source, sink, step or ltn12.pump.step)
+ return ret, err
end
-- closes the underlying c
@@ -108,8 +110,8 @@ function metat.__index:close()
end
-- connect with server and return c object
-function connect(host, port, timeout)
- local c, e = socket.tcp()
+function connect(host, port, create, timeout)
+ local c, e = (create or socket.tcp())
if not c then return nil, e end
c:settimeout(timeout or TIMEOUT)
local r, e = c:connect(host, port)
@@ -120,4 +122,3 @@ function connect(host, port, timeout)
return base.setmetatable({c = c}, metat)
end
---getmetatable(_M).__index = nil
diff --git a/src/url.lua b/src/url.lua
index 0db111b..bd39d98 100644
--- a/src/url.lua
+++ b/src/url.lua
@@ -12,6 +12,7 @@ local string = require("string")
local base = _G
local table = require("table")
module("socket.url")
+getmetatable(_M).__index = nil
-----------------------------------------------------------------------------
-- Encodes a string into its escaped hexadecimal representation
@@ -279,4 +280,3 @@ function build_path(parsed, unsafe)
return path
end
---getmetatable(_M).__index = nil
diff --git a/src/wsocket.c b/src/wsocket.c
index 2cbd073..c4c51b4 100644
--- a/src/wsocket.c
+++ b/src/wsocket.c
@@ -74,7 +74,10 @@ int sock_select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, p_tm tm) {
double t = tm_get(tm);
tv.tv_sec = (int) t;
tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6);
- return select(0, rfds, wfds, efds, t >= 0.0? &tv: NULL);
+ if (n <= 0) {
+ Sleep(1000*t);
+ return 0;
+ } else return select(0, rfds, wfds, efds, t >= 0.0? &tv: NULL);
}
/*-------------------------------------------------------------------------*\
diff --git a/test/testmesg.lua b/test/testmesg.lua
index 5350921..37e8c11 100644
--- a/test/testmesg.lua
+++ b/test/testmesg.lua
@@ -48,18 +48,19 @@ source = smtp.message{
}
}
---[[
-sink = ltn12.sink.file(io.stdout)
-ltn12.pump.all(source, sink)
-]]
+function filter(s)
+ if s then io.write(s) end
+ return s
+end
--- finally send it
r, e = smtp.send{
rcpt = {"",
"" },
from = "",
- source = source,
- server = "mail.cs.princeton.edu"
+ source = ltn12.source.chain(source, filter),
+ --server = "mail.cs.princeton.edu"
+ server = "localhost",
+ port = 2525
}
print(r, e)