Skip to content

Commit cc5c224

Browse files
committed
Merge pull request #26 from moteus/master
Add. Form class to Lua-cURLv3 interface.
2 parents 5737bb7 + f7926e5 commit cc5c224

File tree

3 files changed

+212
-1
lines changed

3 files changed

+212
-1
lines changed

examples/cURLv3/post_form.lua

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
local cURL = require "cURL"
2+
3+
-- Stream class
4+
local Stream = {} do
5+
Stream.__index = Stream
6+
7+
function Stream:new(ch, length)
8+
local o = setmetatable({}, self)
9+
o._len = length
10+
o._ch = ch
11+
o._pos = 0
12+
o._step = 7
13+
return o
14+
end
15+
16+
function Stream:length()
17+
return self._len
18+
end
19+
20+
function Stream:read()
21+
local n = self._len - self._pos
22+
if n <= 0 then return '' end -- eof
23+
if n > self._step then n = self._step end
24+
self._pos = self._pos + n
25+
return self._ch:rep(n)
26+
end
27+
28+
end
29+
30+
-- returns size and reader
31+
local function make_stream(ch, n, m)
32+
local size = n * m
33+
local i = -1
34+
return size, function()
35+
i = i + 1
36+
if i < m then
37+
return (tostring(ch)):rep(n - 2) .. '\r\n'
38+
end
39+
return nil
40+
end
41+
end
42+
43+
local length, stream = make_stream("a", 10, 4)
44+
45+
c = cURL.easy{
46+
url = "http://posttestserver.com/post.php",
47+
-- url = "http://httpbin.org/post",
48+
post = true,
49+
httppost = cURL.form{
50+
51+
-- file form filesystem
52+
name01 = {
53+
file = "post_form.lua",
54+
type = "text/plain",
55+
name = "post.lua",
56+
},
57+
58+
-- file form string
59+
name02 = {
60+
data = "<html><bold>bold</bold></html>",
61+
name = "dummy.html",
62+
type = "text/html",
63+
},
64+
65+
-- file form stream object
66+
name03 = {
67+
stream = Stream:new('8', 25),
68+
name = "stream1.txt",
69+
type = "text/plain",
70+
headers = {
71+
"X-Test-Char : 8",
72+
"X-Test-length : 25",
73+
}
74+
},
75+
76+
-- file form stream function
77+
name04 = {
78+
stream = stream,
79+
length = length,
80+
name = "stream2.txt",
81+
type = "text/plain",
82+
},
83+
84+
},
85+
}
86+
87+
c:perform()

src/lua/cURL/impl/cURL.lua

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
-- Implementation of Lua-cURL http://msva.github.io/lua-curl
1313
--
1414

15+
local function clone(t, o)
16+
o = o or {}
17+
for k,v in pairs(t) do o[k]=v end
18+
return o
19+
end
20+
1521
local function wrap_function(k)
1622
return function(self, ...)
1723
local ok, err = self._handle[k](self._handle, ...)
@@ -94,6 +100,80 @@ local function make_iterator(self, perform)
94100
end
95101
end
96102

