aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buffer.c4
-rw-r--r--src/except.c26
-rw-r--r--src/ftp.lua53
-rw-r--r--src/http.lua23
-rw-r--r--src/ltn12.lua22
-rw-r--r--src/mime.lua11
-rw-r--r--src/smtp.lua25
-rw-r--r--src/tcp.c3
-rw-r--r--src/tp.lua29
-rw-r--r--src/udp.c3
-rw-r--r--src/url.lua15
-rw-r--r--src/wsocket.c15
12 files changed, 159 insertions, 70 deletions
diff --git a/src/buffer.c b/src/buffer.c
index dbd5d2c..1b1b791 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -158,6 +158,7 @@ int buf_isempty(p_buf buf) {
158/*-------------------------------------------------------------------------*\ 158/*-------------------------------------------------------------------------*\
159* Sends a block of data (unbuffered) 159* Sends a block of data (unbuffered)
160\*-------------------------------------------------------------------------*/ 160\*-------------------------------------------------------------------------*/
161#define STEPSIZE 8192
161static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent) { 162static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent) {
162 p_io io = buf->io; 163 p_io io = buf->io;
163 p_tm tm = buf->tm; 164 p_tm tm = buf->tm;
@@ -165,7 +166,8 @@ static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent) {
165 int err = IO_DONE; 166 int err = IO_DONE;
166 while (total < count && err == IO_DONE) { 167 while (total < count && err == IO_DONE) {
167 size_t done; 168 size_t done;
168 err = io->send(io->ctx, data+total, count-total, &done, tm); 169 size_t step = (count-total <= STEPSIZE)? count-total: STEPSIZE;
170 err = io->send(io->ctx, data+total, step, &done, tm);
169 total += done; 171 total += done;
170 } 172 }
171 *sent = total; 173 *sent = total;
diff --git a/src/except.c b/src/except.c
index 80d7e5d..dabaf19 100644
--- a/src/except.c
+++ b/src/except.c
@@ -29,11 +29,21 @@ static luaL_reg func[] = {
29/*-------------------------------------------------------------------------*\ 29/*-------------------------------------------------------------------------*\
30* Try factory 30* Try factory
31\*-------------------------------------------------------------------------*/ 31\*-------------------------------------------------------------------------*/
32static void wrap(lua_State *L) {
33 lua_newtable(L);
34 lua_pushnumber(L, 1);
35 lua_pushvalue(L, -3);
36 lua_settable(L, -3);
37 lua_insert(L, -2);
38 lua_pop(L, 1);
39}
40
32static int finalize(lua_State *L) { 41static int finalize(lua_State *L) {
33 if (!lua_toboolean(L, 1)) { 42 if (!lua_toboolean(L, 1)) {
34 lua_pushvalue(L, lua_upvalueindex(1)); 43 lua_pushvalue(L, lua_upvalueindex(1));
35 lua_pcall(L, 0, 0, 0); 44 lua_pcall(L, 0, 0, 0);
36 lua_settop(L, 2); 45 lua_settop(L, 2);
46 wrap(L);
37 lua_error(L); 47 lua_error(L);
38 return 0; 48 return 0;
39 } else return lua_gettop(L); 49 } else return lua_gettop(L);
@@ -54,13 +64,23 @@ static int global_newtry(lua_State *L) {
54/*-------------------------------------------------------------------------*\ 64/*-------------------------------------------------------------------------*\
55* Protect factory 65* Protect factory
56\*-------------------------------------------------------------------------*/ 66\*-------------------------------------------------------------------------*/
67static int unwrap(lua_State *L) {
68 if (lua_istable(L, -1)) {
69 lua_pushnumber(L, 1);
70 lua_gettable(L, -2);
71 lua_pushnil(L);
72 lua_insert(L, -2);
73 return 1;
74 } else return 0;
75}
76
57static int protected_(lua_State *L) { 77static int protected_(lua_State *L) {
58 lua_pushvalue(L, lua_upvalueindex(1)); 78 lua_pushvalue(L, lua_upvalueindex(1));
59 lua_insert(L, 1); 79 lua_insert(L, 1);
60 if (lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0) != 0) { 80 if (lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0) != 0) {
61 lua_pushnil(L); 81 if (unwrap(L)) return 2;
62 lua_insert(L, 1); 82 else lua_error(L);
63 return 2; 83 return 0;
64 } else return lua_gettop(L); 84 } else return lua_gettop(L);
65} 85}
66 86
diff --git a/src/ftp.lua b/src/ftp.lua
index 9902c88..4529acd 100644
--- a/src/ftp.lua
+++ b/src/ftp.lua
@@ -8,13 +8,15 @@
8----------------------------------------------------------------------------- 8-----------------------------------------------------------------------------
9-- Declare module and import dependencies 9-- Declare module and import dependencies
10----------------------------------------------------------------------------- 10-----------------------------------------------------------------------------
11local base = require("base")
12local table = require("table")
13local string = require("string")
14local math = require("math")
11local socket = require("socket") 15local socket = require("socket")
12local url = require("socket.url") 16local url = require("socket.url")
13local tp = require("socket.tp") 17local tp = require("socket.tp")
14
15local ltn12 = require("ltn12") 18local ltn12 = require("ltn12")
16 19local ftp = module("socket.ftp")
17module("socket.ftp")
18 20
19----------------------------------------------------------------------------- 21-----------------------------------------------------------------------------
20-- Program constants 22-- Program constants
@@ -35,7 +37,7 @@ local metat = { __index = {} }
35 37
36function open(server, port) 38function open(server, port)
37 local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT)) 39 local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT))
38 local f = setmetatable({ tp = tp }, metat) 40 local f = base.setmetatable({ tp = tp }, metat)
39 -- make sure everything gets closed in an exception 41 -- make sure everything gets closed in an exception
40 f.try = socket.newtry(function() f:close() end) 42 f.try = socket.newtry(function() f:close() end)
41 return f 43 return f
@@ -102,7 +104,8 @@ function metat.__index:send(sendt)
102 -- we just get the data connection into self.data 104 -- we just get the data connection into self.data
103 if self.pasvt then self:pasvconnect() end 105 if self.pasvt then self:pasvconnect() end
104 -- get the transfer argument and command 106 -- get the transfer argument and command
105 local argument = sendt.argument or string.gsub(sendt.path, "^/", "") 107 local argument = sendt.argument or
108 url.unescape(string.gsub(sendt.path or "", "^/", ""))
106 if argument == "" then argument = nil end 109 if argument == "" then argument = nil end
107 local command = sendt.command or "stor" 110 local command = sendt.command or "stor"
108 -- send the transfer command and check the reply 111 -- send the transfer command and check the reply
@@ -134,7 +137,8 @@ end
134function metat.__index:receive(recvt) 137function metat.__index:receive(recvt)
135 self.try(self.pasvt or self.server, "need port or pasv first") 138 self.try(self.pasvt or self.server, "need port or pasv first")
136 if self.pasvt then self:pasvconnect() end 139 if self.pasvt then self:pasvconnect() end
137 local argument = recvt.argument or string.gsub(recvt.path, "^/", "") 140 local argument = recvt.argument or
141 url.unescape(string.gsub(recvt.path or "", "^/", ""))
138 if argument == "" then argument = nil end 142 if argument == "" then argument = nil end
139 local command = recvt.command or "retr" 143 local command = recvt.command or "retr"
140 self.try(self.tp:command(command, argument)) 144 self.try(self.tp:command(command, argument))
@@ -182,7 +186,19 @@ end
182----------------------------------------------------------------------------- 186-----------------------------------------------------------------------------
183-- High level FTP API 187-- High level FTP API
184----------------------------------------------------------------------------- 188-----------------------------------------------------------------------------
189function override(t)
190 if t.url then
191 u = url.parse(t.url)
192 for i,v in base.pairs(t) do
193 u[i] = v
194 end
195 return u
196 else return t end
197end
198
185local function tput(putt) 199local function tput(putt)
200 putt = override(putt)
201 socket.try(putt.host, "missing hostname")
186 local f = open(putt.host, putt.port) 202 local f = open(putt.host, putt.port)
187 f:greet() 203 f:greet()
188 f:login(putt.user, putt.password) 204 f:login(putt.user, putt.password)
@@ -201,8 +217,8 @@ local default = {
201 217
202local function parse(u) 218local function parse(u)
203 local t = socket.try(url.parse(u, default)) 219 local t = socket.try(url.parse(u, default))
204 socket.try(t.scheme == "ftp", "invalid scheme '" .. t.scheme .. "'") 220 socket.try(t.scheme == "ftp", "wrong scheme '" .. t.scheme .. "'")
205 socket.try(t.host, "invalid host") 221 socket.try(t.host, "missing hostname")
206 local pat = "^type=(.)$" 222 local pat = "^type=(.)$"
207 if t.params then 223 if t.params then
208 t.type = socket.skip(2, string.find(t.params, pat)) 224 t.type = socket.skip(2, string.find(t.params, pat))
@@ -219,11 +235,13 @@ local function sput(u, body)
219end 235end
220 236
221put = socket.protect(function(putt, body) 237put = socket.protect(function(putt, body)
222 if type(putt) == "string" then return sput(putt, body) 238 if base.type(putt) == "string" then return sput(putt, body)
223 else return tput(putt) end 239 else return tput(putt) end
224end) 240end)
225 241
226local function tget(gett) 242local function tget(gett)
243 gett = override(gett)
244 socket.try(gett.host, "missing hostname")
227 local f = open(gett.host, gett.port) 245 local f = open(gett.host, gett.port)
228 f:greet() 246 f:greet()
229 f:login(gett.user, gett.password) 247 f:login(gett.user, gett.password)
@@ -242,7 +260,22 @@ local function sget(u)
242 return table.concat(t) 260 return table.concat(t)
243end 261end
244 262
263command = socket.protect(function(cmdt)
264 cmdt = override(cmdt)
265 socket.try(cmdt.host, "missing hostname")
266 socket.try(cmdt.command, "missing command")
267 local f = open(cmdt.host, cmdt.port)
268 f:greet()
269 f:login(cmdt.user, cmdt.password)
270 f.try(f.tp:command(cmdt.command, cmdt.argument))
271 if cmdt.check then f.try(f.tp:check(cmdt.check)) end
272 f:quit()
273 return f:close()
274end)
275
245get = socket.protect(function(gett) 276get = socket.protect(function(gett)
246 if type(gett) == "string" then return sget(gett) 277 if base.type(gett) == "string" then return sget(gett)
247 else return tget(gett) end 278 else return tget(gett) end
248end) 279end)
280
281base.setmetatable(ftp, nil)
diff --git a/src/http.lua b/src/http.lua
index b265650..a15ea69 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -12,8 +12,10 @@ local socket = require("socket")
12local url = require("socket.url") 12local url = require("socket.url")
13local ltn12 = require("ltn12") 13local ltn12 = require("ltn12")
14local mime = require("mime") 14local mime = require("mime")
15 15local string = require("string")
16module("socket.http") 16local base = require("base")
17local table = require("table")
18local http = module("socket.http")
17 19
18----------------------------------------------------------------------------- 20-----------------------------------------------------------------------------
19-- Program constants 21-- Program constants
@@ -32,7 +34,7 @@ local metat = { __index = {} }
32 34
33function open(host, port) 35function open(host, port)
34 local c = socket.try(socket.tcp()) 36 local c = socket.try(socket.tcp())
35 local h = setmetatable({ c = c }, metat) 37 local h = base.setmetatable({ c = c }, metat)
36 -- make sure the connection gets closed on exception 38 -- make sure the connection gets closed on exception
37 h.try = socket.newtry(function() h:close() end) 39 h.try = socket.newtry(function() h:close() end)
38 h.try(c:settimeout(TIMEOUT)) 40 h.try(c:settimeout(TIMEOUT))
@@ -46,7 +48,7 @@ function metat.__index:sendrequestline(method, uri)
46end 48end
47 49
48function metat.__index:sendheaders(headers) 50function metat.__index:sendheaders(headers)
49 for i, v in pairs(headers) do 51 for i, v in base.pairs(headers) do
50 self.try(self.c:send(i .. ": " .. v .. "\r\n")) 52 self.try(self.c:send(i .. ": " .. v .. "\r\n"))
51 end 53 end
52 -- mark end of request headers 54 -- mark end of request headers
@@ -66,7 +68,7 @@ end
66function metat.__index:receivestatusline() 68function metat.__index:receivestatusline()
67 local status = self.try(self.c:receive()) 69 local status = self.try(self.c:receive())
68 local code = socket.skip(2, string.find(status, "HTTP/%d*%.%d* (%d%d%d)")) 70 local code = socket.skip(2, string.find(status, "HTTP/%d*%.%d* (%d%d%d)"))
69 return self.try(tonumber(code), status) 71 return self.try(base.tonumber(code), status)
70end 72end
71 73
72function metat.__index:receiveheaders() 74function metat.__index:receiveheaders()
@@ -97,11 +99,11 @@ end
97function metat.__index:receivebody(headers, sink, step) 99function metat.__index:receivebody(headers, sink, step)
98 sink = sink or ltn12.sink.null() 100 sink = sink or ltn12.sink.null()
99 step = step or ltn12.pump.step 101 step = step or ltn12.pump.step
100 local length = tonumber(headers["content-length"]) 102 local length = base.tonumber(headers["content-length"])
101 local TE = headers["transfer-encoding"] 103 local TE = headers["transfer-encoding"]
102 local mode = "default" -- connection close 104 local mode = "default" -- connection close
103 if TE and TE ~= "identity" then mode = "http-chunked" 105 if TE and TE ~= "identity" then mode = "http-chunked"
104 elseif tonumber(headers["content-length"]) then mode = "by-length" end 106 elseif base.tonumber(headers["content-length"]) then mode = "by-length" end
105 return self.try(ltn12.pump.all(socket.source(mode, self.c, length), 107 return self.try(ltn12.pump.all(socket.source(mode, self.c, length),
106 sink, step)) 108 sink, step))
107end 109end
@@ -159,9 +161,10 @@ local default = {
159local function adjustrequest(reqt) 161local function adjustrequest(reqt)
160 -- parse url if provided 162 -- parse url if provided
161 local nreqt = reqt.url and url.parse(reqt.url, default) or {} 163 local nreqt = reqt.url and url.parse(reqt.url, default) or {}
164 local t = url.parse(reqt.url, default)
162 -- explicit components override url 165 -- explicit components override url
163 for i,v in reqt do nreqt[i] = reqt[i] end 166 for i,v in reqt do nreqt[i] = reqt[i] end
164 socket.try(nreqt.host, "invalid host '" .. tostring(nreqt.host) .. "'") 167 socket.try(nreqt.host, "invalid host '" .. base.tostring(nreqt.host) .. "'")
165 -- compute uri if user hasn't overriden 168 -- compute uri if user hasn't overriden
166 nreqt.uri = reqt.uri or adjusturi(nreqt) 169 nreqt.uri = reqt.uri or adjusturi(nreqt)
167 -- ajust host and port if there is a proxy 170 -- ajust host and port if there is a proxy
@@ -253,6 +256,8 @@ local function srequest(u, body)
253end 256end
254 257
255request = socket.protect(function(reqt, body) 258request = socket.protect(function(reqt, body)
256 if type(reqt) == "string" then return srequest(reqt, body) 259 if base.type(reqt) == "string" then return srequest(reqt, body)
257 else return trequest(reqt) end 260 else return trequest(reqt) end
258end) 261end)
262
263base.setmetatable(http, nil)
diff --git a/src/ltn12.lua b/src/ltn12.lua
index ed39ec8..43c2755 100644
--- a/src/ltn12.lua
+++ b/src/ltn12.lua
@@ -8,7 +8,11 @@
8----------------------------------------------------------------------------- 8-----------------------------------------------------------------------------
9-- Declare module 9-- Declare module
10----------------------------------------------------------------------------- 10-----------------------------------------------------------------------------
11module("ltn12") 11local string = require("string")
12local table = require("table")
13local base = require("base")
14local coroutine = require("coroutine")
15local ltn12 = module("ltn12")
12 16
13filter = {} 17filter = {}
14source = {} 18source = {}
@@ -23,7 +27,7 @@ BLOCKSIZE = 2048
23----------------------------------------------------------------------------- 27-----------------------------------------------------------------------------
24-- returns a high level filter that cycles a low-level filter 28-- returns a high level filter that cycles a low-level filter
25function filter.cycle(low, ctx, extra) 29function filter.cycle(low, ctx, extra)
26 assert(low) 30 base.assert(low)
27 return function(chunk) 31 return function(chunk)
28 local ret 32 local ret
29 ret, ctx = low(ctx, chunk, extra) 33 ret, ctx = low(ctx, chunk, extra)
@@ -121,7 +125,7 @@ end
121 125
122-- turns a fancy source into a simple source 126-- turns a fancy source into a simple source
123function source.simplify(src) 127function source.simplify(src)
124 assert(src) 128 base.assert(src)
125 return function() 129 return function()
126 local chunk, err_or_new = src() 130 local chunk, err_or_new = src()
127 src = err_or_new or src 131 src = err_or_new or src
@@ -145,7 +149,7 @@ end
145 149
146-- creates rewindable source 150-- creates rewindable source
147function source.rewind(src) 151function source.rewind(src)
148 assert(src) 152 base.assert(src)
149 local t = {} 153 local t = {}
150 return function(chunk) 154 return function(chunk)
151 if not chunk then 155 if not chunk then
@@ -160,7 +164,7 @@ end
160 164
161-- chains a source with a filter 165-- chains a source with a filter
162function source.chain(src, f) 166function source.chain(src, f)
163 assert(src and f) 167 base.assert(src and f)
164 local co = coroutine.create(function() 168 local co = coroutine.create(function()
165 while true do 169 while true do
166 local chunk, err = src() 170 local chunk, err = src()
@@ -215,7 +219,7 @@ end
215 219
216-- turns a fancy sink into a simple sink 220-- turns a fancy sink into a simple sink
217function sink.simplify(snk) 221function sink.simplify(snk)
218 assert(snk) 222 base.assert(snk)
219 return function(chunk, err) 223 return function(chunk, err)
220 local ret, err_or_new = snk(chunk, err) 224 local ret, err_or_new = snk(chunk, err)
221 if not ret then return nil, err_or_new end 225 if not ret then return nil, err_or_new end
@@ -254,7 +258,7 @@ end
254 258
255-- chains a sink with a filter 259-- chains a sink with a filter
256function sink.chain(f, snk) 260function sink.chain(f, snk)
257 assert(f and snk) 261 base.assert(f and snk)
258 return function(chunk, err) 262 return function(chunk, err)
259 local filtered = f(chunk) 263 local filtered = f(chunk)
260 local done = chunk and "" 264 local done = chunk and ""
@@ -279,10 +283,12 @@ end
279 283
280-- pumps all data from a source to a sink, using a step function 284-- pumps all data from a source to a sink, using a step function
281function pump.all(src, snk, step) 285function pump.all(src, snk, step)
282 assert(src and snk) 286 base.assert(src and snk)
283 step = step or pump.step 287 step = step or pump.step
284 while true do 288 while true do
285 local ret, err = step(src, snk) 289 local ret, err = step(src, snk)
286 if not ret then return not err, err end 290 if not ret then return not err, err end
287 end 291 end
288end 292end
293
294base.setmetatable(ltn12, nil)
diff --git a/src/mime.lua b/src/mime.lua
index 3dbcf79..712600c 100644
--- a/src/mime.lua
+++ b/src/mime.lua
@@ -8,9 +8,10 @@
8----------------------------------------------------------------------------- 8-----------------------------------------------------------------------------
9-- Declare module and import dependencies 9-- Declare module and import dependencies
10----------------------------------------------------------------------------- 10-----------------------------------------------------------------------------
11module("mime") 11local base = require("base")
12local mime = require("lmime")
13local ltn12 = require("ltn12") 12local ltn12 = require("ltn12")
13local mime = require("lmime")
14module("mime")
14 15
15-- encode, decode and wrap algorithm tables 16-- encode, decode and wrap algorithm tables
16mime.encodet = {} 17mime.encodet = {}
@@ -20,11 +21,11 @@ mime.wrapt = {}
20-- creates a function that chooses a filter by name from a given table 21-- creates a function that chooses a filter by name from a given table
21local function choose(table) 22local function choose(table)
22 return function(name, opt1, opt2) 23 return function(name, opt1, opt2)
23 if type(name) ~= "string" then 24 if base.type(name) ~= "string" then
24 name, opt1, opt2 = "default", name, opt1 25 name, opt1, opt2 = "default", name, opt1
25 end 26 end
26 local f = table[name or "nil"] 27 local f = table[name or "nil"]
27 if not f then error("unknown key (" .. tostring(name) .. ")", 3) 28 if not f then error("unknown key (" .. base.tostring(name) .. ")", 3)
28 else return f(opt1, opt2) end 29 else return f(opt1, opt2) end
29 end 30 end
30end 31end
@@ -74,3 +75,5 @@ end
74function mime.stuff() 75function mime.stuff()
75 return ltn12.filter.cycle(dot, 2) 76 return ltn12.filter.cycle(dot, 2)
76end 77end
78
79base.setmetatable(mime, nil)
diff --git a/src/smtp.lua b/src/smtp.lua
index 974d222..9d49178 100644
--- a/src/smtp.lua
+++ b/src/smtp.lua
@@ -8,13 +8,16 @@
8----------------------------------------------------------------------------- 8-----------------------------------------------------------------------------
9-- Declare module and import dependencies 9-- Declare module and import dependencies
10----------------------------------------------------------------------------- 10-----------------------------------------------------------------------------
11local base = require("base")
12local coroutine = require("coroutine")
13local string = require("string")
14local math = require("math")
15local os = require("os")
11local socket = require("socket") 16local socket = require("socket")
12local tp = require("socket.tp") 17local tp = require("socket.tp")
13
14local ltn12 = require("ltn12") 18local ltn12 = require("ltn12")
15local mime = require("mime") 19local mime = require("mime")
16 20local smtp = module("socket.smtp")
17module("socket.smtp")
18 21
19----------------------------------------------------------------------------- 22-----------------------------------------------------------------------------
20-- Program constants 23-- Program constants
@@ -98,8 +101,8 @@ end
98-- send message or throw an exception 101-- send message or throw an exception
99function metat.__index:send(mailt) 102function metat.__index:send(mailt)
100 self:mail(mailt.from) 103 self:mail(mailt.from)
101 if type(mailt.rcpt) == "table" then 104 if base.type(mailt.rcpt) == "table" then
102 for i,v in ipairs(mailt.rcpt) do 105 for i,v in base.ipairs(mailt.rcpt) do
103 self:rcpt(v) 106 self:rcpt(v)
104 end 107 end
105 else 108 else
@@ -110,7 +113,7 @@ end
110 113
111function open(server, port) 114function open(server, port)
112 local tp = socket.try(tp.connect(server or SERVER, port or PORT, TIMEOUT)) 115 local tp = socket.try(tp.connect(server or SERVER, port or PORT, TIMEOUT))
113 local s = setmetatable({tp = tp}, metat) 116 local s = base.setmetatable({tp = tp}, metat)
114 -- make sure tp is closed if we get an exception 117 -- make sure tp is closed if we get an exception
115 s.try = socket.newtry(function() 118 s.try = socket.newtry(function()
116 if s.tp:command("QUIT") then s.tp:check("2..") end 119 if s.tp:command("QUIT") then s.tp:check("2..") end
@@ -145,7 +148,7 @@ local function send_multipart(mesgt)
145 coroutine.yield("\r\n") 148 coroutine.yield("\r\n")
146 end 149 end
147 -- send each part separated by a boundary 150 -- send each part separated by a boundary
148 for i, m in ipairs(mesgt.body) do 151 for i, m in base.ipairs(mesgt.body) do
149 coroutine.yield("\r\n--" .. bd .. "\r\n") 152 coroutine.yield("\r\n--" .. bd .. "\r\n")
150 send_message(m) 153 send_message(m)
151 end 154 end
@@ -191,7 +194,7 @@ end
191-- yield the headers one by one 194-- yield the headers one by one
192local function send_headers(mesgt) 195local function send_headers(mesgt)
193 if mesgt.headers then 196 if mesgt.headers then
194 for i,v in pairs(mesgt.headers) do 197 for i,v in base.pairs(mesgt.headers) do
195 coroutine.yield(i .. ':' .. v .. "\r\n") 198 coroutine.yield(i .. ':' .. v .. "\r\n")
196 end 199 end
197 end 200 end
@@ -200,8 +203,8 @@ end
200-- message source 203-- message source
201function send_message(mesgt) 204function send_message(mesgt)
202 send_headers(mesgt) 205 send_headers(mesgt)
203 if type(mesgt.body) == "table" then send_multipart(mesgt) 206 if base.type(mesgt.body) == "table" then send_multipart(mesgt)
204 elseif type(mesgt.body) == "function" then send_source(mesgt) 207 elseif base.type(mesgt.body) == "function" then send_source(mesgt)
205 else send_string(mesgt) end 208 else send_string(mesgt) end
206end 209end
207 210
@@ -241,3 +244,5 @@ send = socket.protect(function(mailt)
241 s:quit() 244 s:quit()
242 return s:close() 245 return s:close()
243end) 246end)
247
248base.setmetatable(smtp, nil)
diff --git a/src/tcp.c b/src/tcp.c
index 746c4b6..618f4ce 100644
--- a/src/tcp.c
+++ b/src/tcp.c
@@ -233,7 +233,8 @@ static int meth_close(lua_State *L)
233{ 233{
234 p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); 234 p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1);
235 sock_destroy(&tcp->sock); 235 sock_destroy(&tcp->sock);
236 return 0; 236 lua_pushnumber(L, 1);
237 return 1;
237} 238}
238 239
239/*-------------------------------------------------------------------------*\ 240/*-------------------------------------------------------------------------*\
diff --git a/src/tp.lua b/src/tp.lua
index ada00d2..0a671fb 100644
--- a/src/tp.lua
+++ b/src/tp.lua
@@ -8,10 +8,12 @@
8----------------------------------------------------------------------------- 8-----------------------------------------------------------------------------
9-- Declare module and import dependencies 9-- Declare module and import dependencies
10----------------------------------------------------------------------------- 10-----------------------------------------------------------------------------
11local base = require("base")
12local string = require("string")
11local socket = require("socket") 13local socket = require("socket")
12local ltn12 = require("ltn12") 14local ltn12 = require("ltn12")
13 15
14module("socket.tp") 16local tp = module("socket.tp")
15 17
16----------------------------------------------------------------------------- 18-----------------------------------------------------------------------------
17-- Program constants 19-- Program constants
@@ -47,22 +49,27 @@ local metat = { __index = {} }
47function metat.__index:check(ok) 49function metat.__index:check(ok)
48 local code, reply = get_reply(self.c) 50 local code, reply = get_reply(self.c)
49 if not code then return nil, reply end 51 if not code then return nil, reply end
50 if type(ok) ~= "function" then 52 if base.type(ok) ~= "function" then
51 if type(ok) == "table" then 53 if base.type(ok) == "table" then
52 for i, v in ipairs(ok) do 54 for i, v in base.ipairs(ok) do
53 if string.find(code, v) then return tonumber(code), reply end 55 if string.find(code, v) then
56 return base.tonumber(code), reply
57 end
54 end 58 end
55 return nil, reply 59 return nil, reply
56 else 60 else
57 if string.find(code, ok) then return tonumber(code), reply 61 if string.find(code, ok) then return base.tonumber(code), reply
58 else return nil, reply end 62 else return nil, reply end
59 end 63 end
60 else return ok(tonumber(code), reply) end 64 else return ok(base.tonumber(code), reply) end
61end 65end
62 66
63function metat.__index:command(cmd, arg) 67function metat.__index:command(cmd, arg)
64 if arg then return self.c:send(cmd .. " " .. arg.. "\r\n") 68 if arg then
65 else return self.c:send(cmd .. "\r\n") end 69 return self.c:send(cmd .. " " .. arg.. "\r\n")
70 else
71 return self.c:send(cmd .. "\r\n")
72 end
66end 73end
67 74
68function metat.__index:sink(snk, pat) 75function metat.__index:sink(snk, pat)
@@ -111,5 +118,7 @@ function connect(host, port, timeout)
111 c:close() 118 c:close()
112 return nil, e 119 return nil, e
113 end 120 end
114 return setmetatable({c = c}, metat) 121 return base.setmetatable({c = c}, metat)
115end 122end
123
124base.setmetatable(tp, nil)
diff --git a/src/udp.c b/src/udp.c
index 97a6169..7a60080 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -288,7 +288,8 @@ static int meth_setpeername(lua_State *L) {
288static int meth_close(lua_State *L) { 288static int meth_close(lua_State *L) {
289 p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); 289 p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1);
290 sock_destroy(&udp->sock); 290 sock_destroy(&udp->sock);
291 return 0; 291 lua_pushnumber(L, 1);
292 return 1;
292} 293}
293 294
294/*-------------------------------------------------------------------------*\ 295/*-------------------------------------------------------------------------*\
diff --git a/src/url.lua b/src/url.lua
index efe7254..08081f0 100644
--- a/src/url.lua
+++ b/src/url.lua
@@ -8,7 +8,10 @@
8----------------------------------------------------------------------------- 8-----------------------------------------------------------------------------
9-- Declare module 9-- Declare module
10----------------------------------------------------------------------------- 10-----------------------------------------------------------------------------
11module("socket.url") 11local string = require("string")
12local base = require("base")
13local table = require("table")
14local url = module("socket.url")
12 15
13----------------------------------------------------------------------------- 16-----------------------------------------------------------------------------
14-- Encodes a string into its escaped hexadecimal representation 17-- Encodes a string into its escaped hexadecimal representation
@@ -18,7 +21,7 @@ module("socket.url")
18-- escaped representation of string binary 21-- escaped representation of string binary
19----------------------------------------------------------------------------- 22-----------------------------------------------------------------------------
20function escape(s) 23function escape(s)
21 return string.gsub(s, "(.)", function(c) 24 return string.gsub(s, "([^A-Za-z0-9_])", function(c)
22 return string.format("%%%02x", string.byte(c)) 25 return string.format("%%%02x", string.byte(c))
23 end) 26 end)
24end 27end
@@ -33,7 +36,7 @@ end
33----------------------------------------------------------------------------- 36-----------------------------------------------------------------------------
34local function make_set(t) 37local function make_set(t)
35 local s = {} 38 local s = {}
36 for i = 1, table.getn(t) do 39 for i,v in base.ipairs(t) do
37 s[t[i]] = 1 40 s[t[i]] = 1
38 end 41 end
39 return s 42 return s
@@ -62,7 +65,7 @@ end
62----------------------------------------------------------------------------- 65-----------------------------------------------------------------------------
63function unescape(s) 66function unescape(s)
64 return string.gsub(s, "%%(%x%x)", function(hex) 67 return string.gsub(s, "%%(%x%x)", function(hex)
65 return string.char(tonumber(hex, 16)) 68 return string.char(base.tonumber(hex, 16))
66 end) 69 end)
67end 70end
68 71
@@ -191,7 +194,7 @@ end
191-- corresponding absolute url 194-- corresponding absolute url
192----------------------------------------------------------------------------- 195-----------------------------------------------------------------------------
193function absolute(base_url, relative_url) 196function absolute(base_url, relative_url)
194 local base = type(base_url) == "table" and base_url or parse(base_url) 197 local base = base.type(base_url) == "table" and base_url or parse(base_url)
195 local relative = parse(relative_url) 198 local relative = parse(relative_url)
196 if not base then return relative_url 199 if not base then return relative_url
197 elseif not relative then return base_url 200 elseif not relative then return base_url
@@ -269,3 +272,5 @@ function build_path(parsed, unsafe)
269 if parsed.is_absolute then path = "/" .. path end 272 if parsed.is_absolute then path = "/" .. path end
270 return path 273 return path
271end 274end
275
276base.setmetatable(url, nil)
diff --git a/src/wsocket.c b/src/wsocket.c
index 1b169ed..0294dce 100644
--- a/src/wsocket.c
+++ b/src/wsocket.c
@@ -180,9 +180,10 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *len, p_tm tm) {
180 180
181/*-------------------------------------------------------------------------*\ 181/*-------------------------------------------------------------------------*\
182* Send with timeout 182* Send with timeout
183* On windows, if you try to send 10MB, the OS will buffer EVERYTHING
184* this can take an awful lot of time and we will end up blocked.
185* Therefore, whoever calls this function should not pass a huge buffer.
183\*-------------------------------------------------------------------------*/ 186\*-------------------------------------------------------------------------*/
184/* has to be larger than UDP_DATAGRAMSIZE !!!*/
185#define MAXCHUNK (64*1024)
186int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm) 187int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm)
187{ 188{
188 int err; 189 int err;
@@ -192,9 +193,7 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm)
192 *sent = 0; 193 *sent = 0;
193 for ( ;; ) { 194 for ( ;; ) {
194 /* try to send something */ 195 /* try to send something */
195 /* on windows, if you try to send 10MB, the OS will buffer EVERYTHING 196 int put = send(*ps, data, count, 0);
196 * this can take an awful lot of time and we will end up blocked. */
197 int put = send(*ps, data, (count < MAXCHUNK)? (int)count: MAXCHUNK, 0);
198 /* if we sent something, we are done */ 197 /* if we sent something, we are done */
199 if (put > 0) { 198 if (put > 0) {
200 *sent = put; 199 *sent = put;
@@ -221,7 +220,7 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent,
221 if (*ps == SOCK_INVALID) return IO_CLOSED; 220 if (*ps == SOCK_INVALID) return IO_CLOSED;
222 *sent = 0; 221 *sent = 0;
223 for ( ;; ) { 222 for ( ;; ) {
224 int put = send(*ps, data, (int) count, 0); 223 int put = sendto(*ps, data, (int) count, 0, addr, len);
225 if (put > 0) { 224 if (put > 0) {
226 *sent = put; 225 *sent = put;
227 return IO_DONE; 226 return IO_DONE;
@@ -298,13 +297,13 @@ void sock_setnonblocking(p_sock ps) {
298int sock_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { 297int sock_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) {
299 *hp = gethostbyaddr(addr, len, AF_INET); 298 *hp = gethostbyaddr(addr, len, AF_INET);
300 if (*hp) return IO_DONE; 299 if (*hp) return IO_DONE;
301 else return h_errno; 300 else return WSAGetLastError();
302} 301}
303 302
304int sock_gethostbyname(const char *addr, struct hostent **hp) { 303int sock_gethostbyname(const char *addr, struct hostent **hp) {
305 *hp = gethostbyname(addr); 304 *hp = gethostbyname(addr);
306 if (*hp) return IO_DONE; 305 if (*hp) return IO_DONE;
307 else return h_errno; 306 else return WSAGetLastError();
308} 307}
309 308
310/*-------------------------------------------------------------------------*\ 309/*-------------------------------------------------------------------------*\