Skip to content

Commit 71c0deb

Browse files
committed
Add. cURL.safe module.
1 parent e0dfc3a commit 71c0deb

4 files changed

Lines changed: 339 additions & 310 deletions

File tree

rockspecs/lua-curl-scm-0.rockspec

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ build = {
5757
},
5858

5959
modules = {
60-
cURL = "src/lua/cURL.lua",
60+
["cURL" ] = "src/lua/cURL.lua",
61+
["cURL.safe" ] = "src/lua/cURL/safe.lua",
62+
["cURL.impl.cURL" ] = "src/lua/cURL/impl/cURL.lua",
63+
6164
lcurl = {
6265
sources = {
6366
"src/l52util.c", "src/lceasy.c", "src/lcerror.c",
@@ -68,4 +71,6 @@ build = {
6871
libdirs = { "$(CURL_LIBDIR)" }
6972
},
7073
}
71-
}
74+
}
75+
76+

src/lua/cURL.lua

Lines changed: 2 additions & 308 deletions
Original file line numberDiff line numberDiff line change
@@ -1,310 +1,4 @@
1-
--
2-
-- Author: Alexey Melnichuk <mimir@newmail.ru>
3-
--
4-
-- Copyright (C) 2014 Alexey Melnichuk <mimir@newmail.ru>
5-
--
6-
-- Licensed according to the included 'LICENSE' document
7-
--
8-
-- This file is part of lua-lcurl library.
9-
--
10-
11-
--
12-
-- Implementation of Lua-cURL http://msva.github.io/lua-curl
13-
--
14-
151
local curl = require "lcurl"
2+
local impl = require "cURL.impl.cURL"
163

