aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ftp.lua39
-rw-r--r--src/headers.lua8
-rw-r--r--src/http.lua27
-rw-r--r--src/ltn12.lua26
-rw-r--r--src/luasocket.c31
-rw-r--r--src/luasocket.h4
-rw-r--r--src/mbox.lua2
-rw-r--r--src/mime.c9
-rw-r--r--src/mime.lua39
-rw-r--r--src/smtp.lua32
-rw-r--r--src/socket.lua25
-rw-r--r--src/tp.lua11
-rw-r--r--src/url.lua37
-rw-r--r--test/hello.lua4
14 files changed, 179 insertions, 115 deletions
diff --git a/src/ftp.lua b/src/ftp.lua
index 5aa646b..714b388 100644
--- a/src/ftp.lua
+++ b/src/ftp.lua
@@ -15,27 +15,27 @@ local socket = require("socket")
15local url = require("socket.url") 15local url = require("socket.url")
16local tp = require("socket.tp") 16local tp = require("socket.tp")
17local ltn12 = require("ltn12") 17local ltn12 = require("ltn12")
18module("socket.ftp") 18socket.ftp = {}
19 19local _M = socket.ftp
20----------------------------------------------------------------------------- 20-----------------------------------------------------------------------------
21-- Program constants 21-- Program constants
22----------------------------------------------------------------------------- 22-----------------------------------------------------------------------------
23-- timeout in seconds before the program gives up on a connection 23-- timeout in seconds before the program gives up on a connection
24TIMEOUT = 60 24_M.TIMEOUT = 60
25-- default port for ftp service 25-- default port for ftp service
26PORT = 21 26_M.PORT = 21
27-- this is the default anonymous password. used when no password is 27-- this is the default anonymous password. used when no password is
28-- provided in url. should be changed to your e-mail. 28-- provided in url. should be changed to your e-mail.
29USER = "ftp" 29_M.USER = "ftp"
30PASSWORD = "anonymous@anonymous.org" 30_M.PASSWORD = "anonymous@anonymous.org"
31 31
32----------------------------------------------------------------------------- 32-----------------------------------------------------------------------------
33-- Low level FTP API 33-- Low level FTP API
34----------------------------------------------------------------------------- 34-----------------------------------------------------------------------------
35local metat = { __index = {} } 35local metat = { __index = {} }
36 36
37function open(server, port, create) 37function _M.open(server, port, create)
38 local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT, create)) 38 local tp = socket.try(tp.connect(server, port or _M.PORT, _M.TIMEOUT, create))
39 local f = base.setmetatable({ tp = tp }, metat) 39 local f = base.setmetatable({ tp = tp }, metat)
40 -- make sure everything gets closed in an exception 40 -- make sure everything gets closed in an exception
41 f.try = socket.newtry(function() f:close() end) 41 f.try = socket.newtry(function() f:close() end)
@@ -43,22 +43,22 @@ function open(server, port, create)
43end 43end
44 44
45function metat.__index:portconnect() 45function metat.__index:portconnect()
46 self.try(self.server:settimeout(TIMEOUT)) 46 self.try(self.server:settimeout(_M.TIMEOUT))
47 self.data = self.try(self.server:accept()) 47 self.data = self.try(self.server:accept())
48 self.try(self.data:settimeout(TIMEOUT)) 48 self.try(self.data:settimeout(_M.TIMEOUT))
49end 49end
50 50
51function metat.__index:pasvconnect() 51function metat.__index:pasvconnect()
52 self.data = self.try(socket.tcp()) 52 self.data = self.try(socket.tcp())
53 self.try(self.data:settimeout(TIMEOUT)) 53 self.try(self.data:settimeout(_M.TIMEOUT))
54 self.try(self.data:connect(self.pasvt.ip, self.pasvt.port)) 54 self.try(self.data:connect(self.pasvt.ip, self.pasvt.port))
55end 55end
56 56
57function metat.__index:login(user, password) 57function metat.__index:login(user, password)
58 self.try(self.tp:command("user", user or USER)) 58 self.try(self.tp:command("user", user or _M.USER))
59 local code, reply = self.try(self.tp:check{"2..", 331}) 59 local code, reply = self.try(self.tp:check{"2..", 331})
60 if code == 331 then 60 if code == 331 then
61 self.try(self.tp:command("pass", password or PASSWORD)) 61 self.try(self.tp:command("pass", password or _M.PASSWORD))
62 self.try(self.tp:check("2..")) 62 self.try(self.tp:check("2.."))
63 end 63 end
64 return 1 64 return 1
@@ -87,7 +87,7 @@ function metat.__index:port(ip, port)
87 ip, port = self.try(self.tp:getcontrol():getsockname()) 87 ip, port = self.try(self.tp:getcontrol():getsockname())
88 self.server = self.try(socket.bind(ip, 0)) 88 self.server = self.try(socket.bind(ip, 0))
89 ip, port = self.try(self.server:getsockname()) 89 ip, port = self.try(self.server:getsockname())
90 self.try(self.server:settimeout(TIMEOUT)) 90 self.try(self.server:settimeout(_M.TIMEOUT))
91 end 91 end
92 local pl = math.mod(port, 256) 92 local pl = math.mod(port, 256)
93 local ph = (port - pl)/256 93 local ph = (port - pl)/256
@@ -199,7 +199,7 @@ end
199local function tput(putt) 199local function tput(putt)
200 putt = override(putt) 200 putt = override(putt)
201 socket.try(putt.host, "missing hostname") 201 socket.try(putt.host, "missing hostname")
202 local f = open(putt.host, putt.port, putt.create) 202 local f = _M.open(putt.host, putt.port, putt.create)
203 f:greet() 203 f:greet()
204 f:login(putt.user, putt.password) 204 f:login(putt.user, putt.password)
205 if putt.type then f:type(putt.type) end 205 if putt.type then f:type(putt.type) end
@@ -234,7 +234,7 @@ local function sput(u, body)
234 return tput(putt) 234 return tput(putt)
235end 235end
236 236
237put = socket.protect(function(putt, body) 237_M.put = socket.protect(function(putt, body)
238 if base.type(putt) == "string" then return sput(putt, body) 238 if base.type(putt) == "string" then return sput(putt, body)
239 else return tput(putt) end 239 else return tput(putt) end
240end) 240end)
@@ -242,7 +242,7 @@ end)
242local function tget(gett) 242local function tget(gett)
243 gett = override(gett) 243 gett = override(gett)
244 socket.try(gett.host, "missing hostname") 244 socket.try(gett.host, "missing hostname")
245 local f = open(gett.host, gett.port, gett.create) 245 local f = _M.open(gett.host, gett.port, gett.create)
246 f:greet() 246 f:greet()
247 f:login(gett.user, gett.password) 247 f:login(gett.user, gett.password)
248 if gett.type then f:type(gett.type) end 248 if gett.type then f:type(gett.type) end
@@ -260,7 +260,7 @@ local function sget(u)
260 return table.concat(t) 260 return table.concat(t)
261end 261end
262 262
263command = socket.protect(function(cmdt) 263_M.command = socket.protect(function(cmdt)
264 cmdt = override(cmdt) 264 cmdt = override(cmdt)
265 socket.try(cmdt.host, "missing hostname") 265 socket.try(cmdt.host, "missing hostname")
266 socket.try(cmdt.command, "missing command") 266 socket.try(cmdt.command, "missing command")
@@ -273,8 +273,9 @@ command = socket.protect(function(cmdt)
273 return f:close() 273 return f:close()
274end) 274end)
275 275
276get = socket.protect(function(gett) 276_M.get = socket.protect(function(gett)
277 if base.type(gett) == "string" then return sget(gett) 277 if base.type(gett) == "string" then return sget(gett)
278 else return tget(gett) end 278 else return tget(gett) end
279end) 279end)
280 280
281return _M \ No newline at end of file
diff --git a/src/headers.lua b/src/headers.lua
index a293329..1eb8223 100644
--- a/src/headers.lua
+++ b/src/headers.lua
@@ -3,9 +3,11 @@
3-- LuaSocket toolkit. 3-- LuaSocket toolkit.
4-- Author: Diego Nehab 4-- Author: Diego Nehab
5----------------------------------------------------------------------------- 5-----------------------------------------------------------------------------
6module("socket.headers") 6local socket = require("socket")
7socket.headers = {}
8local _M = socket.headers
7 9
8canonic = { 10_M.canonic = {
9 ["accept"] = "Accept", 11 ["accept"] = "Accept",
10 ["accept-charset"] = "Accept-Charset", 12 ["accept-charset"] = "Accept-Charset",
11 ["accept-encoding"] = "Accept-Encoding", 13 ["accept-encoding"] = "Accept-Encoding",
@@ -98,3 +100,5 @@ canonic = {
98 ["www-authenticate"] = "WWW-Authenticate", 100 ["www-authenticate"] = "WWW-Authenticate",
99 ["x-mailer"] = "X-Mailer", 101 ["x-mailer"] = "X-Mailer",
100} 102}
103
104return _M \ No newline at end of file
diff --git a/src/http.lua b/src/http.lua
index 4c7e7d8..ac4b2d6 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -15,7 +15,8 @@ local string = require("string")
15local headers = require("socket.headers") 15local headers = require("socket.headers")
16local base = _G 16local base = _G
17local table = require("table") 17local table = require("table")
18module("socket.http") 18socket.http = {}
19local _M = socket.http
19 20
20----------------------------------------------------------------------------- 21-----------------------------------------------------------------------------
21-- Program constants 22-- Program constants
@@ -23,9 +24,9 @@ module("socket.http")
23-- connection timeout in seconds 24-- connection timeout in seconds
24TIMEOUT = 60 25TIMEOUT = 60
25-- default port for document retrieval 26-- default port for document retrieval
26PORT = 80 27_M.PORT = 80
27-- user agent field sent in request 28-- user agent field sent in request
28USERAGENT = socket._VERSION 29_M.USERAGENT = socket._VERSION
29 30
30----------------------------------------------------------------------------- 31-----------------------------------------------------------------------------
31-- Reads MIME headers from a connection, unfolding where needed 32-- Reads MIME headers from a connection, unfolding where needed
@@ -105,15 +106,15 @@ end
105----------------------------------------------------------------------------- 106-----------------------------------------------------------------------------
106local metat = { __index = {} } 107local metat = { __index = {} }
107 108
108function open(host, port, create) 109function _M.open(host, port, create)
109 -- create socket with user connect function, or with default 110 -- create socket with user connect function, or with default
110 local c = socket.try((create or socket.tcp)()) 111 local c = socket.try((create or socket.tcp)())
111 local h = base.setmetatable({ c = c }, metat) 112 local h = base.setmetatable({ c = c }, metat)
112 -- create finalized try 113 -- create finalized try
113 h.try = socket.newtry(function() h:close() end) 114 h.try = socket.newtry(function() h:close() end)
114 -- set timeout before connecting 115 -- set timeout before connecting
115 h.try(c:settimeout(TIMEOUT)) 116 h.try(c:settimeout(_M.TIMEOUT))
116 h.try(c:connect(host, port or PORT)) 117 h.try(c:connect(host, port or _M.PORT))
117 -- here everything worked 118 -- here everything worked
118 return h 119 return h
119end 120end
@@ -209,7 +210,7 @@ end
209local function adjustheaders(reqt) 210local function adjustheaders(reqt)
210 -- default headers 211 -- default headers
211 local lower = { 212 local lower = {
212 ["user-agent"] = USERAGENT, 213 ["user-agent"] = _M.USERAGENT,
213 ["host"] = reqt.host, 214 ["host"] = reqt.host,
214 ["connection"] = "close, TE", 215 ["connection"] = "close, TE",
215 ["te"] = "trailers" 216 ["te"] = "trailers"
@@ -229,7 +230,7 @@ end
229-- default url parts 230-- default url parts
230local default = { 231local default = {
231 host = "", 232 host = "",
232 port = PORT, 233 port = _M.PORT,
233 path ="/", 234 path ="/",
234 scheme = "http" 235 scheme = "http"
235} 236}
@@ -270,7 +271,7 @@ end
270-- forward declarations 271-- forward declarations
271local trequest, tredirect 272local trequest, tredirect
272 273
273function tredirect(reqt, location) 274--[[local]] function tredirect(reqt, location)
274 local result, code, headers, status = trequest { 275 local result, code, headers, status = trequest {
275 -- the RFC says the redirect URL has to be absolute, but some 276 -- the RFC says the redirect URL has to be absolute, but some
276 -- servers do not respect that 277 -- servers do not respect that
@@ -288,11 +289,11 @@ function tredirect(reqt, location)
288 return result, code, headers, status 289 return result, code, headers, status
289end 290end
290 291
291function trequest(reqt) 292--[[local]] function trequest(reqt)
292 -- we loop until we get what we want, or 293 -- we loop until we get what we want, or
293 -- until we are sure there is no way to get it 294 -- until we are sure there is no way to get it
294 local nreqt = adjustrequest(reqt) 295 local nreqt = adjustrequest(reqt)
295 local h = open(nreqt.host, nreqt.port, nreqt.create) 296 local h = _M.open(nreqt.host, nreqt.port, nreqt.create)
296 -- send request line and headers 297 -- send request line and headers
297 h:sendrequestline(nreqt.method, nreqt.uri) 298 h:sendrequestline(nreqt.method, nreqt.uri)
298 h:sendheaders(nreqt.headers) 299 h:sendheaders(nreqt.headers)
@@ -345,7 +346,9 @@ local function srequest(u, b)
345 return table.concat(t), code, headers, status 346 return table.concat(t), code, headers, status
346end 347end
347 348
348request = socket.protect(function(reqt, body) 349_M.request = socket.protect(function(reqt, body)
349 if base.type(reqt) == "string" then return srequest(reqt, body) 350 if base.type(reqt) == "string" then return srequest(reqt, body)
350 else return trequest(reqt) end 351 else return trequest(reqt) end
351end) 352end)
353
354return _M \ No newline at end of file
diff --git a/src/ltn12.lua b/src/ltn12.lua
index fca1cb2..c5f7c4c 100644
--- a/src/ltn12.lua
+++ b/src/ltn12.lua
@@ -10,16 +10,19 @@
10local string = require("string") 10local string = require("string")
11local table = require("table") 11local table = require("table")
12local base = _G 12local base = _G
13module("ltn12") 13ltn12 = {}
14local _M = ltn12
14 15
15filter = {} 16local filter,source,sink,pump = {},{},{},{}
16source = {} 17
17sink = {} 18_M.filter = filter
18pump = {} 19_M.source = source
20_M.sink = sink
21_M.pump = pump
19 22
20-- 2048 seems to be better in windows... 23-- 2048 seems to be better in windows...
21BLOCKSIZE = 2048 24_M.BLOCKSIZE = 2048
22_VERSION = "LTN12 1.0.2" 25_M._VERSION = "LTN12 1.0.2"
23 26
24----------------------------------------------------------------------------- 27-----------------------------------------------------------------------------
25-- Filter stuff 28-- Filter stuff
@@ -38,7 +41,7 @@ end
38-- (thanks to Wim Couwenberg) 41-- (thanks to Wim Couwenberg)
39function filter.chain(...) 42function filter.chain(...)
40 local arg = {...} 43 local arg = {...}
41 local n = #arg 44 local n = select('#',...)
42 local top, index = 1, 1 45 local top, index = 1, 1
43 local retry = "" 46 local retry = ""
44 return function(chunk) 47 return function(chunk)
@@ -89,7 +92,7 @@ end
89function source.file(handle, io_err) 92function source.file(handle, io_err)
90 if handle then 93 if handle then
91 return function() 94 return function()
92 local chunk = handle:read(BLOCKSIZE) 95 local chunk = handle:read(_M.BLOCKSIZE)
93 if not chunk then handle:close() end 96 if not chunk then handle:close() end
94 return chunk 97 return chunk
95 end 98 end
@@ -112,8 +115,8 @@ function source.string(s)
112 if s then 115 if s then
113 local i = 1 116 local i = 1
114 return function() 117 return function()
115 local chunk = string.sub(s, i, i+BLOCKSIZE-1) 118 local chunk = string.sub(s, i, i+_M.BLOCKSIZE-1)
116 i = i + BLOCKSIZE 119 i = i + _M.BLOCKSIZE
117 if chunk ~= "" then return chunk 120 if chunk ~= "" then return chunk
118 else return nil end 121 else return nil end
119 end 122 end
@@ -291,3 +294,4 @@ function pump.all(src, snk, step)
291 end 294 end
292end 295end
293 296
297return _M \ No newline at end of file
diff --git a/src/luasocket.c b/src/luasocket.c
index b43114e..bea23d7 100644
--- a/src/luasocket.c
+++ b/src/luasocket.c
@@ -18,9 +18,6 @@
18#include "lua.h" 18#include "lua.h"
19#include "lauxlib.h" 19#include "lauxlib.h"
20 20
21#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501)
22#include "compat-5.1.h"
23#endif
24 21
25/*=========================================================================*\ 22/*=========================================================================*\
26* LuaSocket includes 23* LuaSocket includes
@@ -81,6 +78,34 @@ static int global_unload(lua_State *L) {
81 return 0; 78 return 0;
82} 79}
83 80
81#if LUA_VERSION_NUM > 501
82
83int luaL_typerror (lua_State *L, int narg, const char *tname) {
84 const char *msg = lua_pushfstring(L, "%s expected, got %s",
85 tname, luaL_typename(L, narg));
86 return luaL_argerror(L, narg, msg);
87}
88
89#if ! defined(LUA_COMPAT_MODULE)
90void luaL_openlib(lua_State *L, const char *name, const luaL_Reg *funcs, int idx) {
91 if (name != NULL) {
92#ifdef LUASOCKET_USE_GLOBAL
93 lua_getglobal(L,name);
94 if (lua_isnil(L,-1)) {
95 lua_newtable(L);
96 lua_setglobal(L,name);
97 lua_getglobal(L,name);
98 }
99#else
100 lua_newtable(L);
101#endif
102 }
103 luaL_setfuncs(L,funcs,0);
104}
105#endif
106
107#endif
108
84/*-------------------------------------------------------------------------*\ 109/*-------------------------------------------------------------------------*\
85* Setup basic stuff. 110* Setup basic stuff.
86\*-------------------------------------------------------------------------*/ 111\*-------------------------------------------------------------------------*/
diff --git a/src/luasocket.h b/src/luasocket.h
index f2ca3c1..f4463a7 100644
--- a/src/luasocket.h
+++ b/src/luasocket.h
@@ -22,10 +22,6 @@
22#define LUASOCKET_API extern 22#define LUASOCKET_API extern
23#endif 23#endif
24 24
25#if LUA_VERSION_NUM > 501 & !( defined LUA_COMPAT_MODULE)
26# error Lua 5.2 requires LUA_COMPAT_MODULE defined for luaL_openlib
27#endif
28
29/*-------------------------------------------------------------------------*\ 25/*-------------------------------------------------------------------------*\
30* Initializes the library. 26* Initializes the library.
31\*-------------------------------------------------------------------------*/ 27\*-------------------------------------------------------------------------*/
diff --git a/src/mbox.lua b/src/mbox.lua
index 35adf4e..2ce24fa 100644
--- a/src/mbox.lua
+++ b/src/mbox.lua
@@ -86,3 +86,5 @@ function Public.parse_message(message_s)
86 message.headers = Public.parse_headers(message.headers) 86 message.headers = Public.parse_headers(message.headers)
87 return message 87 return message
88end 88end
89
90return mbox \ No newline at end of file
diff --git a/src/mime.c b/src/mime.c
index dddd3d6..ea8876e 100644
--- a/src/mime.c
+++ b/src/mime.c
@@ -81,7 +81,16 @@ static UC b64unbase[256];
81\*-------------------------------------------------------------------------*/ 81\*-------------------------------------------------------------------------*/
82MIME_API int luaopen_mime_core(lua_State *L) 82MIME_API int luaopen_mime_core(lua_State *L)
83{ 83{
84#if LUA_VERSION_NUM > 501
85 lua_newtable(L);
86#ifdef LUASOCKET_USE_GLOBAL
87 lua_setglobal(L,"mime");
88 lua_getglobal(L,"mime");
89#endif
90 luaL_setfuncs(L,func,0);
91#else
84 luaL_openlib(L, "mime", func, 0); 92 luaL_openlib(L, "mime", func, 0);
93#endif
85 /* make version string available to scripts */ 94 /* make version string available to scripts */
86 lua_pushstring(L, "_VERSION"); 95 lua_pushstring(L, "_VERSION");
87 lua_pushstring(L, MIME_VERSION); 96 lua_pushstring(L, MIME_VERSION);
diff --git a/src/mime.lua b/src/mime.lua
index 4aaccc8..642cd9c 100644
--- a/src/mime.lua
+++ b/src/mime.lua
@@ -10,13 +10,16 @@
10local base = _G 10local base = _G
11local ltn12 = require("ltn12") 11local ltn12 = require("ltn12")
12local mime = require("mime.core") 12local mime = require("mime.core")
13local io = require("io")
13local string = require("string") 14local string = require("string")
14module("mime") 15local _M = mime
15 16
16-- encode, decode and wrap algorithm tables 17-- encode, decode and wrap algorithm tables
17encodet = {} 18local encodet, decodet, wrapt = {},{},{}
18decodet = {} 19
19wrapt = {} 20_M.encodet = encodet
21_M.decodet = decodet
22_M.wrapt = wrapt
20 23
21-- creates a function that chooses a filter by name from a given table 24-- creates a function that chooses a filter by name from a given table
22local function choose(table) 25local function choose(table)
@@ -33,21 +36,21 @@ end
33 36
34-- define the encoding filters 37-- define the encoding filters
35encodet['base64'] = function() 38encodet['base64'] = function()
36 return ltn12.filter.cycle(b64, "") 39 return ltn12.filter.cycle(_M.b64, "")
37end 40end
38 41
39encodet['quoted-printable'] = function(mode) 42encodet['quoted-printable'] = function(mode)
40 return ltn12.filter.cycle(qp, "", 43 return ltn12.filter.cycle(_M.qp, "",
41 (mode == "binary") and "=0D=0A" or "\r\n") 44 (mode == "binary") and "=0D=0A" or "\r\n")
42end 45end
43 46
44-- define the decoding filters 47-- define the decoding filters
45decodet['base64'] = function() 48decodet['base64'] = function()
46 return ltn12.filter.cycle(unb64, "") 49 return ltn12.filter.cycle(_M.unb64, "")
47end 50end
48 51
49decodet['quoted-printable'] = function() 52decodet['quoted-printable'] = function()
50 return ltn12.filter.cycle(unqp, "") 53 return ltn12.filter.cycle(_M.unqp, "")
51end 54end
52 55
53local function format(chunk) 56local function format(chunk)
@@ -60,26 +63,28 @@ end
60-- define the line-wrap filters 63-- define the line-wrap filters
61wrapt['text'] = function(length) 64wrapt['text'] = function(length)
62 length = length or 76 65 length = length or 76
63 return ltn12.filter.cycle(wrp, length, length) 66 return ltn12.filter.cycle(_M.wrp, length, length)
64end 67end
65wrapt['base64'] = wrapt['text'] 68wrapt['base64'] = wrapt['text']
66wrapt['default'] = wrapt['text'] 69wrapt['default'] = wrapt['text']
67 70
68wrapt['quoted-printable'] = function() 71wrapt['quoted-printable'] = function()
69 return ltn12.filter.cycle(qpwrp, 76, 76) 72 return ltn12.filter.cycle(_M.qpwrp, 76, 76)
70end 73end
71 74
72-- function that choose the encoding, decoding or wrap algorithm 75-- function that choose the encoding, decoding or wrap algorithm
73encode = choose(encodet) 76_M.encode = choose(encodet)
74decode = choose(decodet) 77_M.decode = choose(decodet)
75wrap = choose(wrapt) 78_M.wrap = choose(wrapt)
76 79
77-- define the end-of-line normalization filter 80-- define the end-of-line normalization filter
78function normalize(marker) 81function _M.normalize(marker)
79 return ltn12.filter.cycle(eol, 0, marker) 82 return ltn12.filter.cycle(_M.eol, 0, marker)
80end 83end
81 84
82-- high level stuffing filter 85-- high level stuffing filter
83function stuff() 86function _M.stuff()
84 return ltn12.filter.cycle(dot, 2) 87 return ltn12.filter.cycle(_M.dot, 2)
85end 88end
89
90return _M \ No newline at end of file
diff --git a/src/smtp.lua b/src/smtp.lua
index 896b536..b113d00 100644
--- a/src/smtp.lua
+++ b/src/smtp.lua
@@ -17,22 +17,24 @@ local tp = require("socket.tp")
17local ltn12 = require("ltn12") 17local ltn12 = require("ltn12")
18local headers = require("socket.headers") 18local headers = require("socket.headers")
19local mime = require("mime") 19local mime = require("mime")
20module("socket.smtp") 20
21socket.smtp = {}
22local _M = socket.smtp
21 23
22----------------------------------------------------------------------------- 24-----------------------------------------------------------------------------
23-- Program constants 25-- Program constants
24----------------------------------------------------------------------------- 26-----------------------------------------------------------------------------
25-- timeout for connection 27-- timeout for connection
26TIMEOUT = 60 28_M.TIMEOUT = 60
27-- default server used to send e-mails 29-- default server used to send e-mails
28SERVER = "localhost" 30_M.SERVER = "localhost"
29-- default port 31-- default port
30PORT = 25 32_M.PORT = 25
31-- domain used in HELO command and default sendmail 33-- domain used in HELO command and default sendmail
32-- If we are under a CGI, try to get from environment 34-- If we are under a CGI, try to get from environment
33DOMAIN = os.getenv("SERVER_NAME") or "localhost" 35_M.DOMAIN = os.getenv("SERVER_NAME") or "localhost"
34-- default time zone (means we don't know) 36-- default time zone (means we don't know)
35ZONE = "-0000" 37_M.ZONE = "-0000"
36 38
37--------------------------------------------------------------------------- 39---------------------------------------------------------------------------
38-- Low level SMTP API 40-- Low level SMTP API
@@ -41,7 +43,7 @@ local metat = { __index = {} }
41 43
42function metat.__index:greet(domain) 44function metat.__index:greet(domain)
43 self.try(self.tp:check("2..")) 45 self.try(self.tp:check("2.."))
44 self.try(self.tp:command("EHLO", domain or DOMAIN)) 46 self.try(self.tp:command("EHLO", domain or _M.DOMAIN))
45 return socket.skip(1, self.try(self.tp:check("2.."))) 47 return socket.skip(1, self.try(self.tp:check("2..")))
46end 48end
47 49
@@ -111,9 +113,9 @@ function metat.__index:send(mailt)
111 self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step) 113 self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step)
112end 114end
113 115
114function open(server, port, create) 116function _M.open(server, port, create)
115 local tp = socket.try(tp.connect(server or SERVER, port or PORT, 117 local tp = socket.try(tp.connect(server or _M.SERVER, port or _M.PORT,
116 TIMEOUT, create)) 118 _M.TIMEOUT, create))
117 local s = base.setmetatable({tp = tp}, metat) 119 local s = base.setmetatable({tp = tp}, metat)
118 -- make sure tp is closed if we get an exception 120 -- make sure tp is closed if we get an exception
119 s.try = socket.newtry(function() 121 s.try = socket.newtry(function()
@@ -221,14 +223,14 @@ end
221local function adjust_headers(mesgt) 223local function adjust_headers(mesgt)
222 local lower = lower_headers(mesgt.headers) 224 local lower = lower_headers(mesgt.headers)
223 lower["date"] = lower["date"] or 225 lower["date"] = lower["date"] or
224 os.date("!%a, %d %b %Y %H:%M:%S ") .. (mesgt.zone or ZONE) 226 os.date("!%a, %d %b %Y %H:%M:%S ") .. (mesgt.zone or _M.ZONE)
225 lower["x-mailer"] = lower["x-mailer"] or socket._VERSION 227 lower["x-mailer"] = lower["x-mailer"] or socket._VERSION
226 -- this can't be overriden 228 -- this can't be overriden
227 lower["mime-version"] = "1.0" 229 lower["mime-version"] = "1.0"
228 return lower 230 return lower
229end 231end
230 232
231function message(mesgt) 233function _M.message(mesgt)
232 mesgt.headers = adjust_headers(mesgt) 234 mesgt.headers = adjust_headers(mesgt)
233 -- create and return message source 235 -- create and return message source
234 local co = coroutine.create(function() send_message(mesgt) end) 236 local co = coroutine.create(function() send_message(mesgt) end)
@@ -242,11 +244,13 @@ end
242--------------------------------------------------------------------------- 244---------------------------------------------------------------------------
243-- High level SMTP API 245-- High level SMTP API
244----------------------------------------------------------------------------- 246-----------------------------------------------------------------------------
245send = socket.protect(function(mailt) 247_M.send = socket.protect(function(mailt)
246 local s = open(mailt.server, mailt.port, mailt.create) 248 local s = _M.open(mailt.server, mailt.port, mailt.create)
247 local ext = s:greet(mailt.domain) 249 local ext = s:greet(mailt.domain)
248 s:auth(mailt.user, mailt.password, ext) 250 s:auth(mailt.user, mailt.password, ext)
249 s:send(mailt) 251 s:send(mailt)
250 s:quit() 252 s:quit()
251 return s:close() 253 return s:close()
252end) 254end)
255
256return _M \ No newline at end of file
diff --git a/src/socket.lua b/src/socket.lua
index e8def75..f2fb8a3 100644
--- a/src/socket.lua
+++ b/src/socket.lua
@@ -10,20 +10,21 @@ local base = _G
10local string = require("string") 10local string = require("string")
11local math = require("math") 11local math = require("math")
12local socket = require("socket.core") 12local socket = require("socket.core")
13module("socket") 13
14local _M = socket
14 15
15----------------------------------------------------------------------------- 16-----------------------------------------------------------------------------
16-- Exported auxiliar functions 17-- Exported auxiliar functions
17----------------------------------------------------------------------------- 18-----------------------------------------------------------------------------
18function connect4(address, port, laddress, lport) 19function _M.connect4(address, port, laddress, lport)
19 return socket.connect(address, port, laddress, lport, "inet") 20 return socket.connect(address, port, laddress, lport, "inet")
20end 21end
21 22
22function connect6(address, port, laddress, lport) 23function _M.connect6(address, port, laddress, lport)
23 return socket.connect(address, port, laddress, lport, "inet6") 24 return socket.connect(address, port, laddress, lport, "inet6")
24end 25end
25 26
26function bind(host, port, backlog) 27function _M.bind(host, port, backlog)
27 if host == "*" then host = "0.0.0.0" end 28 if host == "*" then host = "0.0.0.0" end
28 local addrinfo, err = socket.dns.getaddrinfo(host); 29 local addrinfo, err = socket.dns.getaddrinfo(host);
29 if not addrinfo then return nil, err end 30 if not addrinfo then return nil, err end
@@ -52,9 +53,9 @@ function bind(host, port, backlog)
52 return nil, err 53 return nil, err
53end 54end
54 55
55try = newtry() 56_M.try = _M.newtry()
56 57
57function choose(table) 58function _M.choose(table)
58 return function(name, opt1, opt2) 59 return function(name, opt1, opt2)
59 if base.type(name) ~= "string" then 60 if base.type(name) ~= "string" then
60 name, opt1, opt2 = "default", name, opt1 61 name, opt1, opt2 = "default", name, opt1
@@ -69,10 +70,11 @@ end
69-- Socket sources and sinks, conforming to LTN12 70-- Socket sources and sinks, conforming to LTN12
70----------------------------------------------------------------------------- 71-----------------------------------------------------------------------------
71-- create namespaces inside LuaSocket namespace 72-- create namespaces inside LuaSocket namespace
72sourcet = {} 73local sourcet, sinkt = {}, {}
73sinkt = {} 74_M.sourcet = sourcet
75_M.sinkt = sinkt
74 76
75BLOCKSIZE = 2048 77_M.BLOCKSIZE = 2048
76 78
77sinkt["close-when-done"] = function(sock) 79sinkt["close-when-done"] = function(sock)
78 return base.setmetatable({ 80 return base.setmetatable({
@@ -102,7 +104,7 @@ end
102 104
103sinkt["default"] = sinkt["keep-open"] 105sinkt["default"] = sinkt["keep-open"]
104 106
105sink = choose(sinkt) 107_M.sink = _M.choose(sinkt)
106 108
107sourcet["by-length"] = function(sock, length) 109sourcet["by-length"] = function(sock, length)
108 return base.setmetatable({ 110 return base.setmetatable({
@@ -142,5 +144,6 @@ end
142 144
143sourcet["default"] = sourcet["until-closed"] 145sourcet["default"] = sourcet["until-closed"]
144 146
145source = choose(sourcet) 147_M.source = _M.choose(sourcet)
146 148
149return _M \ No newline at end of file
diff --git a/src/tp.lua b/src/tp.lua
index 2ffe9a4..cbeff56 100644
--- a/src/tp.lua
+++ b/src/tp.lua
@@ -11,12 +11,14 @@ local base = _G
11local string = require("string") 11local string = require("string")
12local socket = require("socket") 12local socket = require("socket")
13local ltn12 = require("ltn12") 13local ltn12 = require("ltn12")
14module("socket.tp") 14
15socket.tp = {}
16local _M = socket.tp
15 17
16----------------------------------------------------------------------------- 18-----------------------------------------------------------------------------
17-- Program constants 19-- Program constants
18----------------------------------------------------------------------------- 20-----------------------------------------------------------------------------
19TIMEOUT = 60 21_M.TIMEOUT = 60
20 22
21----------------------------------------------------------------------------- 23-----------------------------------------------------------------------------
22-- Implementation 24-- Implementation
@@ -109,10 +111,10 @@ function metat.__index:close()
109end 111end
110 112
111-- connect with server and return c object 113-- connect with server and return c object
112function connect(host, port, timeout, create) 114function _M.connect(host, port, timeout, create)
113 local c, e = (create or socket.tcp)() 115 local c, e = (create or socket.tcp)()
114 if not c then return nil, e end 116 if not c then return nil, e end
115 c:settimeout(timeout or TIMEOUT) 117 c:settimeout(timeout or _M.TIMEOUT)
116 local r, e = c:connect(host, port) 118 local r, e = c:connect(host, port)
117 if not r then 119 if not r then
118 c:close() 120 c:close()
@@ -121,3 +123,4 @@ function connect(host, port, timeout, create)
121 return base.setmetatable({c = c}, metat) 123 return base.setmetatable({c = c}, metat)
122end 124end
123 125
126return _M \ No newline at end of file
diff --git a/src/url.lua b/src/url.lua
index 6ca6d68..3c4f85d 100644
--- a/src/url.lua
+++ b/src/url.lua
@@ -10,12 +10,15 @@
10local string = require("string") 10local string = require("string")
11local base = _G 11local base = _G
12local table = require("table") 12local table = require("table")
13module("socket.url") 13local socket = require("socket")
14
15socket.url = {}
16local _M = socket.url
14 17
15----------------------------------------------------------------------------- 18-----------------------------------------------------------------------------
16-- Module version 19-- Module version
17----------------------------------------------------------------------------- 20-----------------------------------------------------------------------------
18_VERSION = "URL 1.0.2" 21_M._VERSION = "URL 1.0.2"
19 22
20----------------------------------------------------------------------------- 23-----------------------------------------------------------------------------
21-- Encodes a string into its escaped hexadecimal representation 24-- Encodes a string into its escaped hexadecimal representation
@@ -24,7 +27,7 @@ _VERSION = "URL 1.0.2"
24-- Returns 27-- Returns
25-- escaped representation of string binary 28-- escaped representation of string binary
26----------------------------------------------------------------------------- 29-----------------------------------------------------------------------------
27function escape(s) 30function _M.escape(s)
28 return (string.gsub(s, "([^A-Za-z0-9_])", function(c) 31 return (string.gsub(s, "([^A-Za-z0-9_])", function(c)
29 return string.format("%%%02x", string.byte(c)) 32 return string.format("%%%02x", string.byte(c))
30 end)) 33 end))
@@ -67,7 +70,7 @@ end
67-- Returns 70-- Returns
68-- escaped representation of string binary 71-- escaped representation of string binary
69----------------------------------------------------------------------------- 72-----------------------------------------------------------------------------
70function unescape(s) 73function _M.unescape(s)
71 return (string.gsub(s, "%%(%x%x)", function(hex) 74 return (string.gsub(s, "%%(%x%x)", function(hex)
72 return string.char(base.tonumber(hex, 16)) 75 return string.char(base.tonumber(hex, 16))
73 end)) 76 end))
@@ -120,7 +123,7 @@ end
120-- Obs: 123-- Obs:
121-- the leading '/' in {/<path>} is considered part of <path> 124-- the leading '/' in {/<path>} is considered part of <path>
122----------------------------------------------------------------------------- 125-----------------------------------------------------------------------------
123function parse(url, default) 126function _M.parse(url, default)
124 -- initialize default parameters 127 -- initialize default parameters
125 local parsed = {} 128 local parsed = {}
126 for i,v in base.pairs(default or parsed) do parsed[i] = v end 129 for i,v in base.pairs(default or parsed) do parsed[i] = v end
@@ -179,9 +182,9 @@ end
179-- Returns 182-- Returns
180-- a stringing with the corresponding URL 183-- a stringing with the corresponding URL
181----------------------------------------------------------------------------- 184-----------------------------------------------------------------------------
182function build(parsed) 185function _M.build(parsed)
183 local ppath = parse_path(parsed.path or "") 186 local ppath = _M.parse_path(parsed.path or "")
184 local url = build_path(ppath) 187 local url = _M.build_path(ppath)
185 if parsed.params then url = url .. ";" .. parsed.params end 188 if parsed.params then url = url .. ";" .. parsed.params end
186 if parsed.query then url = url .. "?" .. parsed.query end 189 if parsed.query then url = url .. "?" .. parsed.query end
187 local authority = parsed.authority 190 local authority = parsed.authority
@@ -215,14 +218,14 @@ end
215-- Returns 218-- Returns
216-- corresponding absolute url 219-- corresponding absolute url
217----------------------------------------------------------------------------- 220-----------------------------------------------------------------------------
218function absolute(base_url, relative_url) 221function _M.absolute(base_url, relative_url)
219 if base.type(base_url) == "table" then 222 if base.type(base_url) == "table" then
220 base_parsed = base_url 223 base_parsed = base_url
221 base_url = build(base_parsed) 224 base_url = _M.build(base_parsed)
222 else 225 else
223 base_parsed = parse(base_url) 226 base_parsed = _M.parse(base_url)
224 end 227 end
225 local relative_parsed = parse(relative_url) 228 local relative_parsed = _M.parse(relative_url)
226 if not base_parsed then return relative_url 229 if not base_parsed then return relative_url
227 elseif not relative_parsed then return base_url 230 elseif not relative_parsed then return base_url
228 elseif relative_parsed.scheme then return relative_url 231 elseif relative_parsed.scheme then return relative_url
@@ -243,7 +246,7 @@ function absolute(base_url, relative_url)
243 relative_parsed.path) 246 relative_parsed.path)
244 end 247 end
245 end 248 end
246 return build(relative_parsed) 249 return _M.build(relative_parsed)
247 end 250 end
248end 251end
249 252
@@ -254,13 +257,13 @@ end
254-- Returns 257-- Returns
255-- segment: a table with one entry per segment 258-- segment: a table with one entry per segment
256----------------------------------------------------------------------------- 259-----------------------------------------------------------------------------
257function parse_path(path) 260function _M.parse_path(path)
258 local parsed = {} 261 local parsed = {}
259 path = path or "" 262 path = path or ""
260 --path = string.gsub(path, "%s", "") 263 --path = string.gsub(path, "%s", "")
261 string.gsub(path, "([^/]+)", function (s) table.insert(parsed, s) end) 264 string.gsub(path, "([^/]+)", function (s) table.insert(parsed, s) end)
262 for i = 1, #parsed do 265 for i = 1, #parsed do
263 parsed[i] = unescape(parsed[i]) 266 parsed[i] = _M.unescape(parsed[i])
264 end 267 end
265 if string.sub(path, 1, 1) == "/" then parsed.is_absolute = 1 end 268 if string.sub(path, 1, 1) == "/" then parsed.is_absolute = 1 end
266 if string.sub(path, -1, -1) == "/" then parsed.is_directory = 1 end 269 if string.sub(path, -1, -1) == "/" then parsed.is_directory = 1 end
@@ -275,7 +278,7 @@ end
275-- Returns 278-- Returns
276-- path: corresponding path stringing 279-- path: corresponding path stringing
277----------------------------------------------------------------------------- 280-----------------------------------------------------------------------------
278function build_path(parsed, unsafe) 281function _M.build_path(parsed, unsafe)
279 local path = "" 282 local path = ""
280 local n = #parsed 283 local n = #parsed
281 if unsafe then 284 if unsafe then
@@ -300,3 +303,5 @@ function build_path(parsed, unsafe)
300 if parsed.is_absolute then path = "/" .. path end 303 if parsed.is_absolute then path = "/" .. path end
301 return path 304 return path
302end 305end
306
307return _M \ No newline at end of file
diff --git a/test/hello.lua b/test/hello.lua
index cfa5c82..3f385dc 100644
--- a/test/hello.lua
+++ b/test/hello.lua
@@ -1,3 +1,3 @@
1require"socket" 1local socket = require"socket"
2require"mime" 2local mime = require"mime"
3print("Hello from " .. socket._VERSION .. " and " .. mime._VERSION .. "!") 3print("Hello from " .. socket._VERSION .. " and " .. mime._VERSION .. "!")