Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion doc/curl.ldoc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ do
--- Form description table.
--
-- @table FORM_DESCRIPTION
-- @tfield string|form_stream|form_file|form_buffer content_name
-- @tfield string|form_stream|form_file|form_buffer|form_content content_name
--
-- @usage
-- post_form = cURL.form{
Expand Down Expand Up @@ -58,6 +58,14 @@ do
-- type = "text/plain",
-- },
--
-- -- content form string
-- name05 = 'value05',
--
-- -- content form string
-- name06 = { 'value06', -- or content = 'value05'
-- type = "text/plain",
-- },
--
-- }

--- Table describe stream part in form.
Expand Down Expand Up @@ -89,6 +97,14 @@ do
-- @tfield[opt] table headers array of headers
--

--- Table describe content part in form.
--
-- @table form_content
-- @tfield string content value (or first field in table)
-- @tfield[opt] string type mime type (e.g. 'text/plain')
-- @tfield[opt] table headers array of headers
--

end

--- HTTP multipart/formdata object
Expand Down
26 changes: 22 additions & 4 deletions src/lua/cURL/impl/cURL.lua
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ local function make_iterator(self, perform)
end


-- name = <string>/<stream>/<file>/<buffer>
-- name = <string>/<stream>/<file>/<buffer>/<content>
--
-- <stream> = {
-- stream = function/object
Expand All @@ -139,15 +139,22 @@ end
-- headers = ?table
-- }
--
-- <content> = {
-- content = string -- or first key in table
-- type = ?string
-- headers = ?table
-- }
--

local function form_add_element(form, name, value)
local vt = type(value)
if vt == "string" then return form:add_content(name, value) end

assert(type(name) == "string")
assert(vt == "table")
assert((value.name == nil) or (type(value.name) == 'string'))
assert((value.type == nil) or (type(value.type) == 'string'))
assert((value.headrs == nil) or (type(value.type) == 'string'))
assert((value.name == nil) or (type(value.name ) == 'string'))
assert((value.type == nil) or (type(value.type ) == 'string'))
assert((value.headers == nil) or (type(value.headers) == 'table' ))

if value.stream then
local vst = type(value.stream)
Expand Down Expand Up @@ -177,6 +184,17 @@ local function form_add_element(form, name, value)
assert(type(value.name) == 'string')
return form:add_buffer(name, value.name, value.data, value.type, value.headers)
end

local content = value[1] or value.content
if content then
assert(type(content) == 'string')
if value.type then
return form:add_content(name, content, value.type, value.headers)
end
return form:add_content(name, content, value.headers)
end

return form
end

local function form_add(form, data)
Expand Down
195 changes: 195 additions & 0 deletions test/test_curl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,200 @@ end

end

local _ENV = TEST_CASE'form' if ENABLE then

local post

function teardown()
if post then post:free() end
post = nil
end

function test_content_01()
post = assert(scurl.form{name01 = 'value01'})
local data = assert_string(post:get())
assert_match("\r\n\r\nvalue01\r\n", data)
assert_match('name="name01"', data)
end

function test_content_02()
post = assert(scurl.form{name02 = {'value02', type = "text/plain"}})
local data = assert_string(post:get())
assert_match("\r\n\r\nvalue02\r\n", data)
assert_match('name="name02"', data)
assert_match('Content%-Type: text/plain\r\n', data)
end

function test_content_03()
post = assert(scurl.form{name03 = {content = 'value03', headers = {"Content-Encoding: gzip"}}})
local data = assert_string(post:get())
assert_match("\r\n\r\nvalue03\r\n", data)
assert_match('name="name03"', data)
assert_match('Content%-Encoding: gzip\r\n', data)
end

function test_content_04()
post = assert(scurl.form{name04 = {'value04', type = "text/plain", headers = {"Content-Encoding: gzip"}}})
local data = assert_string(post:get())
assert_match("\r\n\r\nvalue04\r\n", data)
assert_match('name="name04"', data)
assert_match('Content%-Encoding: gzip\r\n', data)
assert_match('Content%-Type: text/plain\r\n', data)
end

function test_buffer_01()
post = assert(scurl.form{name01 = {
name = 'file01',
data = 'value01',
}})