17-
local function wrap_function(k)
18-
return function(self, ...)
19-
local ok, err = self._handle[k](self._handle, ...)
20-
if ok == self._handle then return self end
21-
return ok, err
22-
end
23-
end
24-
25-
local function wrap_setopt_flags(k, flags)
26-
k = "setopt_" .. k
27-
return function(self, v)
28-
v = assert(flags[v], "Unsupported value " .. tostring(v))
29-
local ok, err = self._handle[k](self._handle, v)
30-
if ok == self._handle then return self end
31-
return ok, err
32-
end
33-
end
34-
35-
local function class(ctor)
36-
local C = {}
37-
C.__index = function(self, k)
38-
local fn = C[k]
39-
40-
if not fn and self._handle[k] then
41-
fn = wrap_function(k)
42-
self[k] = fn
43-
end
44-
return fn
45-
end
46-
47-
function C:new()
48-
local h, err = ctor()
49-
if not h then return nil, err end
50-
51-
local o = setmetatable({
52-
_handle = h
53-
}, self)
54-
55-
return o
56-
end
57-
58-
function C:handle()
59-
return self._handle
60-
end
61-
62-
return C
63-
end
64-
65-
-------------------------------------------
66-
local Easy = class(curl.easy) do
67-
68-
local perform = wrap_function("perform")
69-
local setopt_share = wrap_function("setopt_share")
70-
local setopt_readfunction = wrap_function("setopt_readfunction")
71-
72-
local NONE = {}
73-
74-
function Easy:_call_readfunction(...)
75-
if self._rd_ud == NONE then
76-
return self._rd_fn(...)
77-
end
78-
return self._rd_fn(self._rd_ud, ...)
79-
end
80-
81-
function Easy:setopt_readfunction(fn, ...)
82-
assert(fn)
83-
84-
if select('#', ...) == 0 then
85-
if type(fn) == "function" then
86-
self._rd_fn = fn
87-
self._rd_ud = NONE
88-
else
89-
self._rd_fn = assert(fn.read)
90-
self._rd_ud = fn
91-
end
92-
else
93-
self._rd_fn = fn
94-
self._ud_fn = ...
95-
end
96-
97-
return setopt_readfunction(self, fn, ...)
98-
end
99-
100-
function Easy:perform(opt)
101-
opt = opt or {}
102-
103-
local oerror = opt.errorfunction or function(err) return nil, err end
104-
105-
if opt.readfunction then
106-
local ok, err = self:setopt_readfunction(opt.readfunction)
107-
if not ok then return oerror(err) end
108-
end
109-
110-
if opt.writefunction then
111-
local ok, err = self:setopt_writefunction(opt.writefunction)
112-
if not ok then return oerror(err) end
113-
end
114-
115-
if opt.headerfunction then
116-
local ok, err = self:setopt_headerfunction(opt.headerfunction)
117-
if not ok then return oerror(err) end
118-
end
119-
120-
local ok, err = perform(self)
121-
if not ok then return oerror(err) end
122-
123-
return self
124-
end
125-
126-
function Easy:post(data)
127-
local form = curl.form()
128-
local ok, err = true
129-
130-
for k, v in pairs(data) do
131-
if type(v) == "string" then
132-
ok, err = form:add_content(k, v)
133-
else
134-
assert(type(v) == "table")
135-
if v.stream_length then
136-
local len = assert(tonumber(v.stream_length))
137-
assert(v.file)
138-
if v.stream then
139-
ok, err = form:add_stream(k, v.file, v.type, v.headers, len, v.stream)
140-
else
141-
ok, err = form:add_stream(k, v.file, v.type, v.headers, len, self._call_readfunction, self)
142-
end
143-
elseif v.data then
144-
ok, err = form:add_buffer(k, v.file, v.data, v.type, v.headers)
145-
else
146-
ok, err = form:add_file(k, v.file, v.type, v.filename, v.headers)
147-
end
148-
end
149-
if not ok then break end
150-
end
151-
152-
if not ok then
153-
form:free()
154-
return nil, err
155-
end
156-
157-
ok, err = self:setopt_httppost(form)
158-
if not ok then
159-
form:free()
160-
return nil, err
161-
end
162-
163-
return self
164-
end
165-
166-
function Easy:setopt_share(s)
167-
return setopt_share(self, s:handle())
168-
end
169-
170-
Easy.setopt_proxytype = wrap_setopt_flags("proxytype", {
171-
["HTTP" ] = curl.PROXY_HTTP;
172-
["HTTP_1_0" ] = curl.PROXY_HTTP_1_0;
173-
["SOCKS4" ] = curl.PROXY_SOCKS4;
174-
["SOCKS5" ] = curl.PROXY_SOCKS5;
175-
["SOCKS4A" ] = curl.PROXY_SOCKS4A;
176-
["SOCKS5_HOSTNAME" ] = curl.PROXY_SOCKS5_HOSTNAME;
177-
})
178-
179-
Easy.setopt_httpauth = wrap_setopt_flags("httpauth", {
180-
["NONE" ] = curl.AUTH_NONE;
181-
["BASIC" ] = curl.AUTH_BASIC;
182-
["DIGEST" ] = curl.AUTH_DIGEST;
183-
["GSSNEGOTIATE" ] = curl.AUTH_GSSNEGOTIATE;
184-
["NTLM" ] = curl.AUTH_NTLM;
185-
["DIGEST_IE" ] = curl.AUTH_DIGEST_IE;
186-
["NTLM_WB" ] = curl.AUTH_NTLM_WB;
187-
["ONLY" ] = curl.AUTH_ONLY;
188-
["ANY" ] = curl.AUTH_ANY;
189-
["ANYSAFE" ] = curl.AUTH_ANYSAFE;
190-
["SSH_ANY" ] = curl.SSH_AUTH_ANY;
191-
["SSH_NONE" ] = curl.SSH_AUTH_NONE;
192-
["SSH_PUBLICKEY" ] = curl.SSH_AUTH_PUBLICKEY;
193-
["SSH_PASSWORD" ] = curl.SSH_AUTH_PASSWORD;
194-
["SSH_HOST" ] = curl.SSH_AUTH_HOST;
195-
["SSH_KEYBOARD" ] = curl.SSH_AUTH_KEYBOARD;
196-
["SSH_AGENT" ] = curl.SSH_AUTH_AGENT;
197-
["SSH_DEFAULT" ] = curl.SSH_AUTH_DEFAULT;
198-
})
199-
200-
end
201-
-------------------------------------------
202-
203-
-------------------------------------------
204-
local Multi = class(curl.multi) do
205-
206-
local perform = wrap_function("perform")
207-
local add_handle = wrap_function("add_handle")
208-
local remove_handle = wrap_function("remove_handle")
209-
210-
local function make_iterator(self)
211-
local curl = require "lcurl.safe"
212-
213-
local buffers = {resp = {}, _ = {}} do
214-
215-
function buffers:append(e, ...)
216-
local resp = assert(e:getinfo_response_code())
217-
if not self._[e] then self._[e] = {} end
218-
219-
local b = self._[e]
220-
221-
if self.resp[e] ~= resp then
222-
b[#b + 1] = {"response", resp}
223-
self.resp[e] = resp
224-
end
225-
226-
b[#b + 1] = {...}
227-
end
228-
229-
function buffers:next()
230-
for e, t in pairs(self._) do
231-
local m = table.remove(t, 1)
232-
if m then return e, m end
233-
end
234-
end
235-
236-
end
237-
238-
local remain = #self._easy
239-
for _, e in ipairs(self._easy) do
240-
e:setopt_writefunction (function(str) buffers:append(e, "data", str) end)
241-
e:setopt_headerfunction(function(str) buffers:append(e, "header", str) end)
242-
end
243-
244-
assert(perform(self))
245-
246-
return function()
247-
while true do
248-
local e, t = buffers:next()
249-
if t then return t[2], t[1], e end
250-
if remain == 0 then break end
251-
252-
self:wait()
253-
254-
local n, err = assert(perform(self))
255-
256-
if n <= remain then
257-
while true do
258-
local e, ok, err = assert(self:info_read())
259-
if e == 0 then break end
260-
for _, a in ipairs(self._easy) do
261-
if e == a:handle() then e = a break end
262-
end
263-
if ok then buffers:append(e, "done", ok)
264-
else buffers:append(e, "error", err) end
265-
end
266-
remain = n
267-
end
268-
269-
end
270-
end
271-
end
272-
273-
function Multi:perform()
274-
return make_iterator(self)
275-
end
276-
277-
function Multi:add_handle(e)
278-
self._easy[#self._easy + 1] = e
279-
return add_handle(self, e:handle())
280-
end
281-
282-
function Multi:remove_handle(e)
283-
self._easy[#self._easy + 1] = e
284-
return remove_handle(self, e:handle())
285-
end
286-
287-
end
288-
-------------------------------------------
289-
290-
-------------------------------------------
291-
local Share = class(curl.share) do
292-
293-
Share.setopt_share = wrap_setopt_flags("share", {
294-
[ "COOKIE" ] = curl.LOCK_DATA_COOKIE;
295-
[ "DNS" ] = curl.LOCK_DATA_DNS;
296-
[ "SSL_SESSION" ] = curl.LOCK_DATA_SSL_SESSION;
297-
})
298-
299-
end
300-
-------------------------------------------
301-
302-
local cURL = setmetatable({}, {__index = curl})
303-
304-
function cURL.easy_init() return Easy:new() end
305-
306-
function cURL.multi_init() return Multi:new() end
307-
308-
function cURL.share_init() return Share:new() end
309-
310-
return cURL
4+
return impl(curl)

0 commit comments

Comments
 (0)