diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buffer.c | 4 | ||||
-rw-r--r-- | src/except.c | 26 | ||||
-rw-r--r-- | src/ftp.lua | 53 | ||||
-rw-r--r-- | src/http.lua | 23 | ||||
-rw-r--r-- | src/ltn12.lua | 22 | ||||
-rw-r--r-- | src/mime.lua | 11 | ||||
-rw-r--r-- | src/smtp.lua | 25 | ||||
-rw-r--r-- | src/tcp.c | 3 | ||||
-rw-r--r-- | src/tp.lua | 29 | ||||
-rw-r--r-- | src/udp.c | 3 | ||||
-rw-r--r-- | src/url.lua | 15 | ||||
-rw-r--r-- | src/wsocket.c | 15 |
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 | ||
161 | static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent) { | 162 | static 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 | \*-------------------------------------------------------------------------*/ |
32 | static 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 | |||
32 | static int finalize(lua_State *L) { | 41 | static 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 | \*-------------------------------------------------------------------------*/ |
67 | static 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 | |||
57 | static int protected_(lua_State *L) { | 77 | static 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 | ----------------------------------------------------------------------------- |
11 | local base = require("base") | ||
12 | local table = require("table") | ||
13 | local string = require("string") | ||
14 | local math = require("math") | ||
11 | local socket = require("socket") | 15 | local socket = require("socket") |
12 | local url = require("socket.url") | 16 | local url = require("socket.url") |
13 | local tp = require("socket.tp") | 17 | local tp = require("socket.tp") |
14 | |||
15 | local ltn12 = require("ltn12") | 18 | local ltn12 = require("ltn12") |
16 | 19 | local ftp = module("socket.ftp") | |
17 | module("socket.ftp") | ||
18 | 20 | ||
19 | ----------------------------------------------------------------------------- | 21 | ----------------------------------------------------------------------------- |
20 | -- Program constants | 22 | -- Program constants |
@@ -35,7 +37,7 @@ local metat = { __index = {} } | |||
35 | 37 | ||
36 | function open(server, port) | 38 | function 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 | |||
134 | function metat.__index:receive(recvt) | 137 | function 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 | ----------------------------------------------------------------------------- |
189 | function 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 | ||
197 | end | ||
198 | |||
185 | local function tput(putt) | 199 | local 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 | ||
202 | local function parse(u) | 218 | local 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) | |||
219 | end | 235 | end |
220 | 236 | ||
221 | put = socket.protect(function(putt, body) | 237 | put = 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 |
224 | end) | 240 | end) |
225 | 241 | ||
226 | local function tget(gett) | 242 | local 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) |
243 | end | 261 | end |
244 | 262 | ||
263 | command = 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() | ||
274 | end) | ||
275 | |||
245 | get = socket.protect(function(gett) | 276 | get = 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 |
248 | end) | 279 | end) |
280 | |||
281 | base.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") | |||
12 | local url = require("socket.url") | 12 | local url = require("socket.url") |
13 | local ltn12 = require("ltn12") | 13 | local ltn12 = require("ltn12") |
14 | local mime = require("mime") | 14 | local mime = require("mime") |
15 | 15 | local string = require("string") | |
16 | module("socket.http") | 16 | local base = require("base") |
17 | local table = require("table") | ||
18 | local http = module("socket.http") | ||
17 | 19 | ||
18 | ----------------------------------------------------------------------------- | 20 | ----------------------------------------------------------------------------- |
19 | -- Program constants | 21 | -- Program constants |
@@ -32,7 +34,7 @@ local metat = { __index = {} } | |||
32 | 34 | ||
33 | function open(host, port) | 35 | function 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) | |||
46 | end | 48 | end |
47 | 49 | ||
48 | function metat.__index:sendheaders(headers) | 50 | function 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 | |||
66 | function metat.__index:receivestatusline() | 68 | function 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) |
70 | end | 72 | end |
71 | 73 | ||
72 | function metat.__index:receiveheaders() | 74 | function metat.__index:receiveheaders() |
@@ -97,11 +99,11 @@ end | |||
97 | function metat.__index:receivebody(headers, sink, step) | 99 | function 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)) |
107 | end | 109 | end |
@@ -159,9 +161,10 @@ local default = { | |||
159 | local function adjustrequest(reqt) | 161 | local 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) | |||
253 | end | 256 | end |
254 | 257 | ||
255 | request = socket.protect(function(reqt, body) | 258 | request = 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 |
258 | end) | 261 | end) |
262 | |||
263 | base.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 | ----------------------------------------------------------------------------- |
11 | module("ltn12") | 11 | local string = require("string") |
12 | local table = require("table") | ||
13 | local base = require("base") | ||
14 | local coroutine = require("coroutine") | ||
15 | local ltn12 = module("ltn12") | ||
12 | 16 | ||
13 | filter = {} | 17 | filter = {} |
14 | source = {} | 18 | source = {} |
@@ -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 |
25 | function filter.cycle(low, ctx, extra) | 29 | function 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 |
123 | function source.simplify(src) | 127 | function 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 |
147 | function source.rewind(src) | 151 | function 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 |
162 | function source.chain(src, f) | 166 | function 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 |
217 | function sink.simplify(snk) | 221 | function 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 |
256 | function sink.chain(f, snk) | 260 | function 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 |
281 | function pump.all(src, snk, step) | 285 | function 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 |
288 | end | 292 | end |
293 | |||
294 | base.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 | ----------------------------------------------------------------------------- |
11 | module("mime") | 11 | local base = require("base") |
12 | local mime = require("lmime") | ||
13 | local ltn12 = require("ltn12") | 12 | local ltn12 = require("ltn12") |
13 | local mime = require("lmime") | ||
14 | module("mime") | ||
14 | 15 | ||
15 | -- encode, decode and wrap algorithm tables | 16 | -- encode, decode and wrap algorithm tables |
16 | mime.encodet = {} | 17 | mime.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 |
21 | local function choose(table) | 22 | local 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 |
30 | end | 31 | end |
@@ -74,3 +75,5 @@ end | |||
74 | function mime.stuff() | 75 | function mime.stuff() |
75 | return ltn12.filter.cycle(dot, 2) | 76 | return ltn12.filter.cycle(dot, 2) |
76 | end | 77 | end |
78 | |||
79 | base.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 | ----------------------------------------------------------------------------- |
11 | local base = require("base") | ||
12 | local coroutine = require("coroutine") | ||
13 | local string = require("string") | ||
14 | local math = require("math") | ||
15 | local os = require("os") | ||
11 | local socket = require("socket") | 16 | local socket = require("socket") |
12 | local tp = require("socket.tp") | 17 | local tp = require("socket.tp") |
13 | |||
14 | local ltn12 = require("ltn12") | 18 | local ltn12 = require("ltn12") |
15 | local mime = require("mime") | 19 | local mime = require("mime") |
16 | 20 | local smtp = module("socket.smtp") | |
17 | module("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 |
99 | function metat.__index:send(mailt) | 102 | function 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 | ||
111 | function open(server, port) | 114 | function 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 |
192 | local function send_headers(mesgt) | 195 | local 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 |
201 | function send_message(mesgt) | 204 | function 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 |
206 | end | 209 | end |
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() |
243 | end) | 246 | end) |
247 | |||
248 | base.setmetatable(smtp, nil) | ||
@@ -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 | /*-------------------------------------------------------------------------*\ |
@@ -8,10 +8,12 @@ | |||
8 | ----------------------------------------------------------------------------- | 8 | ----------------------------------------------------------------------------- |
9 | -- Declare module and import dependencies | 9 | -- Declare module and import dependencies |
10 | ----------------------------------------------------------------------------- | 10 | ----------------------------------------------------------------------------- |
11 | local base = require("base") | ||
12 | local string = require("string") | ||
11 | local socket = require("socket") | 13 | local socket = require("socket") |
12 | local ltn12 = require("ltn12") | 14 | local ltn12 = require("ltn12") |
13 | 15 | ||
14 | module("socket.tp") | 16 | local tp = module("socket.tp") |
15 | 17 | ||
16 | ----------------------------------------------------------------------------- | 18 | ----------------------------------------------------------------------------- |
17 | -- Program constants | 19 | -- Program constants |
@@ -47,22 +49,27 @@ local metat = { __index = {} } | |||
47 | function metat.__index:check(ok) | 49 | function 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 |
61 | end | 65 | end |
62 | 66 | ||
63 | function metat.__index:command(cmd, arg) | 67 | function 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 | ||
66 | end | 73 | end |
67 | 74 | ||
68 | function metat.__index:sink(snk, pat) | 75 | function 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) |
115 | end | 122 | end |
123 | |||
124 | base.setmetatable(tp, nil) | ||
@@ -288,7 +288,8 @@ static int meth_setpeername(lua_State *L) { | |||
288 | static int meth_close(lua_State *L) { | 288 | static 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 | ----------------------------------------------------------------------------- |
11 | module("socket.url") | 11 | local string = require("string") |
12 | local base = require("base") | ||
13 | local table = require("table") | ||
14 | local 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 | ----------------------------------------------------------------------------- |
20 | function escape(s) | 23 | function 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) |
24 | end | 27 | end |
@@ -33,7 +36,7 @@ end | |||
33 | ----------------------------------------------------------------------------- | 36 | ----------------------------------------------------------------------------- |
34 | local function make_set(t) | 37 | local 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 | ----------------------------------------------------------------------------- |
63 | function unescape(s) | 66 | function 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) |
67 | end | 70 | end |
68 | 71 | ||
@@ -191,7 +194,7 @@ end | |||
191 | -- corresponding absolute url | 194 | -- corresponding absolute url |
192 | ----------------------------------------------------------------------------- | 195 | ----------------------------------------------------------------------------- |
193 | function absolute(base_url, relative_url) | 196 | function 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 |
271 | end | 274 | end |
275 | |||
276 | base.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) | ||
186 | int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm) | 187 | int 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) { | |||
298 | int sock_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { | 297 | int 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 | ||
304 | int sock_gethostbyname(const char *addr, struct hostent **hp) { | 303 | int 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 | /*-------------------------------------------------------------------------*\ |