103+
104+
-- name = <string>/<stream>/<file>/<buffer>
105+
--
106+
-- <stream> = {
107+
-- stream = function/object
108+
-- length = ?number
109+
-- name = ?string
110+
-- type = ?string
111+
-- headers = ?table
112+
-- }
113+
--
114+
-- <file> = {
115+
-- file = string
116+
-- type = ?string
117+
-- name = ?string
118+
-- headers = ?table
119+
-- }
120+
--
121+
-- <buffer> = {
122+
-- data = string
123+
-- name = string
124+
-- type = ?string
125+
-- headers = ?table
126+
-- }
127+
--
128+
local function form_add_element(form, name, value)
129+
local vt = type(value)
130+
if vt == "string" then return form:add_content(name, value) end
131+
132+
assert(type(name) == "string")
133+
assert(vt == "table")
134+
assert((value.name == nil) or (type(value.name) == 'string'))
135+
assert((value.type == nil) or (type(value.type) == 'string'))
136+
assert((value.headrs == nil) or (type(value.type) == 'string'))
137+
138+
if value.stream then
139+
local vst = type(value.stream)
140+
141+
if vst == 'function' then
142+
assert(type(value.length) == 'number')
143+
local length = value.length
144+
return form:add_stream(name, value.name, value.type, value.headers, length, value.stream)
145+
end
146+
147+
if (vst == 'table') or (vst == 'userdata') then
148+
local length = value.length or assert(value.stream:length())
149+
assert(type(length) == 'number')
150+
return form:add_stream(name, value.name, value.type, value.headers, length, value.stream)
151+
end
152+
153+
error("Unsupported stream type: " .. vst)
154+
end
155+
156+
if value.file then
157+
assert(type(value.file) == 'string')
158+
return form:add_file(name, value.file, value.type, value.filename, value.headers)
159+
end
160+
161+
if value.data then
162+
assert(type(value.data) == 'string')
163+
assert(type(value.name) == 'string')
164+
return form:add_buffer(name, value.name, value.data, value.type, value.headers)
165+
end
166+
end
167+
168+
local function form_add(form, data)
169+
for k, v in pairs(data) do
170+
local ok, err = form_add_element(form, k, v)
171+
if not ok then return nil, err end
172+
end
173+
174+
return form
175+
end
176+
97177
local function class(ctor)
98178
local C = {}
99179
C.__index = function(self, k)
@@ -334,6 +414,21 @@ end
334414

335415
local function Load_cURLv3(cURL, curl)
336416

417+
-------------------------------------------
418+
local Form = class(curl.form) do
419+
420+
function Form:__init(opt)
421+
if opt then return self:add(opt) end
422+
return self
423+
end
424+
425+
function Form:add(data)
426+
return form_add(self, data)
427+
end
428+
429+
end
430+
-------------------------------------------
431+
337432
-------------------------------------------
338433
local Easy = class(curl.easy) do
339434

@@ -352,6 +447,33 @@ function Easy:perform(opt)
352447
return perform(self)
353448
end
354449

450+
local setopt_httppost = wrap_function("setopt_httppost")
451+
function Easy:setopt_httppost(form)
452+
return setopt_httppost(self, form:handle())
453+
end
454+
455+
local setopt = wrap_function("setopt")
456+
function Easy:setopt(k, v)
457+
if type(k) == 'table' then
458+
local t = k
459+
460+
local hpost = t.httppost or t[curl.OPT_HTTPPOST]
461+
if hpost and hpost._handle then
462+
t = clone(t)
463+
if t.httppost then t.httppost = hpost:handle() end
464+
if t[curl.OPT_HTTPPOST] then t[curl.OPT_HTTPPOST] = hpost:handle() end
465+
end
466+
467+
return setopt(self, t)
468+
end
469+
470+
if k == curl.OPT_HTTPPOST then
471+
return self:setopt_httppost(v)
472+
end
473+
474+
return setopt(self, k, v)
475+
end
476+
355477
end
356478
-------------------------------------------
357479

@@ -409,6 +531,8 @@ end
409531

410532
setmetatable(cURL, {__index = curl})
411533

534+
function cURL.form(...) return Form:new(...) end
535+
412536
function cURL.easy(...) return Easy:new(...) end
413537

414538
function cURL.multi(...) return Multi:new(...) end

src/lua/cURL/utils.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ local function find_ca_bundle(name)
3535
end
3636

3737
if env.SSL_CERT_DIR and path.isdir(env.SSL_CERT_DIR) then
38-
return false, env.SSL_CERT_DIR
38+
return nil, env.SSL_CERT_DIR
3939
end
4040

4141
if env.SSL_CERT_FILE and path.isfile(env.SSL_CERT_FILE) then

0 commit comments

Comments
 (0)