local data = assert_string(post:get())
assert_match("\r\n\r\nvalue01\r\n", data)
assert_match('name="name01"', data)
assert_match('filename="file01"', data)
assert_match('Content%-Type: application/octet%-stream\r\n', data)
end

function test_buffer_02()
post = assert(scurl.form{name02 = {
name = 'file02',
data = 'value02',
type = "text/plain",
}})

local data = assert_string(post:get())
assert_match("\r\n\r\nvalue02\r\n", data)
assert_match('name="name02"', data)
assert_match('filename="file02"', data)
assert_match('Content%-Type: text/plain\r\n', data)
assert_not_match('Content%-Type: application/octet%-stream\r\n', data)
end

function test_buffer_03()
post = assert(scurl.form{name03 = {
name = 'file03',
data = 'value03',
headers = {"Content-Encoding: gzip"},
}})
local data = assert_string(post:get())
assert_match("\r\n\r\nvalue03\r\n", data)
assert_match('name="name03"', data)
assert_match('filename="file03"', data)
assert_match('Content%-Type: application/octet%-stream\r\n', data)
assert_match('Content%-Encoding: gzip\r\n', data)
end

function test_buffer_04()
post = assert(scurl.form{name04 = {
name = 'file04',
data = 'value04',
type = "text/plain",
headers = {"Content-Encoding: gzip"},
}})

local data = assert_string(post:get())
assert_match("\r\n\r\nvalue04\r\n", data)
assert_match('name="name04"', data)
assert_match('filename="file04"', data)
assert_match('Content%-Type: text/plain\r\n', data)
assert_not_match('Content%-Type: application/octet%-stream\r\n', data)
assert_match('Content%-Encoding: gzip\r\n', data)
end

function test_stream_01()
post = assert(scurl.form{name01 = {
stream = function() end,
length = 128,
}})
local data = assert_string(post:get())
assert_match('name="name01"', data)
assert_not_match('filename', data)
end

function test_stream_02()
post = assert(scurl.form{name02 = {
name = 'file02',
stream = function() end,
length = 128,
}})
local data = assert_string(post:get())
assert_match('name="name02"', data)
assert_match('filename="file02"', data)
end

function test_stream_03()
post = assert(scurl.form{name03 = {
name = 'file03',
stream = function() end,
length = 128,
type = 'text/plain',
}})

local data = assert_string(post:get())
assert_match('name="name03"', data)
assert_match('filename="file03"', data)
assert_match('Content%-Type: text/plain\r\n', data)
end

function test_stream_04()
post = assert(scurl.form{name04 = {
name = 'file04',
stream = function() end,
length = 128,
type = 'text/plain',
headers = {"Content-Encoding: gzip"},
}})
local data = assert_string(post:get())
assert_match('name="name04"', data)
assert_match('filename="file04"', data)
assert_match('Content%-Type: text/plain\r\n', data)
assert_match('Content%-Encoding: gzip\r\n', data)
end

function test_stream_05()
post = assert(scurl.form{name05 = {
stream = {
length = function() return 128 end;
read = function() end;
}
}})
local data = assert_string(post:get())
assert_match('name="name05"', data)
assert_not_match('filename', data)
end

function test_error()
assert_error(function() post = scurl.form{name = {content = 1}} end)
assert_error(function() post = scurl.form{name = {1}} end)
assert_error(function() post = scurl.form{name = {data = {}}} end)
assert_error(function() post = scurl.form{name = {file = true}} end)
assert_error(function() post = scurl.form{name = {stream = function() end}} end)
assert_error(function() post = scurl.form{name = {stream = {}}} end)
assert_error(function() post = scurl.form{name = {stream = {
read=function()end;length=function()end
}}}end)
assert_error(function() post = scurl.form{name = {stream = {
read=function()end;length=function() return "123" end
}}}end)
assert_error(function() post = scurl.form{name = {stream = {
read=function()end;length=function() return "hello" end
}}}end)
end

function test_ignore_unknown()
post = assert(scurl.form{
name01 = {},
name02 = {name = "helo"},
})
local data = assert_string(post:get())
assert_not_match('name="name01"', data)
assert_not_match('name="name02"', data)
end

function test_empty()
post = assert(scurl.form{})
end

end

if not HAS_RUNNER then lunit.run() end