From 1285ae42c5212557e423957e1c12810cfd726fda Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Fri, 12 Sep 2014 11:46:43 +0500 Subject: [PATCH 1/2] Add. Form class to Lua-cURLv3 interface. See examples/cURLv3/post_form.lua --- examples/cURLv3/post_form.lua | 87 ++++++++++++++++++++++++ src/lua/cURL/impl/cURL.lua | 124 ++++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 examples/cURLv3/post_form.lua diff --git a/examples/cURLv3/post_form.lua b/examples/cURLv3/post_form.lua new file mode 100644 index 0000000..ce3a8f8 --- /dev/null +++ b/examples/cURLv3/post_form.lua @@ -0,0 +1,87 @@ +local cURL = require "cURL" + +-- Stream class +local Stream = {} do +Stream.__index = Stream + +function Stream:new(ch, length) + local o = setmetatable({}, self) + o._len = length + o._ch = ch + o._pos = 0 + o._step = 7 + return o +end + +function Stream:length() + return self._len +end + +function Stream:read() + local n = self._len - self._pos + if n <= 0 then return '' end -- eof + if n > self._step then n = self._step end + self._pos = self._pos + n + return self._ch:rep(n) +end + +end + +-- returns size and reader +local function make_stream(ch, n, m) + local size = n * m + local i = -1 + return size, function() + i = i + 1 + if i < m then + return (tostring(ch)):rep(n - 2) .. '\r\n' + end + return nil + end +end + +local length, stream = make_stream("a", 10, 4) + +c = cURL.easy{ + url = "http://posttestserver.com/post.php", + -- url = "http://httpbin.org/post", + post = true, + httppost = cURL.form{ + + -- file form filesystem + name01 = { + file = "post_form.lua", + type = "text/plain", + name = "post.lua", + }, + + -- file form string + name02 = { + data = "bold", + name = "dummy.html", + type = "text/html", + }, + + -- file form stream object + name03 = { + stream = Stream:new('8', 25), + name = "stream1.txt", + type = "text/plain", + headers = { + "X-Test-Char : 8", + "X-Test-length : 25", + } + }, + + -- file form stream function + name04 = { + stream = stream, + length = length, + name = "stream2.txt", + type = "text/plain", + }, + + }, +} + +c:perform() diff --git a/src/lua/cURL/impl/cURL.lua b/src/lua/cURL/impl/cURL.lua index 066d212..f444eb5 100644 --- a/src/lua/cURL/impl/cURL.lua +++ b/src/lua/cURL/impl/cURL.lua @@ -12,6 +12,12 @@ -- Implementation of Lua-cURL http://msva.github.io/lua-curl -- +local function clone(t, o) + o = o or {} + for k,v in pairs(t) do o[k]=v end + return o +end + local function wrap_function(k) return function(self, ...) local ok, err = self._handle[k](self._handle, ...) @@ -94,6 +100,80 @@ local function make_iterator(self, perform) end end + +-- name = /// +-- +-- = { +-- stream = function/object +-- length = ?number +-- name = ?string +-- type = ?string +-- headers = ?table +-- } +-- +-- = { +-- file = string +-- type = ?string +-- name = ?string +-- headers = ?table +-- } +-- +-- = { +-- data = string +-- name = string +-- 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')) + + if value.stream then + local vst = type(value.stream) + + if vst == 'function' then + assert(type(value.length) == 'number') + local length = value.length + return form:add_stream(name, value.name, value.type, value.headers, length, value.stream) + end + + if (vst == 'table') or (vst == 'userdata') then + local length = value.length or assert(value.stream:length()) + assert(type(length) == 'number') + return form:add_stream(name, value.name, value.type, value.headers, length, value.stream) + end + + error("Unsupported stream type: " .. vst) + end + + if value.file then + assert(type(value.file) == 'string') + return form:add_file(name, value.file, value.type, value.filename, value.headers) + end + + if value.data then + assert(type(value.data) == 'string') + assert(type(value.name) == 'string') + return form:add_buffer(name, value.name, value.data, value.type, value.headers) + end +end + +local function form_add(form, data) + for k, v in pairs(data) do + local ok, err = form_add_element(form, k, v) + if not ok then return nil, err end + end + + return form +end + local function class(ctor) local C = {} C.__index = function(self, k) @@ -334,6 +414,21 @@ end local function Load_cURLv3(cURL, curl) +------------------------------------------- +local Form = class(curl.form) do + +function Form:__init(opt) + if opt then return self:add(opt) end + return self +end + +function Form:add(data) + return form_add(self, data) +end + +end +------------------------------------------- + ------------------------------------------- local Easy = class(curl.easy) do @@ -352,6 +447,33 @@ function Easy:perform(opt) return perform(self) end +local setopt_httppost = wrap_function("setopt_httppost") +function Easy:setopt_httppost(form) + return setopt_httppost(self, form:handle()) +end + +local setopt = wrap_function("setopt") +function Easy:setopt(k, v) + if type(k) == 'table' then + local t = k + + local hpost = t.httppost or t[curl.OPT_HTTPPOST] + if hpost and hpost._handle then + t = clone(t) + if t.httppost then t.httppost = hpost:handle() end + if t[curl.OPT_HTTPPOST] then t[curl.OPT_HTTPPOST] = hpost:handle() end + end + + return setopt(self, t) + end + + if k == curl.OPT_HTTPPOST then + return self:setopt_httppost(v) + end + + return setopt(self, k, v) +end + end ------------------------------------------- @@ -409,6 +531,8 @@ end setmetatable(cURL, {__index = curl}) +function cURL.form(...) return Form:new(...) end + function cURL.easy(...) return Easy:new(...) end function cURL.multi(...) return Multi:new(...) end From f7926e5f1cd8412931f71690c880b3e2d657ac17 Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Fri, 12 Sep 2014 11:57:46 +0500 Subject: [PATCH 2/2] Fix. `find_ca_bundle` should return nil if there no file. --- src/lua/cURL/utils.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua/cURL/utils.lua b/src/lua/cURL/utils.lua index 438d7b2..045e9fc 100644 --- a/src/lua/cURL/utils.lua +++ b/src/lua/cURL/utils.lua @@ -35,7 +35,7 @@ local function find_ca_bundle(name) end if env.SSL_CERT_DIR and path.isdir(env.SSL_CERT_DIR) then - return false, env.SSL_CERT_DIR + return nil, env.SSL_CERT_DIR end if env.SSL_CERT_FILE and path.isfile(env.SSL_CERT_FILE) then